Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3780 → Rev 3908

/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc
768,6 → 768,8
cmp [cd_status], 0
jne .end
mov [IDE_Channel_2], 1
mov ecx, ide_channel2_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 1
791,6 → 793,8
cmp [cd_status], 0
jne .end
mov [IDE_Channel_2], 1
mov ecx, ide_channel2_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 0
814,6 → 818,8
cmp [cd_status], 0
jne .end
mov [IDE_Channel_1], 1
mov ecx, ide_channel1_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 1
837,6 → 843,8
cmp [cd_status], 0
jne .end
mov [IDE_Channel_1], 1
mov ecx, ide_channel1_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 0
/kernel/branches/Kolibri-acpi/blkdev/disk.inc
5,7 → 5,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 3460 $
$Revision: 3742 $
 
; =============================================================================
; ================================= Constants =================================
186,9 → 186,9
; Pointer to parent DISK structure.
FSUserFunctions dd ?
; Handlers for the sysfunction 70h. This field is a pointer to the following
; array. The first dword is a number of supported subfunctions, other dwords
; array. The first dword is pointer to disconnect handler.
; The first dword is a number of supported subfunctions, other dwords
; point to handlers of corresponding subfunctions.
; This field is 0 if file system is not recognized.
; ...fs-specific data may follow...
ends
 
501,7 → 501,8
jz .nofree
.freeloop:
lodsd
call free
mov ecx, [eax+PARTITION.FSUserFunctions]
call dword [ecx]
dec edi
jnz .freeloop
.nofree:
727,7 → 728,7
; 10. This is not an MBR. The media is not partitioned. Create one partition
; which covers all the media and abort the loop.
stdcall disk_add_partition, 0, 0, \
dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4]
dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4], esi
jmp .done
.mbr:
; 11. Process all entries of the new MBR/EBR
855,7 → 856,7
adc edx, 0
push ecx
stdcall disk_add_partition, eax, edx, \
[ecx+PARTITION_TABLE_ENTRY.Length], 0
[ecx+PARTITION_TABLE_ENTRY.Length], 0, esi
pop ecx
.nothing:
; 5. Return.
869,7 → 870,10
; This is an internal function called from disk_scan_partitions and
; process_partition_table_entry. It adds one partition to the list of
; partitions for the media.
proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword
; Important note: start, length, disk MUST be present and
; MUST be in the same order as in PARTITION structure.
; esi duplicates [disk].
proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword, disk:dword
; 1. Check that this partition will not exceed the limit on total number.
cmp [esi+DISK.NumPartitions], MAX_NUM_PARTITIONS
jae .nothing
974,27 → 978,34
virtual at ebp+8
.start dq ?
.length dq ?
.disk dd ?
end virtual
; 1. Read the bootsector to the buffer.
; When disk_add_partition is called, ebx contains a pointer to
; a two-sectors-sized buffer. This function saves ebx in the stack
; a three-sectors-sized buffer. This function saves ebx in the stack
; immediately before ebp.
virtual at ebp-4
.buffer dd ?
end virtual
; 1. Read the bootsector to the buffer.
mov al, DISKFUNC.read
mov ebx, [.buffer]
add ebx, 512
push 1
stdcall disk_call_driver, ebx, dword [.start], dword [.start+4], esp
mov ebx, [ebp-4] ; get buffer
add ebx, 512 ; advance over MBR data to bootsector data
add ebp, 8 ; ebp points to part of PARTITION structure
xor eax, eax ; first sector of the partition
call fs_read32_sys
push eax
; 2. Run tests for all supported filesystems. If at least one test succeeded,
; go to 4.
; For tests: qword [ebp+8] = partition start, qword [ebp+10h] = partition
; length, [esp] = 0 if reading bootsector failed or 1 if succeeded,
; ebx points to the buffer for bootsector.
; For tests:
; ebp -> first three fields of PARTITION structure, .start, .length, .disk;
; [esp] = error code after bootsector read: 0 = ok, otherwise = failed,
; ebx points to the buffer for bootsector,
; ebx+512 points to 512-bytes buffer that can be used for anything.
call fat_create_partition
test eax, eax
jnz .success
call ntfs_create_partition
test eax, eax
jnz .success
call ext2_create_partition
test eax, eax
jnz .success
; 3. No file system has recognized the volume, so just allocate the PARTITION
; structure without extra fields.
movi eax, sizeof.PARTITION
1001,22 → 1012,30
call malloc
test eax, eax
jz .nothing
mov edx, dword [.start]
mov edx, dword [ebp+PARTITION.FirstSector]
mov dword [eax+PARTITION.FirstSector], edx
mov edx, dword [.start+4]
mov edx, dword [ebp+PARTITION.FirstSector+4]
mov dword [eax+PARTITION.FirstSector+4], edx
mov edx, dword [.length]
mov edx, dword [ebp+PARTITION.Length]
mov dword [eax+PARTITION.Length], edx
mov edx, dword [.length+4]
mov edx, dword [ebp+PARTITION.Length+4]
mov dword [eax+PARTITION.Length+4], edx
mov [eax+PARTITION.Disk], esi
and [eax+PARTITION.FSUserFunctions], 0
mov [eax+PARTITION.FSUserFunctions], default_fs_functions
.success:
.nothing:
sub ebp, 8 ; restore ebp
; 4. Return with eax = pointer to PARTITION or NULL.
pop ecx
ret
 
iglobal
align 4
default_fs_functions:
dd free
dd 0 ; no user functions
endg
 
; This function is called from file_system_lfn.
; This handler gets the control each time when fn 70 is called
; with unknown item of root subdirectory.
1200,15 → 1219,13
mov eax, [edx+DISK.Partitions]
mov eax, [eax+ecx*4]
mov edi, [eax+PARTITION.FSUserFunctions]
test edi, edi
jz .nofs
mov ecx, [ebx]
cmp [edi], ecx
cmp [edi+4], ecx
jbe .unsupported
push edx
push ebp
mov ebp, eax
call dword [edi+4+ecx*4]
call dword [edi+8+ecx*4]
pop ebp
pop edx
mov dword [esp+32], eax
1225,6 → 1242,8
mov dword [esp+32], ERROR_FILE_NOT_FOUND
jmp .cleanup
.unsupported:
cmp edi, default_fs_functions
jz .nofs
mov dword [esp+32], ERROR_UNSUPPORTED_FS
jmp .cleanup
.nomedia:
/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc
5,7 → 5,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 3284 $
$Revision: 3742 $
 
; This function is intended to replace the old 'hd_read' function when
; [hdd_appl_data] = 0, so its input/output parameters are the same, except
14,19 → 14,7
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_read32_sys:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 0
call hd_read
mov [hdd_appl_data], 1 ; restore to default state
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; do its work.
; Save ecx, set ecx to SysCache and let the common part do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.SysCache
39,18 → 27,7
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_read32_app:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 1
call hd_read
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
; Save ecx, set ecx to AppCache and let the common part do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.AppCache
185,19 → 162,7
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_write32_sys:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 0
call hd_write
mov [hdd_appl_data], 1 ; restore to default state
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; do its work.
; Save ecx, set ecx to SysCache and let the common part do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.SysCache
210,18 → 175,7
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_write32_app:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 1
call hd_write
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
; Save ecx, set ecx to AppCache and let the common part do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.AppCache
622,17 → 576,6
; This function flushes all modified data from both caches for the given DISK.
; esi = pointer to DISK
disk_sync:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by write_cache.
cmp esi, 'old'
jnz @f
mov [hdd_appl_data], 0
call write_cache
mov [hdd_appl_data], 1
call write_cache
mov eax, [hd_error]
ret
@@:
; The algorithm is straightforward.
push esi
push esi ; for second write_cache64
/kernel/branches/Kolibri-acpi/blkdev/fdc.inc
8,11 → 8,6
$Revision$
 
 
iglobal
;function pointers.
fdc_irq_func dd fdc_null
endg
 
uglobal
dmasize db 0x0
dmamode db 0x0
25,11 → 20,6
rep stosb
ret
 
fdc_irq:
call [fdc_irq_func]
fdc_null:
ret
 
save_image:
call reserve_flp
call restorefatchain
64,7 → 54,6
cmp [FDD_Track], 80
jne save_image_1
unnecessary_save_image:
mov [fdc_irq_func], fdc_null
popa
mov [flp_status], 0
ret
/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc
185,19 → 185,11
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
;*********************************************
FDCInterrupt:
; Установить флаг прерывани
; Установить флаг прерывания
mov [FDD_IntFlag], 1
mov al, 1
ret
 
 
;******************************************
;* УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЙ *
;* НГМД *
;******************************************
SetUserInterrupts:
mov [fdc_irq_func], FDCInterrupt
ret
 
;*******************************************
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
;*******************************************
212,9 → 204,9
mov [TickCounter], eax
; Ожидать установки флага прерывания НГМД
@@TestRS_2:
call change_task
cmp [FDD_IntFlag], 0
jnz @@End_7 ;прерывание произошло
call change_task
mov eax, [timer_ticks]
sub eax, [TickCounter]
cmp eax, 50 ;25 ;5 ;ожидать 5 тиков
/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13,39 → 13,96
; Access through BIOS by diamond
; LBA48 support by Mario79
;-----------------------------------------------------------------------------
struct HD_DATA
hdbase dd ?
hdid dd ?
hdpos dd ?
ends
 
iglobal
align 4
hd_read:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
and [hd_error], 0
push ecx esi edi ; scan cache
ide_callbacks:
dd ide_callbacks.end - ide_callbacks ; strucsize
dd 0 ; no close function
dd 0 ; no closemedia function
dd ide_querymedia
dd ide_read
dd ide_write
dd 0 ; no flush function
dd 0 ; use default cache size
.end:
 
call calculate_cache
add esi, 8
bd_callbacks:
dd bd_callbacks.end - bd_callbacks ; strucsize
dd 0 ; no close function
dd 0 ; no closemedia function
dd bd_querymedia
dd bd_read_interface
dd bd_write_interface
dd 0 ; no flush function
dd 0 ; use default cache size
.end:
 
mov edi, 1
hd0_data HD_DATA ?, 0, 1
hd1_data HD_DATA ?, 0x10, 2
hd2_data HD_DATA ?, 0, 3
hd3_data HD_DATA ?, 0x10, 4
endg
 
hdreadcache:
cmp dword [esi+4], 0 ; empty
je nohdcache
uglobal
ide_mutex MUTEX
ide_channel1_mutex MUTEX
ide_channel2_mutex MUTEX
endg
 
cmp [esi], eax ; correct sector
je yeshdcache
 
nohdcache:
add esi, 8
inc edi
dec ecx
jnz hdreadcache
 
call find_empty_slot ; ret in edi
cmp [hd_error], 0
jne return_01
; Read through BIOS?
cmp [hdpos], 0x80
jae .bios
proc ide_read stdcall uses edi, \
hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data
; buffer = pointer to buffer for data
; startsector = 64-bit start sector
; numsectors = pointer to number of sectors on input,
; must be filled with number of sectors really read
locals
sectors_todo dd ?
channel_lock dd ?
endl
; 1. Initialize number of sectors: get number of requested sectors
; and say that no sectors were read yet.
mov ecx, [numsectors]
mov eax, [ecx]
mov dword [ecx], 0
mov [sectors_todo], eax
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
mov ecx, ide_channel2_mutex
mov eax, [hd_data]
push ecx
mov ecx, [hd_address_table]
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0
pop ecx
jne .IDE_Channel_2
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov [channel_lock], ecx
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
; Underlying procedures do not know about 64-bit sectors.
; Worker procedures use global variables and edi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase]
mov [hdbase], eax
mov eax, [ecx+HD_DATA.hdid]
mov [hdid], eax
mov eax, [ecx+HD_DATA.hdpos]
mov [hdpos], eax
mov eax, dword [startsector]
mov edi, [buffer]
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
.sectors_loop:
; DMA read is permitted if [allow_dma_access]=1 or 2
cmp [allow_dma_access], 2
ja .nodma
55,38 → 112,276
jmp @f
.nodma:
call hd_read_pio
jmp @f
.bios:
call bd_read
@@:
cmp [hd_error], 0
jne return_01
jnz .fail
mov ecx, [numsectors]
inc dword [ecx] ; one more sector is read
dec [sectors_todo]
jz .done
inc eax
jnz .sectors_loop
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
.done:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
call calculate_cache_1
lea esi, [edi*8+esi]
proc ide_write stdcall uses esi edi, \
hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data
; buffer = pointer to buffer with data
; startsector = 64-bit start sector
; numsectors = pointer to number of sectors on input,
; must be filled with number of sectors really written
locals
sectors_todo dd ?
channel_lock dd ?
endl
; 1. Initialize number of sectors: get number of requested sectors
; and say that no sectors were read yet.
mov ecx, [numsectors]
mov eax, [ecx]
mov dword [ecx], 0
mov [sectors_todo], eax
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
mov ecx, ide_channel2_mutex
mov eax, [hd_data]
push ecx
mov ecx, [hd_address_table]
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0
pop ecx
jne .IDE_Channel_2
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov [channel_lock], ecx
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
; Underlying procedures do not know about 64-bit sectors.
; Worker procedures use global variables and esi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase]
mov [hdbase], eax
mov eax, [ecx+HD_DATA.hdid]
mov [hdid], eax
mov eax, [ecx+HD_DATA.hdpos]
mov [hdpos], eax
mov esi, [buffer]
lea edi, [startsector]
mov [cache_chain_ptr], edi
; 4. Worker procedures take max 16 sectors per time,
; loop until all sectors will be processed.
.sectors_loop:
mov ecx, 16
cmp ecx, [sectors_todo]
jbe @f
mov ecx, [sectors_todo]
@@:
mov [cache_chain_size], cl
; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2
jae .nodma
cmp [dma_hdd], 1
jnz .nodma
call cache_write_dma
jmp .common
.nodma:
mov [cache_chain_size], 1
call cache_write_pio
.common:
cmp [hd_error], 0
jnz .fail
movzx ecx, [cache_chain_size]
mov eax, [numsectors]
add [eax], ecx
sub [sectors_todo], ecx
jz .done
add [edi], ecx
jc .fail
shl ecx, 9
add esi, ecx
jmp .sectors_loop
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
.done:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
mov [esi], eax ; sector number
mov dword [esi+4], 1 ; hd read - mark as same as in hd
; This is a stub.
proc ide_querymedia stdcall, hd_data, mediainfo
mov eax, [mediainfo]
mov [eax+DISKMEDIAINFO.Flags], 0
mov [eax+DISKMEDIAINFO.SectorSize], 512
or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
xor eax, eax
ret
endp
 
yeshdcache:
mov esi, edi
shl esi, 9
proc bd_read_interface stdcall uses edi, \
userdata, buffer, startsector:qword, numsectors
; userdata = old [hdpos] = 80h + index in NumBiosDisks
; buffer = pointer to buffer for data
; startsector = 64-bit start sector
; numsectors = pointer to number of sectors on input,
; must be filled with number of sectors really read
locals
sectors_todo dd ?
endl
; 1. Initialize number of sectors: get number of requested sectors
; and say that no sectors were read yet.
mov ecx, [numsectors]
mov eax, [ecx]
mov dword [ecx], 0
mov [sectors_todo], eax
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
; Underlying procedures do not know about 64-bit sectors.
; Worker procedures use global variables and edi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov eax, [userdata]
mov [hdpos], eax
mov eax, dword [startsector]
mov edi, [buffer]
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
.sectors_loop:
call bd_read
cmp [hd_error], 0
jnz .fail
mov ecx, [numsectors]
inc dword [ecx] ; one more sector is read
dec [sectors_todo]
jz .done
inc eax
jnz .sectors_loop
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
.done:
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
push eax
call calculate_cache_2
add esi, eax
pop eax
proc bd_write_interface stdcall uses esi edi, \
userdata, buffer, startsector:qword, numsectors
; userdata = old [hdpos] = 80h + index in NumBiosDisks
; buffer = pointer to buffer with data
; startsector = 64-bit start sector
; numsectors = pointer to number of sectors on input,
; must be filled with number of sectors really written
locals
sectors_todo dd ?
endl
; 1. Initialize number of sectors: get number of requested sectors
; and say that no sectors were read yet.
mov ecx, [numsectors]
mov eax, [ecx]
mov dword [ecx], 0
mov [sectors_todo], eax
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
; Underlying procedures do not know about 64-bit sectors.
; Worker procedures use global variables and esi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov eax, [userdata]
mov [hdpos], eax
mov esi, [buffer]
lea edi, [startsector]
mov [cache_chain_ptr], edi
; 4. Worker procedures take max 16 sectors per time,
; loop until all sectors will be processed.
.sectors_loop:
mov ecx, 16
cmp ecx, [sectors_todo]
jbe @f
mov ecx, [sectors_todo]
@@:
mov [cache_chain_size], cl
call bd_write_cache_chain
cmp [hd_error], 0
jnz .fail
movzx ecx, [cache_chain_size]
mov eax, [numsectors]
add [eax], ecx
sub [sectors_todo], ecx
jz .done
add [edi], ecx
jc .fail
shl ecx, 9
add esi, ecx
jmp .sectors_loop
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
.done:
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
mov edi, ebx
mov ecx, 512/4
cld
rep movsd ; move data
; This is a stub.
proc bd_querymedia stdcall, hd_data, mediainfo
mov eax, [mediainfo]
mov [eax+DISKMEDIAINFO.Flags], 0
mov [eax+DISKMEDIAINFO.SectorSize], 512
or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
xor eax, eax
ret
endp
 
return_01:
pop edi esi ecx
ret
;-----------------------------------------------------------------------------
align 4
; input: eax = sector, edi -> buffer
; output: edi = edi + 512
hd_read_pio:
push eax edx
 
184,19 → 479,11
 
pushfd
cli
push edi
shl edi, 9
 
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx, 256
mov edx, [hdbase]
cld
rep insw
pop edi
popfd
 
pop edx eax
203,61 → 490,7
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
call calculate_cache
add esi, 8
mov edi, 1
 
hdwritecache:
cmp dword [esi+4], 0 ; if cache slot is empty
je not_in_cache_write
 
cmp [esi], eax ; if the slot has the sector
je yes_in_cache_write
 
not_in_cache_write:
add esi, 8
inc edi
dec ecx
jnz hdwritecache
 
; sector not found in cache
; write the block to a new location
call find_empty_slot ; ret in edi
cmp [hd_error], 0
jne hd_write_access_denied
 
call calculate_cache_1
lea esi, [edi*8+esi]
mov [esi], eax ; sector number
 
yes_in_cache_write:
mov dword [esi+4], 2 ; write - differs from hd
 
shl edi, 9
 
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov esi, ebx
mov ecx, 512/4
cld
rep movsd ; move data
 
hd_write_access_denied:
pop edi esi ecx
ret
;-----------------------------------------------------------------------------
align 4
; edi -> sector, esi -> data
cache_write_pio:
; Select the desired drive
mov edx, [hdbase]
271,7 → 504,7
jne hd_write_error
 
; ATA with 28 or 48 bit for sector number?
mov eax, [esi]
mov eax, [edi]
cmp eax, 0x10000000
jae .lba48
;--------------------------------------
286,7 → 519,7
inc eax
out dx, al ; ATA Sector Counter счётчик секторов
inc edx
mov eax, [esi] ; eax = sector to write
mov eax, [edi] ; eax = sector to write
out dx, al ; LBA Low LBA (7:0)
shr eax, 8
inc edx
303,7 → 536,6
inc edx
mov al, 30h ; WRITE SECTOR(S)
out dx, al ; ATACommand регистр команд
popfd
jmp .continue
;--------------------------------------
.lba48:
319,7 → 551,7
inc eax
out dx, al ; Sector Count Current Sector count (7:0)
inc edx
mov eax, [esi]
mov eax, [edi]
rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax ; because only 32 bit cache
328,7 → 560,7
inc edx
out dx, al ; LBA High Previous LBA (47:40)
sub edx, 2
mov eax, [esi]
mov eax, [edi]
out dx, al ; LBA Low Current LBA (7:0)
shr eax, 8
inc edx
343,9 → 575,9
inc edx
mov al, 34h ; WRITE SECTOR(S) EXT
out dx, al ; ATACommand регистр команд
popfd
;--------------------------------------
.continue:
popfd
call wait_for_sector_buffer
 
cmp [hd_error], 0
355,14 → 587,6
 
pushfd
cli
mov esi, edi
shl esi, 9
 
push eax
call calculate_cache_2
add esi, eax
pop eax
 
mov ecx, 256
mov edx, [hdbase]
cld
485,6 → 709,9
pop edx eax
ret
;-----------------------------------------------------------------------------
irq14_num equ byte 14
irq15_num equ byte 15
;-----------------------------------------------------------------------------
align 4
wait_for_sector_dma_ide0:
push eax
494,15 → 721,22
align 4
.wait:
call change_task
cmp [irq14_func], hdd_irq14
jnz .done
cmp [IDE_common_irq_param], 0
jz .done
 
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
mov [irq14_func], hdd_irq_null
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
popfd
;--------------------------------------
align 4
.done:
pop edx
pop eax
517,16 → 751,23
align 4
.wait:
call change_task
cmp [irq15_func], hdd_irq15
jnz .done
cmp [IDE_common_irq_param], 0
jz .done
 
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
mov [irq15_func], hdd_irq_null
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
popfd
;--------------------------------------
align 4
.done:
pop edx
pop eax
542,8 → 783,7
 
dma_cur_sector dd not 40h
dma_hdpos dd 0
irq14_func dd hdd_irq_null
irq15_func dd hdd_irq_null
IDE_common_irq_param db 0
endg
;-----------------------------------------------------------------------------
uglobal
560,35 → 800,97
endg
;-----------------------------------------------------------------------------
align 4
hdd_irq14:
IDE_irq_14_handler:
cmp [IDE_common_irq_param], irq14_num
jne .exit
 
pushfd
cli
pushad
mov [irq14_func], hdd_irq_null
; clear Bus Master IDE Command register
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
; clear Bus Master IDE Status register
; clear Interrupt bit
add edx, 2
mov al, 4 ; 100b
out dx, al
 
popad
popfd
;--------------------------------------
align 4
hdd_irq_null:
.exit:
mov al, 1
ret
;-----------------------------------------------------------------------------
align 4
hdd_irq15:
IDE_irq_15_handler:
cmp [IDE_common_irq_param], irq15_num
jne .exit
 
pushfd
cli
pushad
mov [irq15_func], hdd_irq_null
; clear Bus Master IDE Command register
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
; clear Bus Master IDE Status register
; clear Interrupt bit
add edx, 2
mov al, 4 ; 100b
out dx, al
 
popad
popfd
;--------------------------------------
align 4
.exit:
mov al, 1
ret
;-----------------------------------------------------------------------------
align 4
IDE_common_irq_handler:
cmp [IDE_common_irq_param], 0
je .exit
 
pushfd
cli
pushad
; clear Bus Master IDE Command register
xor ebx, ebx
mov dx, [IDEContrRegsBaseAddr]
mov eax, IDE_common_irq_param
cmp [eax], irq14_num
mov [eax], bl
xor eax, eax
je @f
 
add dx, 8
;--------------------------------------
align 4
@@:
out dx, al
; clear Bus Master IDE Status register
; clear Interrupt bit
add edx, 2
mov al, 4 ; 100b
out dx, al
 
popad
popfd
;--------------------------------------
align 4
.exit:
mov al, 1
ret
;-----------------------------------------------------------------------------
align 4
hd_read_dma:
push eax
push edx
605,42 → 907,45
sub eax, [dma_cur_sector]
shl eax, 9
add eax, (OS_BASE+IDE_DMA)
push ecx esi edi
push ecx esi
mov esi, eax
shl edi, 9
 
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx, 512/4
cld
rep movsd
pop edi esi ecx
pop esi ecx
pop edx
pop eax
ret
.notread:
; set data for PRD Table
mov eax, IDE_descriptor_table
mov dword [eax], IDE_DMA
mov word [eax+4], 0x2000
sub eax, OS_BASE
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jz @f
add edx, 8
@@:
push edx
; Bus Master IDE PRD Table Address
add edx, 4
; save IDE_descriptor_table
out dx, eax
pop edx
; clear Bus Master IDE Command register
mov al, 0
out dx, al
; clear Bus Master IDE Status register
; clear Error bit and Interrupt bit
add edx, 2
mov al, 6
mov al, 6 ; 110b
out dx, al
 
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ; адрес регистра головок
728,6 → 1033,7
out dx, al ; ATACommand регистр команд
;--------------------------------------
.continue:
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
734,21 → 1040,27
jz @f
add dx, 8
@@:
; set write to memory and Start Bus Master
mov al, 9
out dx, al
 
mov eax, [CURRENT_TASK]
mov [dma_process], eax
 
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
 
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
 
mov [IDE_common_irq_param], irq14_num
jmp @f
.ide1:
mov [irq15_func], hdd_irq15
mov [IDE_common_irq_param], irq15_num
@@:
popfd
; wait for interrupt
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .wait_ide1
766,24 → 1078,13
mov [dma_cur_sector], eax
jmp hd_read_dma
;-----------------------------------------------------------------------------
align 4
write_cache_sector:
mov [cache_chain_size], 1
mov [cache_chain_pos], edi
;--------------------------------------
align 4
write_cache_chain:
cmp [hdpos], 0x80
jae bd_write_cache_chain
mov eax, [cache_chain_ptr]
cache_write_dma:
mov eax, [cache_chain_ptr] ; for what?
push esi
; set data for PRD Table
mov eax, IDE_descriptor_table
mov edx, eax
pusha
mov esi, [cache_chain_pos]
shl esi, 9
call calculate_cache_2
add esi, eax
mov edi, (OS_BASE+IDE_DMA)
mov dword [edx], IDE_DMA
movzx ecx, [cache_chain_size]
794,21 → 1095,29
rep movsd
popa
sub eax, OS_BASE
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jz @f
add edx, 8
@@:
push edx
; Bus Master IDE PRD Table Address
add edx, 4
; save IDE_descriptor_table
out dx, eax
pop edx
; clear Bus Master IDE Command register
mov al, 0
out dx, al
; clear Bus Master IDE Status register
; clear Error bit and Interrupt bit
add edx, 2
mov al, 6
out dx, al
 
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ; адрес регистра головок
897,6 → 1206,7
out dx, al ; ATACommand регистр команд
;--------------------------------------
.continue:
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
903,6 → 1213,7
jz @f
add dx, 8
@@:
; set write to device and Start Bus Master
mov al, 1
out dx, al
mov eax, [CURRENT_TASK]
912,12 → 1223,14
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
 
mov [IDE_common_irq_param], irq14_num
jmp @f
.ide1:
mov [irq15_func], hdd_irq15
mov [IDE_common_irq_param], irq15_num
@@:
popfd
; wait for interrupt
mov [dma_cur_sector], not 0x40
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
933,6 → 1246,8
ret
;-----------------------------------------------------------------------------
uglobal
align 4
IDE_Interrupt dw ?
IDEContrRegsBaseAddr dw ?
IDEContrProgrammingInterface dw ?
IDE_BAR0_val dw ?
965,19 → 1280,12
sub eax, [bios_cur_sector]
shl eax, 9
add eax, (OS_BASE+0x9A000)
push ecx esi edi
push ecx esi
mov esi, eax
shl edi, 9
 
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx, 512/4
cld
rep movsd
pop edi esi ecx
pop esi ecx
pop edx
pop eax
ret
1006,10 → 1314,6
align 4
bd_write_cache_chain:
pusha
mov esi, [cache_chain_pos]
shl esi, 9
call calculate_cache_2
add esi, eax
mov edi, OS_BASE + 0x9A000
movzx ecx, [cache_chain_size]
push ecx
1041,7 → 1345,7
int13_call:
; Because this code uses fixed addresses,
; it can not be run simultaniously by many threads.
; In current implementation it is protected by common mutex 'hd1_status'
; In current implementation it is protected by common mutex 'ide_status'
mov word [OS_BASE + 510h], 10h ; packet length
mov word [OS_BASE + 512h], cx ; number of sectors
mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000
1088,82 → 1392,3
@@:
ret
; \end{diamond}
;-----------------------------------------------------------------------------
align 4
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
;-----------------------------------------------------------------------------
align 4
reserve_hd_channel:
; BIOS disk accesses are protected with common mutex hd1_status
; This must be modified when hd1_status will not be valid!
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1], 0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2], 0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_2
.reserve_ok_1:
mov [IDE_Channel_1], 1
push eax
mov al, 1
jmp @f
.reserve_ok_2:
mov [IDE_Channel_2], 1
push eax
mov al, 3
@@:
cmp [hdid], 1
sbb al, -1
mov [hd_in_cache], al
pop eax
sti
.ret:
ret
;-----------------------------------------------------------------------------
free_hd_channel:
; see comment at reserve_hd_channel
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
.ret:
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
ret
;-----------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc
23,546 → 23,7
 
$Revision$
 
 
align 4
write_cache:
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
push eax ecx edx esi edi
 
; write difference ( 2 ) from cache to hd
call calculate_cache
add esi, 8
mov edi, 1
write_cache_more:
cmp dword [esi+4], 2; if cache slot is not different
jne .write_chain
mov dword [esi+4], 1; same as in hd
mov eax, [esi] ; eax = sector to write
cmp eax, [PARTITION_START]
jb danger
cmp eax, [PARTITION_END]
ja danger
cmp [hdpos], 0x80
jae @f
; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2
jae .nodma
cmp [dma_hdd], 1
jnz .nodma
@@:
; Объединяем запись цепочки последовательных секторов в одно обращение к диску
cmp ecx, 1
jz .nonext
cmp dword [esi+8+4], 2
jnz .nonext
push eax
inc eax
cmp eax, [esi+8]
pop eax
jnz .nonext
cmp [cache_chain_started], 1
jz @f
mov [cache_chain_started], 1
mov [cache_chain_size], 0
mov [cache_chain_pos], edi
mov [cache_chain_ptr], esi
@@:
inc [cache_chain_size]
cmp [cache_chain_size], 16
jnz .continue
jmp .write_chain
.nonext:
call flush_cache_chain
mov [cache_chain_size], 1
mov [cache_chain_ptr], esi
call write_cache_sector
jmp .continue
.nodma:
call cache_write_pio
.write_chain:
call flush_cache_chain
.continue:
danger:
add esi, 8
inc edi
dec ecx
jnz write_cache_more
call flush_cache_chain
return_02:
pop edi esi edx ecx eax
ret
 
flush_cache_chain:
cmp [cache_chain_started], 0
jz @f
call write_cache_chain
mov [cache_chain_started], 0
@@:
ret
;--------------------------------------------------------------------
align 4
find_empty_slot:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
; output : edi = cache slot
;-----------------------------------------------------------
; push ecx esi
 
search_again:
call calculate_cache_3
shr ecx, 3
search_for_empty:
inc edi
call calculate_cache_4
jbe inside_cache
mov edi, 1
inside_cache:
push esi
call calculate_cache_1
cmp dword [edi*8+esi+4], 2
pop esi
jb found_slot ; it's empty or read
dec ecx
jnz search_for_empty
call write_cache ; no empty slots found, write all
cmp [hd_error], 0
jne found_slot_access_denied
jmp search_again ; and start again
found_slot:
call calculate_cache_5
found_slot_access_denied:
ret
;--------------------------------------------------------------------
align 4
calculate_cache:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov esi, [cache_ide0_pointer]
ret
.ide0_appl_data:
mov ecx, [cache_ide0_appl_sad_size]
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx, [cache_ide1_appl_sad_size]
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx, [cache_ide2_appl_sad_size]
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx, [cache_ide3_appl_sad_size]
mov esi, [cache_ide3_data_pointer]
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov ecx, [cache_ide0_system_sad_size-cache_ide0+eax]
mov esi, [cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov ecx, [cache_ide0_appl_sad_size-cache_ide0+eax]
mov esi, [cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
;--------------------------------------------------------------------
align 4
calculate_cache_1:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov esi, [cache_ide0_pointer]
ret
.ide0_appl_data:
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi, [cache_ide3_data_pointer]
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov esi, [cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov esi, [cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
 
;--------------------------------------------------------------------
align 4
calculate_cache_2:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov eax, [cache_ide0_system_data]
ret
.ide0_appl_data:
mov eax, [cache_ide0_appl_data]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov eax, [cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax, [cache_ide1_appl_data]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov eax, [cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax, [cache_ide2_appl_data]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov eax, [cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax, [cache_ide3_appl_data]
ret
.noide:
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov eax, [cache_ide0_system_data-cache_ide0+eax]
ret
.bd_appl_data:
mov eax, [cache_ide0_appl_data-cache_ide0+eax]
ret
;--------------------------------------------------------------------
align 4
calculate_cache_3:
; mov ecx,cache_max*10/100
; mov edi,[cache_search_start]
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov edi, [cache_ide0_search_start]
ret
.ide0_appl_data:
mov ecx, [cache_ide0_appl_sad_size]
mov edi, [cache_ide0_appl_search_start]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov edi, [cache_ide1_search_start]
ret
.ide1_appl_data:
mov ecx, [cache_ide1_appl_sad_size]
mov edi, [cache_ide1_appl_search_start]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov edi, [cache_ide2_search_start]
ret
.ide2_appl_data:
mov ecx, [cache_ide2_appl_sad_size]
mov edi, [cache_ide2_appl_search_start]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov edi, [cache_ide3_search_start]
ret
.ide3_appl_data:
mov ecx, [cache_ide3_appl_sad_size]
mov edi, [cache_ide3_appl_search_start]
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov ecx, [cache_ide0_system_sad_size-cache_ide0+eax]
mov edi, [cache_ide0_search_start-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov ecx, [cache_ide0_appl_sad_size-cache_ide0+eax]
mov edi, [cache_ide0_appl_search_start-cache_ide0+eax]
pop eax
ret
;--------------------------------------------------------------------
align 4
calculate_cache_4:
; cmp edi,cache_max
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
cmp edi, [cache_ide0_system_sad_size]
ret
.ide0_appl_data:
cmp edi, [cache_ide0_appl_sad_size]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
cmp edi, [cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi, [cache_ide1_appl_sad_size]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
cmp edi, [cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi, [cache_ide2_appl_sad_size]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
cmp edi, [cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi, [cache_ide3_appl_sad_size]
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
cmp edi, [cache_ide0_system_sad_size-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
cmp edi, [cache_ide0_appl_sad_size-cache_ide0+eax]
pop eax
ret
 
;--------------------------------------------------------------------
align 4
calculate_cache_5:
; mov [cache_search_start],edi
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov [cache_ide0_search_start], edi
ret
.ide0_appl_data:
mov [cache_ide0_appl_search_start], edi
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov [cache_ide1_search_start], edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start], edi
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov [cache_ide2_search_start], edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start], edi
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov [cache_ide3_search_start], edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start], edi
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov [cache_ide0_search_start-cache_ide0+eax], edi
pop eax
ret
.bd_appl_data:
mov [cache_ide0_appl_search_start-cache_ide0+eax], edi
pop eax
ret
 
;--------------------------------------------------------------------
align 4
find_empty_slot_CD_cache:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
/kernel/branches/Kolibri-acpi/boot/bootcode.inc
47,21 → 47,21
popa
ret
 
getkey:
getkey: ; Use BIOS INT 16h to read a key from the keyboard
; 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
mov ah, 0 ; If 'int 16h' is called with 'ah' equal to zero, the BIOS will not return control
int 16h ; to the caller until a key is available in the system type ahead buffer. On return,
cmp al, bl ; 'al' contains the ASCII code for the key read from the buffer and 'ah' contains
jb getkey ; the keyboard scan code. Here we compare 'al' with the range of accepted characters.
cmp al, bh ; If the key pressed is not in the range, continue waiting for another key.
ja getkey
push ax
push ax ; If the pressed key is in the accepted range, save it on the stack and echo to screen.
call putchar
pop ax
and ax, 0Fh
jnz @f
and ax, 0Fh ; ASCII code for '0' is 48 (110000b). 0F4=1111b. (110000b AND 1111b) = 0
jnz @f ; So if key '0' was entered, return 10 in 'ax'
mov al, 10
@@:
ret
434,8 → 434,11
xor si, si ; device index = 0
int 0x1A
jnc .found_1 ; Parallel IDE Controller
 
; Controller not found!
xor ax, ax
mov [es:BOOT_IDE_PI_16], ax
jmp .nopci
;--------------------------------------
.found_1:
; get memory base BAR4
mov ax, 0xB10A
443,11 → 446,23
push cx
int 0x1A
jc .no_BAR4 ;.nopci
and cx, 0xFFF0 ; clear address decode type
and cx, 0xFFFC ; clear address decode type
mov [es:BOOT_IDE_BASE_ADDR], cx
.no_BAR4:
pop cx
;--------------------------------------
.found:
; get Interrupt Line
mov ax, 0xB10A
mov di, 0x3c ; memory base is config register at 0x3c
push cx
int 0x1A
jc .no_Interrupt ;.nopci
 
mov [es:BOOT_IDE_INTERR_16], cx
.no_Interrupt:
pop cx
;--------------------------------------
; get memory base BAR0
mov ax, 0xB10A
mov di, 0x10 ; memory base is config register at 0x10
454,9 → 469,11
push cx
int 0x1A
jc .no_BAR0 ;.nopci
 
mov [es:BOOT_IDE_BAR0_16], cx
.no_BAR0:
pop cx
;--------------------------------------
; get memory base BAR1
mov ax, 0xB10A
mov di, 0x14 ; memory base is config register at 0x14
463,9 → 480,11
push cx
int 0x1A
jc .no_BAR1 ;.nopci
 
mov [es:BOOT_IDE_BAR1_16], cx
.no_BAR1:
pop cx
;--------------------------------------
; get memory base BAR2
mov ax, 0xB10A
mov di, 0x18 ; memory base is config register at 0x18
472,9 → 491,11
push cx
int 0x1A
jc .no_BAR2 ;.nopci
 
mov [es:BOOT_IDE_BAR2_16], cx
.no_BAR2:
pop cx
;--------------------------------------
; get memory base BAR3
mov ax, 0xB10A
mov di, 0x1C ; memory base is config register at 0x1c
481,9 → 502,11
push cx
int 0x1A
jc .no_BAR3 ;.nopci
 
mov [es:BOOT_IDE_BAR3_16], cx
.no_BAR3:
pop cx
;--------------------------------------
.nopci:
; \end{Mario79}
 
573,9 → 596,11
; 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?
; b) preboot_biosdisk = use BIOS disks through V86 emulation? // (earlier was: preboot_dma = use DMA access?)
; c) preboot_debug = duplicates kernel debug output to the screen // (earlier was: preboot_vrrm = use VRR?)
; // VRR is an obsolete functionality, used only with CRT monitors: increase display frequency by reducing screen resolution
; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded?
; e) preboot_device = from where to boot?
 
; determine default settings
if ~ defined extended_primary_loader
609,6 → 634,8
; following 4 lines set variables to 1 if its current value is 0
cmp byte [di+preboot_dma-preboot_device], 1
adc byte [di+preboot_dma-preboot_device], 0
cmp byte [di+preboot_launcher-preboot_device], 1 ; Start LAUNCHER by default
adc byte [di+preboot_launcher-preboot_device], 0
; cmp byte [di+preboot_biosdisk-preboot_device], 1
; adc byte [di+preboot_biosdisk-preboot_device], 0
;; default value for VRR is OFF
646,6 → 673,12
; mov si, vrrm_msg
; cmp [preboot_vrrm], 1
; call .say_on_off
mov si, debug_mode_msg
cmp [preboot_debug], 1
call .say_on_off
mov si, launcher_msg
cmp [preboot_launcher], 1
call .say_on_off
mov si, preboot_device_msg
call print
mov al, [preboot_device]
729,25 → 762,30
cmp al, 13
jz .continue
or al, 20h
cmp al, 'a'
cmp al, 'a' ; select graphical mode
jz .change_a
cmp al, 'b'
cmp al, 'q' ; Trick to make 'A' key on azerty keyboard work
je .change_a
cmp al, 'b' ; use BIOS disks? // (selecting YES will make BIOS disks visible as /bd)
jz .change_b
; cmp al, 'c'
; jz .change_c
cmp al, 'c' ; 'd'
cmp al, 'c' ; load kernel in debug mode? // (earlier was: use VRR?)
jz .change_c
cmp al, 'd' ; start launcher after kernel is loaded?
jz .change_d
cmp al, 'e' ; select boot origin
jnz .show_remarks
_setcursor 15,0
; e) preboot_device = from where to boot?
_setcursor 16,0
mov si, bdev
call print
if defined extended_primary_loader
mov bx, '12'
mov bx, '12' ; range accepted for answer: 1-2
else
mov bx, '14'
mov bx, '14' ; range accepted for answer: 1-4
end if
call getkey
mov [preboot_device], al
_setcursor 13,0
_setcursor 14,0
.d:
if ~ defined extended_primary_loader
mov [.bSettingsChanged], 1
755,6 → 793,7
call clear_vmodes_table ;clear vmodes_table
jmp .printcfg
.change_a:
call clear_vmodes_table ;clear vmodes_table
.loops:
call draw_vmodes_table
_setcursor 25,0 ; out of screen
833,29 → 872,47
 
jmp .d
 
.change_b:
_setcursor 15,0
; mov si, ask_dma
.change_b: ; b) preboot_biosdisk = use BIOS disks through V86 emulation?
_setcursor 16,0
; mov si, ask_dma // (earlier was: preboot_dma = use DMA access?)
; call print
; mov bx, '13'
; mov bx, '13' ; range accepted for answer: 1-3
; call getkey
; mov [preboot_dma], al
mov si, ask_bd
call print
mov bx, '12'
mov bx, '12' ; range accepted for answer: 1-2
call getkey
mov [preboot_biosdisk], al
_setcursor 11,0
jmp .d
;.change_c:
; _setcursor 15,0
;.change_c: ; // VRR is an obsolete functionality, used only with CRT monitors
; _setcursor 16,0
; mov si, vrrmprint
; call print
; mov bx, '12'
; mov bx, '12' ; range accepted for answer: 1-2
; call getkey
; mov [preboot_vrrm], al
; _setcursor 12,0
; jmp .d
.change_c: ; c) preboot_debug = duplicates kernel debug output to the screen
_setcursor 16,0
mov si, ask_debug
call print
mov bx, '12' ; range accepted for answer: 1-2
call getkey
mov [preboot_debug], al
_setcursor 12,0
jmp .d
.change_d: ; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded?
_setcursor 16,0
mov si, ask_launcher
call print
mov bx, '12' ; range accepted for answer: 1-2
call getkey
mov [preboot_launcher], al
_setcursor 13,0
jmp .d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.say_on_off:
pushf
963,7 → 1020,7
_setcursor 6,0
mov si, loading_msg
call print
_setcursor 15,0
_setcursor 16,0
if ~ defined extended_primary_loader
cmp [.bSettingsChanged], 0
jz .load
1005,9 → 1062,9
pop ds
mov si, space_msg
mov byte [si+80], 0
_setcursor 15,0
_setcursor 16,0
call printplain
_setcursor 15,0
_setcursor 16,0
.load:
end if
; \end{diamond}[02.12.2005]
1028,8 → 1085,16
;; VRR_M USE
;
; mov al,[preboot_vrrm]
; mov [es:0x9030], al
; mov [es:BOOT_VRR], al ;// 0x9030
 
; Set kernel DEBUG mode - if nonzero, duplicates debug output to the screen.
mov al, [preboot_debug]
mov [es:BOOT_DEBUG_PRINT], al ;// 0x901E
 
; Start the first app (right now it's LAUNCHER) after kernel is loaded?
mov al, [preboot_launcher]
mov [es:BOOT_LAUNCHER_START], al ;// 0x901D
 
; BOOT DEVICE
 
mov al, [preboot_device]
/kernel/branches/Kolibri-acpi/boot/booten.inc
15,12 → 15,10
 
 
d80x25_bottom:
db 186,' KolibriOS is based on MenuetOS and comes with ABSOLUTELY '
db 'NO WARRANTY ',186
db 186,' See file COPYING for details '
db ' ',186
db 186,' KolibriOS comes with ABSOLUTELY NO WARRANTY. See file COP'
db 'YING for details ',186
line_full_bottom
d80x25_bottom_num = 3
d80x25_bottom_num = 2
 
msg_apm db " APM x.x ", 0
novesa db "Display: EGA/CGA",13,10,0
54,7 → 52,7
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
start_msg db "Press [abcde] 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
68,8 → 66,14
on_msg db " on",13,10,0
off_msg db " off",13,10,0
 
preboot_device_msg db " [c] Floppy image: ",0
debug_mode_msg db " [c] Duplicate debug output to the screen:",0
ask_debug db "Duplicate debug output to the screen? [1-yes, 2-no]: ",0
 
launcher_msg db " [d] Start LAUNCHER after kernel is loaded:",0
ask_launcher db "Start first application (LAUNCHER) after kernel is loaded? [1-yes, 2-no]: ",0
 
preboot_device_msg db " [e] Floppy image: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 db "real floppy",13,10,0
/kernel/branches/Kolibri-acpi/boot/bootet.inc
15,12 → 15,10
 
d80x25_bottom:
latin1 '║ KolibriOS pohineb MenuetOS ja kaasas IGASUGUSE GARANTI'
latin1 'ITA ║'
latin1 '║ Naha faili COPYING detailid '
latin1 ' ║'
latin1 '║ KolibriOS kaasas IGASUGUSE GARANTIITA. Naha faili COPY'
latin1 'ING detailid ║'
line_full_bottom
d80x25_bottom_num = 3
d80x25_bottom_num = 2
 
msg_apm: latin1 " APM x.x ", 0
novesa: latin1 "Ekraan: EGA/CGA",13,10,0
54,7 → 52,7
pros: latin1 "00"
backspace2:latin1 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg:latin1 "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
start_msg:latin1 "Vajuta [abcde] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
time_msg: latin1 " või oota "
time_str: latin1 " 5 sekundit"
latin1 " automaatseks jätkamiseks",13,10,0
68,8 → 66,14
on_msg: latin1 " sees",13,10,0
off_msg: latin1 " väljas",13,10,0
 
preboot_device_msg:latin1 " [c] Disketi kujutis: ",0
debug_mode_msg: latin1 " [c] Duplicate siluda väljund ekraani:",0
ask_debug: latin1 "Duplicate siluda väljund ekraani? [1-jah, 2-no]: ",0
 
launcher_msg: latin1 " [d] Alusta LAUNCHER pärast kernel on koormatud:",0
ask_launcher: latin1 "Alusta esimese taotluse (LAUNCHER) pärast kernel laetakse? [1-jah, 2-no]: ",0
 
preboot_device_msg:latin1 " [e] Disketi kujutis: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1: latin1 "reaalne diskett",13,10,0
/kernel/branches/Kolibri-acpi/boot/bootge.inc
15,8 → 15,8
 
 
d80x25_bottom:
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche '
db ' Garantie vertrieben ',186
db 186,' KolibriOS wird ohne jegliche Garantie vertrieben. '
db ' ',186
db 186,' Details stehen in der Datei COPYING '
db ' ',186
line_full_bottom
54,7 → 54,7
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
start_msg db "Druecke [abcde], 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
68,8 → 68,14
on_msg db " an",13,10,0
off_msg db " aus",13,10,0
 
preboot_device_msg db " [c] Diskettenimage: ",0
debug_mode_msg db " [c] Duplizieren debuggen Ausgabe auf dem Bildschirm:",0
ask_debug db "Duplizieren debuggen Ausgabe auf dem Bildschirm? [1-ja, 2 nein]: ",0
 
launcher_msg db " [d] Start LAUNCHER nach Kernel geladen wird:",0
ask_launcher db "Starten erste Anwendung nach Kernel geladen wird? [1-ja, 2 nein]: ",0
 
preboot_device_msg db " [e] Diskettenimage: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 db "Echte Diskette",13,10,0
/kernel/branches/Kolibri-acpi/boot/bootru.inc
15,7 → 15,7
 
 
d80x25_bottom:
cp866 '║ KolibriOS основана на MenuetOS и НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. ║'
cp866 '║ KolibriOS НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. ║'
cp866 '║ Подробнее смотрите в файле COPYING.TXT ║'
line_full_bottom
d80x25_bottom_num = 3
50,7 → 50,7
pros: cp866 "00"
backspace2:cp866 8,8,0
boot_dev db 0
start_msg:cp866 "Нажмите [abcd] для изменения настроек, [Enter] для продолжения загрузки",13,10,0
start_msg:cp866 "Нажмите [abcde] для изменения настроек, [Enter] для продолжения загрузки",13,10,0
time_msg: cp866 " или подождите "
time_str: cp866 " 5 секунд "
cp866 " до автоматического продолжения",13,10,0
64,8 → 64,14
on_msg: cp866 " вкл",13,10,0
off_msg: cp866 " выкл",13,10,0
 
preboot_device_msg:cp866 " [c] Образ дискеты: ",0
debug_mode_msg: cp866 " [c] Дублировать дебаг-вывод на экран монитора:",0
ask_debug: cp866 "Дублировать дебаг-вывод на экран монитора? [1-да, 2-нет]: ",0
 
launcher_msg: cp866 " [d] Запустить программу LAUNCHER после загрузки ядра:",0
ask_launcher: cp866 "Запустить первую программу (LAUNCHER) после загрузки ядра? [1-да, 2-нет]: ",0
 
preboot_device_msg:cp866 " [e] Образ дискеты: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1: cp866 "настоящая дискета",13,10,0
/kernel/branches/Kolibri-acpi/boot/bootsp.inc
17,8 → 17,8
 
 
d80x25_bottom:
cp850 '║ KolibriOS está basado en MenuetOS y viene ABSOLUTAMENTE '
cp850 'SIN GARANTíA ║'
cp850 '║ KolibriOS y viene ABSOLUTAMENTE SIN GARANTíA. '
cp850 ' ║'
cp850 '║ Lee el archivo COPYING por más detalles '
cp850 ' ║'
line_full_bottom
56,7 → 56,7
pros: cp850 "00"
backspace2:cp850 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg:cp850 "Presiona [abcd] para cambiar la configuración, [Enter] para continuar",13,10,0
start_msg:cp850 "Presiona [abcde] para cambiar la configuración, [Enter] para continuar",13,10,0
time_msg: cp850 " o espera "
time_str: cp850 " 5 segundos"
cp850 " para que inicie automáticamente",13,10,0
70,8 → 70,14
on_msg: cp850 " activado",13,10,0
off_msg: cp850 " desactivado",13,10,0
 
preboot_device_msg:cp850 " [c] Imagen de disquete: ",0
debug_mode_msg: cp850 " [c] Duplicar depurar salida a la pantalla:",0
ask_debug: cp850 "¿Duplicar depurar la salida a la pantalla? [1-si, 2-no]: ",0
 
launcher_msg: cp850 " [d] Iniciar LAUNCHER después de cargar kernel:",0
ask_launcher: cp850 "¿Inicie la primera aplicación después de cargar el kernel? [1-si, 2-no]: ",0
 
preboot_device_msg:cp850 " [e] Imagen de disquete: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1: cp850 "disquete real",13,10,0
/kernel/branches/Kolibri-acpi/boot/bootvesa.inc
700,12 → 700,12
mov di, 1444
xor ax, ax
mov ah, 1*16+15
mov cx, 70
mov cx, 77
mov bp, 12
.loop_start:
rep stosw
mov cx, 70
add di, 20
mov cx, 77
add di, 6
dec bp
jns .loop_start
pop es
/kernel/branches/Kolibri-acpi/boot/parsers.inc
5,7 → 5,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2261 $
$Revision: 2288 $
 
; All parsers are called with ds:si -> value of the variable,
; possibly with spaces before, and dx = limit of config file.
/kernel/branches/Kolibri-acpi/boot/preboot.inc
24,6 → 24,8
;pixel_save dw 0 ; per to pixel
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
;preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
preboot_debug db 0 ; load kernel in debug mode? (1-yes, 2-no)
preboot_launcher db 0 ; start launcher after kernel is loaded? (1-yes, 2-no)
preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never)
preboot_device db 0 ; boot device
; (1-floppy 2-harddisk 3-kernel restart 4-format ram disk)
/kernel/branches/Kolibri-acpi/boot/rdload.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8,86 → 8,69
$Revision$
 
 
read_ramdisk:
; 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
xor ebp, ebp
.hd_loop:
lea eax, [ebp+'0']
mov [read_image_fsinfo.name_digit], al
movzx eax, byte [DRIVE_DATA+2+ebp]
test eax, eax
jz .next_hd
push eax
mov esi, 1
.partition_loop:
mov eax, esi
push -'0'
@@:
xor edx, edx
div [_10]
push edx
test eax, eax
jnz @b
mov edi, read_image_fsinfo.partition
@@:
pop eax
add al, '0'
stosb
jnz @b
mov byte [edi-1], '/'
push esi edi
mov esi, bootpath1
mov ecx, bootpath1.len
rep movsb
call read_image
test eax, eax
jz image_present
mov edx, bootpath2
jz .yes
cmp eax, 6
jz .yes
pop edi
push edi
mov esi, bootpath2
mov ecx, bootpath2.len
rep movsb
call read_image
test eax, eax
jz image_present
ret
image_present:
mov [image_retrieved], 1
ret
jz .yes
cmp eax, 6
jz .yes
pop edi esi
inc esi
cmp esi, [esp]
jbe .partition_loop
pop eax
.next_hd:
inc ebp
cmp ebp, 4
jb .hd_loop
jmp no_sys_on_hd
.yes:
pop edi esi eax
jmp yes_sys_on_hd
 
iglobal
align 4
94,10 → 77,18
read_image_fsinfo:
dd 0 ; function: read
dq 0 ; offset: zero
dd 1474560/512 ; size
dd 1474560 ; size
dd RAMDISK ; buffer
db 0
dd hdsysimage+OS_BASE+0x10000
db '/hd'
.name_digit db '0'
db '/'
.partition:
rb 64 ; should be enough for '255/KOLIBRI/KOLIBRI.IMG'
 
bootpath1 db 'KOLIBRI.IMG',0
.len = $ - bootpath1
bootpath2 db 'KOLIBRI/KOLIBRI.IMG',0
.len = $ - bootpath2
endg
 
read_image:
107,8 → 98,6
popad
ret
 
image_retrieved db 0
counter_of_partitions db 0
no_sys_on_hd:
; test_to_format_ram_disk (need if not using ram disk)
cmp [boot_dev+OS_BASE+0x10000], 3
/kernel/branches/Kolibri-acpi/bus/pci/pci32.inc
101,17 → 101,17
 
pci_fn_0:
; PCI function 0: get pci version (AH.AL)
movzx eax, word [BOOT_VAR+0x9022]
movzx eax, word [BOOT_VARS+0x9022]
ret
 
pci_fn_1:
; PCI function 1: get last bus in AL
mov al, [BOOT_VAR+0x9021]
mov al, [BOOT_VARS+0x9021]
ret
 
pci_fn_2:
; PCI function 2: get pci access mechanism
mov al, [BOOT_VAR+0x9020]
mov al, [BOOT_VARS+0x9020]
ret
 
pci_service_not_supported:
156,7 → 156,7
 
pci_read_reg:
push ebx esi
cmp byte [BOOT_VAR+0x9020], 2;what mechanism will we use?
cmp byte [BOOT_VARS+0x9020], 2;what mechanism will we use?
je pci_read_reg_2
 
; mechanism 1
287,7 → 287,7
 
pci_write_reg:
push esi ebx
cmp byte [BOOT_VAR+0x9020], 2;what mechanism will we use?
cmp byte [BOOT_VARS+0x9020], 2;what mechanism will we use?
je pci_write_reg_2
 
; mechanism 1
570,9 → 570,9
cmp ebp, 1 ; PCI_FUNCTION_ID
jnz .not_PCI_BIOS_PRESENT
mov edx, 'PCI '
mov al, [BOOT_VAR + 0x9020]
mov bx, [BOOT_VAR + 0x9022]
mov cl, [BOOT_VAR + 0x9021]
mov al, [BOOT_VARS + 0x9020]
mov bx, [BOOT_VARS + 0x9022]
mov cl, [BOOT_VARS + 0x9021]
xor ah, ah
jmp .return_abcd
 
659,6 → 659,12
mov dword[esp + 32], eax
ret
 
PCI_VENDOR_ID equ 0x00
PCI_CLASS_REVISION equ 0x08
PCI_HEADER_TYPE equ 0x0E
PCI_SUBSYSTEM_VENDOR_ID equ 0x2c
PCI_IRQ_LINE equ 0x3C
 
proc pci_enum
push ebp
mov ebp, esp
671,7 → 677,7
mov ah, [.bus]
mov al, 2
mov bh, [.devfn]
mov bl, 0
mov bl, PCI_VENDOR_ID
call pci_read_reg
cmp eax, 0xFFFFFFFF
jnz .has_device
686,27 → 692,38
test eax, eax
jz .nomemory
mov edi, eax
mov [edi+PCIDEV.vendor_device_id], ecx
mov eax, pcidev_list
mov ecx, [eax+PCIDEV.bk]
mov [edi+PCIDEV.bk], ecx
mov [edi+PCIDEV.fd], eax
mov [ecx+PCIDEV.fd], edi
mov [eax+PCIDEV.bk], edi
mov [edi+PCIDEV.vid_did], ecx
mov edx, pcidev_list
list_add_tail edi, edx
mov eax, dword [.devfn]
mov word [edi+PCIDEV.devfn], ax
mov bh, al
mov al, 2
mov bl, 8
mov bl, PCI_CLASS_REVISION
call pci_read_reg
shr eax, 8
shr eax, 8 ;FIXME use byte mask
mov [edi+PCIDEV.class], eax
 
mov ah, [.bus]
mov bh, byte [.devfn]
mov al, 2
mov bl, PCI_SUBSYSTEM_VENDOR_ID
call pci_read_reg
mov [edi+PCIDEV.svid_sdid], eax
 
mov ah, [.bus]
mov al, 0
mov bh, [.devfn]
mov bl, PCI_IRQ_LINE
call pci_read_reg
mov [edi+PCIDEV.irq_line], al
 
test byte [.devfn], 7
jnz .next_func
mov ah, [.bus]
mov al, 0
mov bh, [.devfn]
mov bl, 0Eh
mov bl, PCI_HEADER_TYPE
call pci_read_reg
test al, al
js .next_func
715,9 → 732,222
.next_func:
inc dword [.devfn]
mov ah, [.bus]
cmp ah, [BOOT_VAR+0x9021]
cmp ah, [BOOT_VARS+0x9021]
jbe .loop
.nomemory:
leave
ret
endp
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;internal functions
;ecx (bus << 8)|devfn
;edx register
 
align 4
pci_bus:
.conf1_index:
; dword CF8 = (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) | (devfn << 8) | (reg & 0xFC))
push edx
mov eax, edx ; eax = reg
shl eax, 16 ; eax = reg << 16
shl ecx, 8 ; ecx = (bus << 16)|(devfn<<8)
mov al, dl ; eax = (reg << 16)|reg
and eax, 0x0F0000FC ; eax = ((reg & 0xF00) << 16)|(reg & 0xFC)
lea eax, [0x80000000+eax+ecx]
mov dx, 0xCF8
out dx, eax
pop edx
xor eax, eax
ret
 
align 4
.conf2_index:
; byte CF8 = 0xF0 | (fn << 1)
; byte CFA = bus
push edx
mov eax, ecx ; (bus << 8)|devfn
and al, 7 ; fn
lea eax, [0xF0+eax+eax]
mov dx, 0xCF8
out dx, al
mov al, ch ; bus
mov dx, 0xCFA
out dx, al
pop edx
xor eax, eax
ret
 
align 4
.conf1_read8:
call .conf1_index
and dx, 3
add dx, 0xCFC
in al, dx
ret
 
align 4
.conf1_read16:
call .conf1_index
and dx, 2
add dx, 0xCFC
in ax, dx
ret
 
align 4
.conf1_read32:
call .conf1_index
mov dx, 0xCFC
in eax, dx
ret
 
align 4
.conf1_write8:
call .conf1_index
mov eax, [esp+4]
and dx, 3
add dx, 0xCFC
out dx, al
ret 4
 
align 4
.conf1_write16:
call .conf1_index
mov eax, [esp+4]
and dx, 2
add dx, 0xCFC
out dx, ax
ret 4
 
align 4
.conf1_write32:
call .conf1_index
mov eax, [esp+4]
mov dx, 0xCFC
out dx, eax
ret 4
 
align 4
.conf2_read8:
; in (0xC000 | (dev << 8) | reg)
call .conf2_index
and ecx, 0xF1 ;ecx = dev << 3
shl ecx, 5 ;ecx = dev << 8
lea edx, [0xC000+edx+ecx]
in al, dx
ret
 
align 4
.conf2_read16:
call .conf2_index
and ecx, 0xF1
shl ecx, 5
lea edx, [0xC000+edx+ecx]
in ax, dx
ret
 
align 4
.conf2_read32:
call .conf2_index
and ecx, 0xF1
shl ecx, 5
lea edx, [0xC000+edx+ecx]
in eax, dx
ret
 
;proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
;proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
;proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
 
;proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
;proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
;proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
 
PCI_R8 equ 0
PCI_R16 equ 4
PCI_R32 equ 8
 
PCI_W8 equ 12
PCI_W16 equ 16
PCI_W32 equ 20
 
align 8
pci_fn_table:
pci_bus_read8 dd pci_bus.conf1_read8 ;0
pci_bus_read16 dd pci_bus.conf1_read16 ;4
pci_bus_read32 dd pci_bus.conf1_read32 ;8
pci_bus_write8 dd pci_bus.conf1_write8 ;12
pci_bus_write16 dd pci_bus.conf1_write16 ;16
pci_bus_write32 dd pci_bus.conf1_write32 ;20
 
align 4
pci_read8:
mov eax, PCI_R8
jmp @F
 
align 4
pci_read16:
mov eax, PCI_R16
jmp @F
 
align 4
pci_read32:
mov eax, PCI_R32
 
align 4
@@:
.bus equ esp+4
.devfn equ esp+8
.pci_reg equ esp+12
 
xor ecx, ecx
mov ch, [.bus]
mov cl, [.devfn]
movzx edx, word [.pci_reg]
 
pushfd
cli
 
call dword [pci_fn_table+eax]
 
popfd
 
ret 12
 
align 4
pci_write8:
mov eax, PCI_W8
jmp @F
 
align 4
pci_write16:
mov eax, PCI_W16
jmp @F
 
align 4
pci_write32:
mov eax, PCI_W32
 
align 4
@@:
.bus equ esp+4
.devfn equ esp+8
.pci_reg equ esp+12
.val equ esp+16
 
xor ecx, ecx
mov ch, [.bus]
mov cl, [.devfn]
movzx edx, word [.pci_reg]
 
pushfd
cli
 
push dword [esp+20]
call dword [pci_fn_table+eax]
 
popfd
 
ret 16
/kernel/branches/Kolibri-acpi/bus/usb/ehci.inc
919,11 → 919,11
; This could fail if the requested bandwidth is not available;
; if so, return an error.
test word [edi+ehci_pipe.Flags-sizeof.ehci_pipe+2], 3FFFh
jnz .interrupt_fs
jnz .interrupt_tt
call ehci_select_hs_interrupt_list
jmp .interrupt_common
.interrupt_fs:
call ehci_select_fs_interrupt_list
.interrupt_tt:
call ehci_select_tt_interrupt_list
.interrupt_common:
test edx, edx
jz .return0
1310,16 → 1310,17
; ehci_init_pipe assumes that the parent pipe is a control pipe.
movzx ecx, [esi+usb_controller.ResettingPort]
mov edx, [esi+usb_controller.ResettingHub]
; If the parent hub is high-speed, it is TT for the device.
; Otherwise, the parent hub itself is behind TT, and the device
; has the same TT hub+port as the parent hub.
push eax
.find_hs_hub:
mov eax, [edx+usb_hub.ConfigPipe]
mov eax, [eax+usb_pipe.DeviceData]
cmp [eax+usb_device_data.Speed], USB_SPEED_HS
jz .found_hs_hub
movzx ecx, [eax+usb_device_data.Port]
mov edx, [eax+usb_device_data.Hub]
jmp .find_hs_hub
.found_hs_hub:
jz @f
movzx ecx, [eax+usb_device_data.TTPort]
mov edx, [eax+usb_device_data.TTHub]
@@:
mov edx, [edx+usb_hub.ConfigPipe]
inc ecx
mov edx, [edx+ehci_pipe.Token-sizeof.ehci_pipe]
/kernel/branches/Kolibri-acpi/bus/usb/hccommon.inc
133,17 → 133,22
; Number of not-yet-closed pipes.
Hub dd ?
; NULL if connected to the root hub, pointer to usb_hub otherwise.
TTHub dd ?
; Pointer to usb_hub for (the) hub with Transaction Translator for the device,
; NULL if the device operates in the same speed as the controller.
Port db ?
; Port on the hub, zero-based.
TTPort db ?
; Port on the TTHub, zero-based.
DeviceDescrSize db ?
; Size of device descriptor.
NumInterfaces db ?
; Number of interfaces.
Speed db ?
; Device speed, one of USB_SPEED_*.
NumInterfaces dd ?
; Number of interfaces.
ConfigDataSize dd ?
; Total size of data associated with the configuration descriptor
; (including the configuration descriptor itself);
; (including the configuration descriptor itself).
Interfaces dd ?
; Offset from the beginning of this structure to Interfaces field.
; Variable-length fields:
/kernel/branches/Kolibri-acpi/bus/usb/init.inc
54,7 → 54,7
mov esi, pcidev_list
push 0
.kickoff:
mov esi, [esi+PCIDEV.fd]
mov esi, [esi+PCIDEV.list.next]
cmp esi, pcidev_list
jz .done_kickoff
cmp word [esi+PCIDEV.class+1], 0x0C03
92,7 → 92,7
; for all EHCI controllers.
mov eax, pcidev_list
.scan_ehci:
mov eax, [eax+PCIDEV.fd]
mov eax, [eax+PCIDEV.list.next]
cmp eax, pcidev_list
jz .done_ehci
cmp [eax+PCIDEV.class], 0x0C0320
105,7 → 105,7
; for all UHCI and OHCI controllers.
mov eax, pcidev_list
.scan_usb1:
mov eax, [eax+PCIDEV.fd]
mov eax, [eax+PCIDEV.list.next]
cmp eax, pcidev_list
jz .done_usb1
mov edi, uhci_hardware_func
/kernel/branches/Kolibri-acpi/bus/usb/ohci.inc
924,7 → 924,12
; esi -> usb_controller, eax -> usb_gtd for the first TD,
; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type
proc ohci_init_pipe
virtual at ebp+8
virtual at ebp-12
.speed db ?
rb 3
.bandwidth dd ?
.target dd ?
rd 2
.config_pipe dd ?
.endpoint dd ?
.maxpacket dd ?
944,6 → 949,8
shl edx, 7
or eax, edx
mov [edi+ohci_pipe.Flags-sizeof.ohci_pipe], eax
bt eax, 13
setc [.speed]
mov eax, [.maxpacket]
mov word [edi+ohci_pipe.Flags+2-sizeof.ohci_pipe], ax
cmp [.type], CONTROL_PIPE
/kernel/branches/Kolibri-acpi/bus/usb/pipe.inc
216,6 → 216,7
proc usb_open_pipe stdcall uses ebx esi edi,\
config_pipe:dword, endpoint:dword, maxpacket:dword, type:dword, interval:dword
locals
tt_vars rd (ehci_select_tt_interrupt_list.local_vars_size + 3) / 4
targetsmask dd ? ; S-Mask for USB2
bandwidth dd ?
target dd ?
509,7 → 510,7
; That was the last pipe for the device.
; 5. Notify device driver(s) about disconnect.
call mutex_unlock
movzx eax, [ecx+usb_device_data.NumInterfaces]
mov eax, [ecx+usb_device_data.NumInterfaces]
test eax, eax
jz .notify_done
add ecx, [ecx+usb_device_data.Interfaces]
697,6 → 698,36
ret
endp
 
; Part of API for drivers, see documentation for USBGetParam.
proc usb_get_param
virtual at esp
dd ? ; return address
.pipe dd ?
.param dd ?
end virtual
mov edx, [.param]
mov ecx, [.pipe]
mov eax, [ecx+usb_pipe.DeviceData]
test edx, edx
jz .get_device_descriptor
dec edx
jz .get_config_descriptor
dec edx
jz .get_speed
or eax, -1
ret 8
.get_device_descriptor:
add eax, usb_device_data.DeviceDescriptor
ret 8
.get_config_descriptor:
movzx ecx, [eax+usb_device_data.DeviceDescrSize]
lea eax, [eax+ecx+usb_device_data.DeviceDescriptor]
ret 8
.get_speed:
movzx eax, [eax+usb_device_data.Speed]
ret 8
endp
 
; Initialize software part of usb_gtd. Called from controller-specific code
; somewhere in AllocTransfer with eax -> next (inactive) usb_gtd,
; ebx -> usb_pipe, ebp frame from call to AllocTransfer with [.td] ->
/kernel/branches/Kolibri-acpi/bus/usb/protocol.inc
239,16 → 239,39
; 2. Store pointer to device data in the pipe structure.
mov [ebx+usb_pipe.DeviceData], eax
; 3. Init device data, using usb_controller.Resetting* variables.
mov [eax+usb_device_data.TTHub], edi
mov [eax+usb_device_data.TTPort], 0
mov [eax+usb_device_data.NumInterfaces], edi
mov [eax+usb_device_data.DeviceDescrSize], 0
mov dl, [esi+usb_controller.ResettingSpeed]
mov [eax+usb_device_data.Speed], dl
mov [eax+usb_device_data.NumPipes], 1
push ebx
cmp dl, USB_SPEED_HS
jz .nott
mov ebx, [esi+usb_controller.ResettingHub]
test ebx, ebx
jz .nott
mov cl, [esi+usb_controller.ResettingPort]
mov edx, [ebx+usb_hub.ConfigPipe]
mov edx, [edx+usb_pipe.DeviceData]
cmp [edx+usb_device_data.TTHub], 0
jz @f
mov cl, [edx+usb_device_data.TTPort]
mov ebx, [edx+usb_device_data.TTHub]
jmp .has_tt
@@:
cmp [edx+usb_device_data.Speed], USB_SPEED_HS
jnz .nott
.has_tt:
mov [eax+usb_device_data.TTHub], ebx
mov [eax+usb_device_data.TTPort], cl
.nott:
pop ebx
mov [eax+usb_device_data.ConfigDataSize], edi
mov [eax+usb_device_data.Interfaces], edi
movzx ecx, [esi+usb_controller.ResettingPort]
; Note: the following write zeroes
; usb_device_data.DeviceDescrSize, usb_device_data.NumInterfaces,
; usb_device_data.Speed.
mov dword [eax+usb_device_data.Port], ecx
mov dl, [esi+usb_controller.ResettingSpeed]
mov [eax+usb_device_data.Speed], dl
mov [eax+usb_device_data.Port], cl
mov edx, [esi+usb_controller.ResettingHub]
mov [eax+usb_device_data.Hub], edx
; 4. Store pointer to the config pipe in the hub data.
470,9 → 493,8
mov [ebx+usb_pipe.DeviceData], eax
mov edi, eax
mov eax, esi
repeat sizeof.usb_device_data / 4
movsd
end repeat
mov ecx, sizeof.usb_device_data / 4
rep movsd
pop edi esi
call usb_reinit_pipe_list
; 1d. Free the old memory.
736,7 → 758,7
jmp .nothing
@@:
; 3. Store the number of interfaces in device data structure.
mov [ebx+usb_device_data.NumInterfaces], dl
mov [ebx+usb_device_data.NumInterfaces], edx
; 4. If there is only one interface (which happens quite often),
; the memory allocated in usb_know_length_callback is sufficient.
; Otherwise (which also happens quite often), reallocate device data.
775,7 → 797,7
mov edi, [ebx+usb_device_data.Interfaces]
add edi, ebx
mov [InterfacesData], edi
movzx ecx, [ebx+usb_device_data.NumInterfaces]
mov ecx, [ebx+usb_device_data.NumInterfaces]
if sizeof.usb_interface_data <> 8
You have changed sizeof.usb_interface_data? Modify this place too.
end if
837,9 → 859,8
@@:
; 7f. Check that the new interface does not overflow allocated table.
mov edx, [NumInterfaces]
inc dl
jz .invalid
cmp dl, [ebx+usb_device_data.NumInterfaces]
inc edx
cmp edx, [ebx+usb_device_data.NumInterfaces]
ja .invalid
; 7g. We have found a new interface. Advance bookkeeping vars.
mov [NumInterfaces], edx
/kernel/branches/Kolibri-acpi/bus/usb/scheduler.inc
20,7 → 20,9
; out: edx -> usb_static_ep for the selected list or zero if failed
proc usb1_select_interrupt_list
; inherit some variables from usb_open_pipe
virtual at ebp-8
virtual at ebp-12
.speed db ?
rb 3
.bandwidth dd ?
.target dd ?
dd ?
116,20 → 118,32
add edx, sizeof.ohci_static_ep
dec ecx
jnz .varloop
; 4. Get the pointer to the best list.
; 4. Calculate bandwidth for the new pipe.
mov eax, [.maxpacket]
mov cl, [.speed]
mov ch, byte [.endpoint]
and ch, 80h
call calc_usb1_bandwidth
; 5. Get the pointer to the best list.
pop edx ; restore value from step 2
pop eax ; purge stack var from prolog
pop ecx ; purge stack var from prolog
add edx, [.target]
; 5. Calculate bandwidth for the new pipe.
mov eax, [.maxpacket] ; TODO: calculate real bandwidth
and eax, (1 shl 11) - 1
; 6. TODO: check that bandwidth for the new pipe plus old bandwidth
; still fits to maximum allowed by the core specification.
; 6. Check that bandwidth for the new pipe plus old bandwidth
; still fits to maximum allowed by the core specification, 90% of 12000 bits.
mov ecx, eax
add ecx, [.bandwidth]
cmp ecx, 10800
ja .no_bandwidth
; 7. Convert {o|u}hci_static_ep to usb_static_ep, update bandwidth and return.
add edx, ohci_static_ep.SoftwarePart
add [edx+usb_static_ep.Bandwidth], eax
pop edi ebx ; restore used registers to be stdcall
ret
.no_bandwidth:
dbgstr 'Periodic bandwidth limit reached'
xor edx, edx
pop edi ebx
ret
endp
; sanity check, part 2
else
147,28 → 161,85
.direction db ?
rb 2
end virtual
; calculate bandwidth on the bus
mov eax, [.maxpacket]
mov ecx, dword [.lowspeed]
call calc_usb1_bandwidth
; find list header
mov edx, ebx
@@:
mov edx, [edx+usb_pipe.NextVirt]
cmp [edx+usb_pipe.Controller], esi
jnz @b
jz @b
; subtract pipe bandwidth
; TODO: calculate real bandwidth
mov eax, [.maxpacket]
and eax, (1 shl 11) - 1
sub [edx+usb_static_ep.Bandwidth], eax
ret 8
endp
 
; Helper procedure for USB1 scheduler: calculate bandwidth on the bus.
; in: low 11 bits of eax = payload size in bytes
; in: cl = 0 - full-speed, nonzero - high-speed
; in: ch = 0 - OUT, nonzero - IN
; out: eax = maximal bandwidth in FS-bits
proc calc_usb1_bandwidth
and eax, (1 shl 11) - 1 ; get payload for one transaction
add eax, 3 ; add 3 bytes for other fields in data packet, PID+CRC16
test cl, cl
jnz .low_speed
; Multiply by 8 for bytes -> bits, by 7/6 to accomodate bit stuffing
; and by 401/400 for IN transfers to accomodate timers difference
; 9+107/300 for IN transfers, 9+1/3 for OUT transfers
; For 0 <= eax < 09249355h, floor(eax * 107/300) = floor(eax * 5B4E81B5h / 2^32).
; For 0 <= eax < 80000000h, floor(eax / 3) = floor(eax * 55555556h / 2^32).
mov edx, 55555556h
test ch, ch
jz @f
mov edx, 5B4E81B5h
@@:
lea ecx, [eax*9]
mul edx
; Add 93 extra bits: 39 bits for Token packet (8 for SYNC, 24 for token+address,
; 4 extra bits for possible bit stuffing in token+address, 3 for EOP),
; 18 bits for bus turn-around, 11 bits for SYNC+EOP in Data packet plus 1 bit
; for possible timers difference, 2 bits for inter-packet delay, 20 bits for
; Handshake packet, 2 bits for another inter-packet delay.
lea eax, [ecx+edx+93]
ret
.low_speed:
; Multiply by 8 for bytes -> bits, by 7/6 to accomodate bit stuffing,
; by 8 for LS -> FS and by 406/50 for IN transfers to accomodate timers difference.
; 75+59/75 for IN transfers, 74+2/3 for OUT transfers.
mov edx, 0AAAAAABh
test ch, ch
mov ecx, 74
jz @f
mov edx, 0C962FC97h
inc ecx
@@:
imul ecx, eax
mul edx
; Add 778 extra bits:
; 16 bits for PRE packet, 4 bits for hub delay, 8*39 bits for Token packet
; 8*18 bits for bus turn-around
; (406/50)*11 bits for SYNC+EOP in Data packet,
; 8*2 bits for inter-packet delay,
; 16 bits for PRE packet, 4 bits for hub delay, 8*20 bits for Handshake packet,
; 8*2 bits for another inter-packet delay.
lea eax, [ecx+edx+778]
ret
endp
 
; USB2 scheduler.
; There are two parts: high-speed pipes and split-transaction pipes.
; Split-transaction scheduler is currently a stub.
;
; High-speed scheduler uses the same algorithm as USB1 scheduler:
; when adding a pipe, optimize the following quantity:
; * for every microframe, take all bandwidth scheduled to periodic transfers,
; * calculate maximum over all microframe,
; * calculate maximum over all microframes,
; * select a variant which minimizes that maximum;
; * if there are several such variants,
; prefer those that are closer to end of frame
; to minimize collisions with split transactions;
; when removing a pipe, do nothing (except for bookkeeping).
; in: esi -> usb_controller
; out: edx -> usb_static_ep, eax = S-Mask
277,11 → 348,13
; then the previous optimum, update the optimal bandwidth and the target.
cmp edi, [.bandwidth]
ja @f
jb .update
cmp ecx, [.targetsmask]
jb @f
.update:
mov [.bandwidth], edi
mov [.target], edx
movi eax, 1
shl eax, cl
mov [.targetsmask], eax
mov [.targetsmask], ecx
@@:
; 4k. Loop #2: continue 8 times for every microframe.
inc ecx
292,23 → 365,26
add edx, sizeof.ehci_static_ep
dec ebx
jnz .varloop0
; 5. Get the pointer to the best list.
pop edx ; restore value from step 3
pop edx ; get delta calculated in step 3
add edx, [.target]
; 6. Calculate bandwidth for the new pipe.
; TODO1: calculate real bandwidth
; 5. Calculate bandwidth for the new pipe.
mov eax, [.maxpacket]
mov ecx, eax
and eax, (1 shl 11) - 1
call calc_hs_bandwidth
mov ecx, [.maxpacket]
shr ecx, 11
inc ecx
and ecx, 3
imul eax, ecx
; 7. TODO2: check that bandwidth for the new pipe plus old bandwidth
; 6. Get the pointer to the best list.
pop edx ; restore value from step 3
pop edx ; get delta calculated in step 3
add edx, [.target]
; 7. Check that bandwidth for the new pipe plus old bandwidth
; still fits to maximum allowed by the core specification
; current [.bandwidth] + new bandwidth <= limit;
; USB2 specification allows maximum 60000*80% bit times for periodic microframe
mov ecx, [.bandwidth]
add ecx, eax
cmp ecx, 48000
ja .no_bandwidth
; 8. Convert {o|u}hci_static_ep to usb_static_ep, update bandwidth and return.
mov ecx, [.targetsmask]
add [edx+ehci_static_ep.Bandwidths+ecx*2], ax
317,6 → 393,12
shl eax, cl
pop edi ebx ; restore used registers to be stdcall
ret
.no_bandwidth:
dbgstr 'Periodic bandwidth limit reached'
xor eax, eax
xor edx, edx
pop edi ebx
ret
.every_frame:
; The pipe should be scheduled every frame in two or more microframes.
; 9. Calculate maximal bandwidth for every microframe: three nested loops.
374,7 → 456,7
mov dl, 0xFF
@@:
; try all variants edx, edx shl 1, edx shl 2, ...
; until they fit in the lower byte (8 microframes per frame)
; while they fit in the lower byte (8 microframes per frame)
.select_best_mframe:
xor edi, edi
mov ecx, edx
400,17 → 482,21
add esp, 8*4
; 12. Get the pointer to the target list (responsible for every microframe).
lea edx, [esi+ehci_controller.IntEDs.SoftwarePart+62*sizeof.ehci_static_ep-sizeof.ehci_controller]
; 13. TODO1: calculate real bandwidth.
; 13. Calculate bandwidth on the bus.
mov eax, [.maxpacket]
mov ecx, eax
and eax, (1 shl 11) - 1
call calc_hs_bandwidth
mov ecx, [.maxpacket]
shr ecx, 11
inc ecx
and ecx, 3
imul eax, ecx
; 14. TODO2: check that current [.bandwidth] + new bandwidth <= limit;
; 14. Check that current [.bandwidth] + new bandwidth <= limit;
; USB2 specification allows maximum 60000*80% bit times for periodic microframe.
; Update bandwidths including the new pipe.
mov ecx, [.bandwidth]
add ecx, eax
cmp ecx, 48000
ja .no_bandwidth
; 15. Update bandwidths including the new pipe.
mov ecx, [.targetsmask]
lea edi, [edx+ehci_static_ep.Bandwidths-ehci_static_ep.SoftwarePart]
.update_bandwidths:
421,7 → 507,7
add edi, 2
test ecx, ecx
jnz .update_bandwidths
; 15. Return target list and target S-Mask.
; 16. Return target list and target S-Mask.
mov eax, [.targetsmask]
pop edi ebx ; restore used registers to be stdcall
ret
431,21 → 517,20
; We do not reorder anything, so just update book-keeping variable
; in the list header.
proc ehci_hs_interrupt_list_unlink
; get target list
mov edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
; TODO: calculate real bandwidth
movzx eax, word [ebx+ehci_pipe.Token-sizeof.ehci_pipe+2]
; calculate bandwidth
call calc_hs_bandwidth
mov ecx, [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
and eax, (1 shl 11) - 1
shr ecx, 30
imul eax, ecx
movzx ecx, byte [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
add edx, ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart
; get target list
mov edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
; update bandwidth
.dec_bandwidth:
shr ecx, 1
jnc @f
sub [edx], ax
sub word [edx+ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart], ax
@@:
add edx, 2
test ecx, ecx
454,18 → 539,298
ret
endp
 
uglobal
ehci_last_fs_alloc dd ?
endg
; Helper procedure for USB2 scheduler: calculate bandwidth on the bus.
; in: low 11 bits of eax = payload size in bytes
; out: eax = maximal bandwidth in HS-bits
proc calc_hs_bandwidth
and eax, (1 shl 11) - 1 ; get payload for one transaction
add eax, 3 ; add 3 bytes for other fields in data packet, PID+CRC16
; Multiply by 8 for bytes -> bits and then by 7/6 to accomodate bit stuffing;
; total 28/3 = 9+1/3
mov edx, 55555556h
lea ecx, [eax*9]
mul edx
; Add 989 extra bits: 68 bits for Token packet (32 for SYNC, 24 for token+address,
; 4 extra bits for possible bit stuffing in token+address, 8 for EOP),
; 736 bits for bus turn-around, 40 bits for SYNC+EOP in Data packet,
; 8 bits for inter-packet delay, 49 bits for Handshake packet,
; 88 bits for another inter-packet delay.
lea eax, [ecx+edx+989]
ret
endp
 
; This needs to be rewritten. Seriously.
; It schedules everything to the first microframe of some frame,
; frame is spinned out of thin air.
; This works while you have one keyboard and one mouse...
; maybe even ten keyboards and ten mice... but give any serious stress,
; and this would break.
proc ehci_select_fs_interrupt_list
virtual at ebp-12
; Split-transaction scheduler (aka TT scheduler, TT stands for Transaction
; Translator, section 11.14 of the core spec) needs to schedule three event
; types on two buses: Start-Split and Complete-Split on HS bus and normal
; transaction on FS/LS bus.
; Assume that FS/LS bus is more restricted and more important to be scheduled
; uniformly, so select the variant which minimizes maximal used bandwidth
; on FS/LS bus and does not overflow HS bus.
; If there are several such variants, prefer variants which is closest to
; start of frame, and within the same microframe consider HS bandwidth
; utilization as a last criteria.
 
; The procedure ehci_select_tt_interrupt_list has been splitted into several
; macro, each representing a logical step of the procedure,
; to simplify understanding what is going on. Consider all the following macro
; as logical parts of one procedure, they are meaningless outside the context.
 
; Given a frame, calculate bandwidth occupied by already opened pipes
; in every microframe.
; Look for both HS and FS/LS buses: there are 16 words of information,
; 8 for HS bus, 8 for FS/LS bus, for every microframe.
; Since we count already opened pipes, the total bandwidth in every microframe
; is less than 60000 bits (and even 60000*80% bits), otherwise the scheduler
; would not allow to open those pipes.
; edi -> first list for the frame
macro tt_calc_bandwidth_in_frame
{
local .lists, .pipes, .pipes_done, .carry
; 1. Zero everything.
xor eax, eax
mov edx, edi
repeat 4
mov dword [.budget+(%-1)*4], eax
end repeat
repeat 4
mov dword [.hs_bandwidth+(%-1)*4], eax
end repeat
mov [.total_budget], ax
; Loop over all lists for the given frame.
.lists:
; 2. Total HS bandwidth for all pipes in one list is kept inside list header,
; add it. Note that overflow is impossible, so we may add entire dwords.
mov ebx, [edx+ehci_static_ep.SoftwarePart+usb_static_ep.NextVirt]
repeat 4
mov eax, dword [edx+ehci_static_ep.Bandwidths+(%-1)*4]
add dword [.hs_bandwidth+(%-1)*4], eax
end repeat
; Loop over all pipes in the given list.
add edx, ehci_static_ep.SoftwarePart
.pipes:
cmp ebx, edx
jz .pipes_done
; 3. For every pipe in every list for the given frame:
; 3a. Check whether the pipe resides on the same FS/LS bus as the new pipe.
; If not, skip this pipe.
mov eax, [ebx+usb_pipe.DeviceData]
mov eax, [eax+usb_device_data.TTHub]
cmp eax, [.tthub]
jnz @f
; 3b. Calculate FS/LS budget for the opened pipe.
; Note that eax = TTHub after 3a.
call tt_calc_budget
; 3c. Update total budget: add the value from 3b
; to the budget of the first microframe scheduled for this pipe.
bsf ecx, [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
add [.budget+ecx*2], ax
@@:
mov ebx, [ebx+usb_pipe.NextVirt]
jmp .pipes
.pipes_done:
mov edx, [edx+ehci_static_ep.NextList-ehci_static_ep.SoftwarePart]
test edx, edx
jnz .lists
; 4. If the budget for some microframe is exceeded, carry it to the following
; microframe(s). The actual size of one microframe is 187.5 raw bytes;
; the core spec says that 188 bytes should be scheduled in every microframe.
xor eax, eax
xor ecx, ecx
.carry:
xor edx, edx
add ax, [.budget+ecx*2]
cmp ax, 188
jbe @f
mov dx, ax
mov ax, 188
sub dx, ax
@@:
mov [.budget+ecx*2], ax
add [.total_budget], ax
mov ax, dx
inc ecx
cmp ecx, 8
jb .carry
}
 
; Checks whether the new pipe fits in the existing FS budget
; starting from the given microframe. If not, mark the microframe
; as impossible for scheduling.
; in: ecx = microframe
macro tt_exclude_microframe_if_no_budget
{
local .loop, .good, .bad
; 1. If the new budget plus the current budget does not exceed 188 bytes,
; the variant is possible.
mov ax, [.budget+ecx*2]
mov edx, ecx
add ax, [.new_budget]
sub ax, 188
jbe .good
; 2. Otherwise,
; a) nothing should be scheduled in some following microframes,
; b) after adding the new budget everything should fit in first 6 microframes,
; this guarantees that even in the worst case 90% limit is satisfied.
.loop:
cmp edx, 5
jae .bad
cmp [.budget+(edx+1)*2], 0
jnz .bad
inc edx
sub ax, 188
ja .loop
.bad:
btr [.possible_microframes], ecx
.good:
}
 
; Calculate data corresponding to the particular scheduling variant for the new pipe.
; Data describe the current scheduling state collected over all frames touched
; by the given variant: maximal HS bandwidth, maximal FS/LS budget,
; which microframes fit in the current FS/LS budget for all frames.
macro tt_calc_statistics_for_one_variant
{
local .frames, .microframes
; 1. Initialize: zero maximal bandwidth,
; first 6 microframes are possible for scheduling.
xor eax, eax
repeat 4
mov dword [.max_hs_bandwidth+(%-1)*4], eax
end repeat
mov [.max_fs_bandwidth], ax
mov [.possible_microframes], 0x3F
; Loop over all frames starting with [.variant] advancing by [.variant_delta].
mov edi, [.variant]
.frames:
; 2. Calculate statistics for one frame.
tt_calc_bandwidth_in_frame
; 3. Update maximal FS budget.
mov ax, [.total_budget]
cmp ax, [.max_fs_bandwidth]
jb @f
mov [.max_fs_bandwidth], ax
@@:
; 4. For every microframe, update maximal HS bandwidth
; and check whether the microframe is allowed for scheduling.
xor ecx, ecx
.microframes:
mov ax, [.hs_bandwidth+ecx*2]
cmp ax, [.max_hs_bandwidth+ecx*2]
jb @f
mov [.max_hs_bandwidth+ecx*2], ax
@@:
tt_exclude_microframe_if_no_budget
inc ecx
cmp ecx, 8
jb .microframes
; Stop loop when outside of first descriptor group.
lea eax, [esi+ehci_controller.IntEDs+32*sizeof.ehci_static_ep-sizeof.ehci_controller]
add edi, [.variant_delta]
cmp edi, eax
jb .frames
}
 
struct usb_split_info
microframe_mask dd ? ; lower byte is S-mask, second byte is C-mask
ssplit_bandwidth dd ?
csplit_bandwidth dd ?
ends
 
; Check whether the current variant and the current microframe are allowed
; for scheduling. If so, check whether they are better than the previously
; selected variant+microframe, if any. If so, update the previously selected
; variant+microframe to current ones.
; ecx = microframe, [.variant] = variant
macro tt_check_variant_microframe
{
local .nothing, .update, .ssplit, .csplit, .csplit_done
; 1. If the current microframe does not fit in existing FS budget, do nothing.
bt [.possible_microframes], ecx
jnc .nothing
; 2. Calculate maximal HS bandwidth over all affected microframes.
; 2a. Start-split phase: one or more microframes starting with ecx,
; coded in lower byte of .info.microframe_mask.
xor ebx, ebx
xor edx, edx
.ssplit:
lea eax, [ecx+edx]
movzx eax, [.max_hs_bandwidth+eax*2]
add eax, [.info.ssplit_bandwidth]
cmp ebx, eax
ja @f
mov ebx, eax
@@:
inc edx
bt [.info.microframe_mask], edx
jc .ssplit
; 2b. Complete-split phase: zero or more microframes starting with
; ecx+(last start-split microframe)+2,
; coded in second byte of .info.microframe_mask.
add edx, 8
.csplit:
inc edx
bt [.info.microframe_mask], edx
jnc .csplit_done
lea eax, [ecx+edx]
cmp eax, 8
jae .csplit_done
movzx eax, [.max_hs_bandwidth+(eax-8)*2]
add eax, [.info.csplit_bandwidth]
cmp ebx, eax
ja .csplit
mov ebx, eax
jmp .csplit
.csplit_done:
; 3. Check that current HS bandwidth + new bandwidth <= limit;
; USB2 specification allows maximum 60000*80% bit times for periodic microframe.
cmp ebx, 48000
ja .nothing
; 4. This variant is possible for scheduling.
; Check whether it is better than the currently selected one.
; 4a. The primary criteria: FS/LS bandwidth.
mov ax, [.max_fs_bandwidth]
cmp ax, [.best_fs_bandwidth]
ja .nothing
jb .update
; 4b. The secondary criteria: prefer microframes which are closer to start of frame.
cmp ecx, [.targetsmask]
ja .nothing
jb .update
; 4c. The last criteria: HS bandwidth.
cmp ebx, [.bandwidth]
ja .nothing
.update:
; 5. This variant is better than the previously selected.
; Update the best variant with current data.
mov [.best_fs_bandwidth], ax
mov [.bandwidth], ebx
mov [.targetsmask], ecx
mov eax, [.variant]
mov [.target], eax
.nothing:
}
 
; TT scheduler: add new pipe.
; in: esi -> usb_controller, edi -> usb_pipe
; out: edx -> usb_static_ep, eax = S-Mask
proc ehci_select_tt_interrupt_list
virtual at ebp-12-.local_vars_size
.local_vars_start:
.info usb_split_info
.new_budget dw ?
.total_budget dw ?
.possible_microframes dd ?
.tthub dd ?
.budget rw 8
.hs_bandwidth rw 8
.max_hs_bandwidth rw 8
.max_fs_bandwidth dw ?
.best_fs_bandwidth dw ?
.variant dd ?
.variant_delta dd ?
.target_delta dd ?
.local_vars_size = $ - .local_vars_start
 
.targetsmask dd ?
.bandwidth dd ?
.target dd ?
477,26 → 842,246
.type dd ?
.interval dd ?
end virtual
mov eax, [edi+ehci_pipe.Token-sizeof.ehci_pipe]
shr eax, 16
and eax, (1 shl 11) - 1
push ebx edi
; 1. Compute the real interval. FS/LS devices encode the interval as
; number of milliseconds. Use the maximal power of two that is not greater than
; the given interval and EHCI scheduling area = 32 frames.
cmp [.interval], 1
adc [.interval], 0
mov ecx, 64
mov eax, ecx
mov eax, 64 * sizeof.ehci_static_ep
@@:
shr ecx, 1
cmp [.interval], ecx
jb @b
mov [.interval], ecx
; 2. Compute variables for further calculations.
; 2a. [.variant_delta] is delta between two lists from the first group
; that correspond to the same variant.
imul ecx, sizeof.ehci_static_ep
mov [.variant_delta], ecx
; 2b. [.target_delta] is delta between the final answer from the group
; corresponding to [.interval] and the item from the first group.
sub eax, ecx
sub eax, ecx
dec ecx
and ecx, [ehci_last_fs_alloc]
inc [ehci_last_fs_alloc]
add eax, ecx
imul eax, sizeof.ehci_static_ep
lea edx, [esi+ehci_controller.IntEDs.SoftwarePart+eax-sizeof.ehci_controller]
mov ax, 1C01h
mov [.target_delta], eax
; 2c. [.variant] is the first list from the first group that corresponds
; to the current variant.
lea eax, [esi+ehci_controller.IntEDs-sizeof.ehci_controller]
mov [.variant], eax
; 2d. [.tthub] identifies TT hub for new pipe, [.new_budget] is FS budget
; for new pipe.
mov eax, [edi+usb_pipe.DeviceData]
mov eax, [eax+usb_device_data.TTHub]
mov ebx, edi
mov [.tthub], eax
call tt_calc_budget
mov [.new_budget], ax
; 2e. [.usb_split_info] describes bandwidth used by new pipe on HS bus.
lea edi, [.info]
call tt_fill_split_info
test eax, eax
jz .no_bandwidth
; 2f. There is no best variant yet, put maximal possible values,
; so any variant would be better than the "current".
or [.best_fs_bandwidth], -1
or [.target], -1
or [.bandwidth], -1
or [.targetsmask], -1
; 3. Loop over all variants, for every variant decide whether it is acceptable,
; select the best variant from all acceptable variants.
.check_variants:
tt_calc_statistics_for_one_variant
xor ecx, ecx
.check_microframes:
tt_check_variant_microframe
inc ecx
cmp ecx, 6
jb .check_microframes
add [.variant], sizeof.ehci_static_ep
dec [.interval]
jnz .check_variants
; 4. If there is no acceptable variants, return error.
mov ecx, [.targetsmask]
mov edx, [.target]
cmp ecx, -1
jz .no_bandwidth
; 5. Calculate the answer: edx -> selected list, eax = S-Mask and C-Mask.
mov eax, [.info.microframe_mask]
add edx, [.target_delta]
shl eax, cl
and eax, 0xFFFF
; 6. Update HS bandwidths in the selected list.
xor ecx, ecx
mov ebx, [.info.ssplit_bandwidth]
.update_ssplit:
bt eax, ecx
jnc @f
add [edx+ehci_static_ep.Bandwidths+ecx*2], bx
@@:
inc ecx
cmp ecx, 8
jb .update_ssplit
mov ebx, [.info.csplit_bandwidth]
.update_csplit:
bt eax, ecx
jnc @f
add [edx+ehci_static_ep.Bandwidths+(ecx-8)*2], bx
@@:
inc ecx
cmp ecx, 16
jb .update_csplit
; 7. Return.
add edx, ehci_static_ep.SoftwarePart
pop edi ebx
ret
.no_bandwidth:
dbgstr 'Periodic bandwidth limit reached'
xor eax, eax
xor edx, edx
pop edi ebx
ret
endp
 
; Pipe is removing, update the corresponding lists.
; We do not reorder anything, so just update book-keeping variable
; in the list header.
proc ehci_fs_interrupt_list_unlink
; calculate bandwidth
push edi
sub esp, sizeof.usb_split_info
mov edi, esp
call tt_fill_split_info
; get target list
mov edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
; update bandwidth for Start-Split
mov eax, [edi+usb_split_info.ssplit_bandwidth]
xor ecx, ecx
.dec_bandwidth_1:
bt [ebx+ehci_pipe.Flags-sizeof.ehci_pipe], ecx
jnc @f
sub word [edx+ecx*2+ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart], ax
@@:
inc ecx
cmp ecx, 8
jb .dec_bandwidth_1
; update bandwidth for Complete-Split
mov eax, [edi+usb_split_info.csplit_bandwidth]
.dec_bandwidth_2:
bt [ebx+ehci_pipe.Flags-sizeof.ehci_pipe], ecx
jnc @f
sub word [edx+(ecx-8)*2+ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart], ax
@@:
inc ecx
cmp ecx, 16
jb .dec_bandwidth_2
add esp, sizeof.usb_split_info
pop edi
ret
endp
 
; Helper procedure for ehci_select_tt_interrupt_list.
; Calculates "best-case budget" according to the core spec,
; that is, number of bytes (not bits) corresponding to "optimistic" transaction
; time, including inter-packet delays/bus turn-around time,
; but without bit stuffing and timers drift.
; One extra TT-specific delay is added: TT think time from the hub descriptor.
; Similar to calc_usb1_bandwidth with corresponding changes.
; eax -> usb_hub with TT, ebx -> usb_pipe
proc tt_calc_budget
movzx ecx, [eax+usb_hub.HubCharacteristics]
shr ecx, 5
and ecx, 3 ; 1+ecx = TT think time in FS-bytes
mov eax, [ebx+ehci_pipe.Token-sizeof.ehci_pipe]
shr eax, 16
and eax, (1 shl 11) - 1 ; get data length
bt [ebx+ehci_pipe.Token-sizeof.ehci_pipe], 12
jc .low_speed
; Full-speed interrupt IN/OUT:
; 33 bits for Token packet (8 for SYNC, 24 for token+address, 3 for EOP),
; 18 bits for bus turn-around, 11 bits for SYNC+EOP in Data packet,
; 2 bits for inter-packet delay, 19 bits for Handshake packet,
; 2 bits for another inter-packet delay. 85 bits total, pad to 11 bytes.
lea eax, [eax+11+ecx+1]
; 1 byte is minimal TT think time in addition to ecx.
ret
.low_speed:
; Low-speed interrupt IN/OUT:
; multiply by 8 for LS -> FS,
; add 85 bytes as in full-speed interrupt and extra 5 bytes for two PRE packets
; and two hub delays.
; 1 byte is minimal TT think time in addition to ecx.
lea eax, [eax*8+90+ecx+1]
ret
endp
 
; Helper procedure for TT scheduler.
; Calculates Start-Split/Complete-Split masks and HS bandwidths.
; ebx -> usb_pipe, edi -> usb_split_info
proc tt_fill_split_info
; Interrupt endpoints.
; The core spec says in 5.7.3 "Interrupt Transfer Packet Size Constraints" that:
; The maximum allowable interrupt data payload size is 64 bytes or less for full-speed.
; Low-speed devices are limited to eight bytes or less maximum data payload size.
; This is important for scheduling, it guarantees that in any case transaction fits
; in two microframes (usually one, two if transaction has started too late in the first
; microframe), so check it.
mov eax, [ebx+ehci_pipe.Token-sizeof.ehci_pipe]
mov ecx, 8
bt eax, 12
jc @f
mov ecx, 64
@@:
shr eax, 16
and eax, (1 shl 11) - 1 ; get data length
cmp eax, ecx
ja .error
add eax, 3 ; add 3 bytes for other fields in data packet, PID+CRC16
; Multiply by 8 for bytes -> bits and then by 7/6 to accomodate bit stuffing;
; total 28/3 = 9+1/3
mov edx, 55555556h
lea ecx, [eax*9]
mul edx
; One start-split, three complete-splits (unless the last is too far,
; but this is handled by the caller).
mov eax, [ebx+usb_pipe.LastTD]
mov [edi+usb_split_info.microframe_mask], 0x1C01
; Structure and HS bandwidth of packets depends on the direction.
bt [eax+ehci_gtd.Token-sizeof.ehci_gtd], 8
jc .interrupt_in
.interrupt_out:
; Start-Split phase:
; 77 bits for SPLIT packet (32 for SYNC, 8 for EOP, 32 for data, 5 for bit stuffing),
; 88 bits for inter-packet delay, 68 bits for Token packet,
; 88 bits for inter-packet delay, 40 bits for SYNC+EOP in Data packet,
; 88 bits for last inter-packet delay, total 449 bits.
lea eax, [edx+ecx+449]
mov [edi+usb_split_info.ssplit_bandwidth], eax
; Complete-Split phase:
; 77 bits for SPLIT packet,
; 88 bits for inter-packet delay, 68 bits for Token packet,
; 736 bits for bus turn-around, 49 bits for Handshake packet,
; 8 bits for inter-packet delay, total 1026 bits.
mov [edi+usb_split_info.csplit_bandwidth], 1026
ret
.interrupt_in:
; Start-Split phase:
; 77 bits for SPLIT packet, 88 bits for inter-packet delay,
; 68 bits for Token packet, 88 bits for another inter-packet delay,
; total 321 bits.
mov [edi+usb_split_info.ssplit_bandwidth], 321
; Complete-Split phase:
; 77 bits for SPLIT packet, 88 bits for inter-packet delay,
; 68 bits for Token packet, 736 bits for bus turn-around,
; 40 bits for SYNC+EOP in Data packet, 8 bits for inter-packet delay,
; total 1017 bits.
lea eax, [edx+ecx+1017]
mov [edi+usb_split_info.csplit_bandwidth], eax
ret
.error:
xor eax, eax
ret
endp
/kernel/branches/Kolibri-acpi/bus/usb/uhci.inc
1375,7 → 1375,12
; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type
proc uhci_init_pipe
; inherit some variables from the parent usb_open_pipe
virtual at ebp+8
virtual at ebp-12
.speed db ?
rb 3
.bandwidth dd ?
.target dd ?
rd 2
.config_pipe dd ?
.endpoint dd ?
.maxpacket dd ?
1413,6 → 1418,8
mov al, USB_PID_IN
@@:
mov [edi+uhci_pipe.Token-sizeof.uhci_pipe], eax
bt eax, 20
setc [.speed]
; 4. Initialize the first TD:
; copy Token from uhci_pipe.Token zeroing reserved bit 20,
; set ControlStatus for future transfers, bit make it inactive,
/kernel/branches/Kolibri-acpi/const.inc
184,18 → 184,55
 
OS_BASE equ 0x80000000
 
TASK_COUNT equ (CURRENT_TASK+0x04)
TASK_BASE equ (CURRENT_TASK+0x10)
TASK_DATA equ (CURRENT_TASK+0x20)
TASK_EVENT equ (CURRENT_TASK+0x20)
FDD_BUFF equ (OS_BASE+0x000D000)
window_data equ (OS_BASE+0x0001000)
 
CURRENT_TASK equ (OS_BASE+0x0003000)
TASK_COUNT equ (OS_BASE+0x0003004)
TASK_BASE equ (OS_BASE+0x0003010)
TASK_DATA equ (OS_BASE+0x0003020)
TASK_EVENT equ (OS_BASE+0x0003020)
 
CDDataBuf equ (OS_BASE+0x0005000)
 
;unused 0x6000 - 0x8fff
 
BOOT_VARS equ (OS_BASE) ;0x9000
 
idts equ (OS_BASE+0x000B100)
WIN_STACK equ (OS_BASE+0x000C000)
WIN_POS equ (OS_BASE+0x000C400)
FDD_BUFF equ (OS_BASE+0x000D000) ;512
 
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)
 
 
BTN_ADDR equ (OS_BASE+0x000FE88)
MEM_AMOUNT equ (OS_BASE+0x000FE8C)
 
SYS_SHUTDOWN equ (OS_BASE+0x000FF00)
TASK_ACTIVATE equ (OS_BASE+0x000FF01)
 
 
TMP_STACK_TOP equ 0x006CC00
 
sys_pgdir equ (OS_BASE+0x006F000)
 
SLOT_BASE equ (OS_BASE+0x0080000)
 
VGABasePtr equ (OS_BASE+0x00A0000)
 
CLEAN_ZONE equ (_CLEAN_ZONE-OS_BASE)
IDE_DMA equ (_IDE_DMA-OS_BASE)
 
; unused?
SB16Buffer equ (OS_BASE+0x02A0000)
SB16_Status equ (OS_BASE+0x02B0000)
 
UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000)
 
virtual at (OS_BASE+0x05FFF80)
258,8 → 295,10
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_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display)
BOOT_LAUNCHER_START equ 0x901D ;byte (0 or 1) start the first app (right now it's LAUNCHER) after kernel is loaded?
;BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled
BOOT_DEBUG_PRINT equ 0x901E ;byte If nonzero, duplicates debug output to the screen.
BOOT_DMA equ 0x901F ;
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no
277,6 → 316,7
BOOT_IDE_BAR2_16 equ 0x905A
BOOT_IDE_BAR3_16 equ 0x905C
BOOT_IDE_PI_16 equ 0x905E
BOOT_IDE_INTERR_16 equ 0x9060
 
TMP_FILE_NAME equ 0
TMP_CMD_LINE equ 1024
463,12 → 503,13
ends
 
struct PCIDEV
bk dd ?
fd dd ?
vendor_device_id dd ?
list LHEAD
vid_did dd ?
class dd ?
svid_sdid dd ?
devfn db ?
bus db ?
irq_line db ?
ends
 
; The following macro assume that we are on uniprocessor machine.
/kernel/branches/Kolibri-acpi/core/apic.inc
41,15 → 41,6
IOAPIC_ARB equ 0x2
IOAPIC_REDTBL equ 0x10
 
IPI_INIT equ (0x5 shl 8)
IPI_START equ (0x6 shl 8)
IPI_LEVEL_ASSERT equ (0x1 shl 14)
SHORTHAND_ALL_EXCL equ (0x3 shl 18)
 
CMD_IPI_INIT equ (IPI_INIT+SHORTHAND_ALL_EXCL)
 
 
 
align 4
APIC_init:
mov [irq_mode], IRQ_PIC
91,7 → 82,7
@@:
mov ebx, eax
call IOAPIC_read
mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical
mov ah, 0x08; Delivery Mode: Fixed, Destination Mode: Logical
mov al, cl
add al, 0x20; vector
or eax, 0x10000; Mask Interrupt
193,19 → 184,19
 
; LAPIC timer
; pre init
; mov dword[esi + APIC_timer_div], 1011b; 1
; mov dword[esi + APIC_timer_init], 0xffffffff; max val
; push esi
; mov esi, 640 ; wait 0.64 sec
; call delay_ms
; pop esi
; mov eax, [esi + APIC_timer_cur]; read current tick couner
; xor eax, 0xffffffff ; eax = 0xffffffff - eax
; shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec
mov dword[esi + APIC_timer_div], 1011b; 1
mov dword[esi + APIC_timer_init], 0xffffffff; max val
push esi
mov esi, 640 ; wait 0.64 sec
call delay_ms
pop esi
mov eax, [esi + APIC_timer_cur]; read current tick couner
xor eax, 0xffffffff ; eax = 0xffffffff - eax
shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec
 
; Start (every 0.01 sec)
; mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
; mov dword[esi + APIC_timer_init], eax
mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
mov dword[esi + APIC_timer_init], eax
 
.done:
ret
446,38 → 437,7
pop ebp
ret
 
if 0
align 4
start_ap:
;eax= cpu id
 
; xchg bx, bx
 
test eax, eax ;do not start self
jz .exit
 
cmp eax, [cpu_count]
jae .exit
 
mov eax, [smpt+eax*4]
shl eax, 24
 
mov [esi+APIC_ICRH], eax
mov [esi+APIC_ICRL], dword (IPI_INIT+IPI_LEVEL_ASSERT)
 
mov ecx, 10000
@@:
loop @B
 
CMD_IPI_START equ (IPI_START+IPI_LEVEL_ASSERT)+((0x10000+__ap_start_16) shr 12)
 
mov [esi+APIC_ICRH], eax
mov [esi+APIC_ICRL], dword CMD_IPI_START
.exit:
ret
 
end if
 
 
 
 
/kernel/branches/Kolibri-acpi/core/dll.inc
34,93 → 34,7
jmp .wait
endp
 
align 4
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 6
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop ebx
ret
endp
 
align 4
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 5
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop ebx
ret
endp
 
align 4
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 4
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop ebx
ret
endp
 
align 4
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 8
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop ebx
ret
endp
 
align 4
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 9
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop ebx
ret
endp
 
align 4
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 10
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop ebx
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
509,6 → 423,136
ret
endp
 
; description
; allocate user memory and loads the specified file
;
; param
; file_name= path to file
;
; retval
; eax= file image in user 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_umode 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 ?
 
km_file dd ?
um_file dd ?
endl
 
push esi
push edi
push ebx
 
 
lea eax, [attr]
stdcall get_fileinfo, [file_name], eax ;find file and get info
test eax, eax
jnz .err_1
 
mov eax, [file_size]
cmp eax, 1024*1024*16 ;to be enough for anybody (c)
ja .err_1
;it is very likely that the file is packed
stdcall kernel_alloc, [file_size] ;with kpack, so allocate memory from kernel heap
mov [km_file], eax
test eax, eax
jz .err_1
 
stdcall read_file, [file_name], eax, dword 0, [file_size]
cmp ebx, [file_size]
 
jne .err_2
 
mov eax, [km_file]
cmp dword [eax], 0x4B43504B ; check kpack signature
jne .raw_file
 
mov ebx, [eax+4] ;get real size of file
mov [file_size], ebx
stdcall user_alloc, ebx ;and allocate memory from user heap
mov [um_file], eax
test eax, eax
jz .err_2
 
pushad
mov ecx, unpack_mutex
call mutex_lock
 
stdcall unpack, [km_file], [um_file]
 
mov ecx, unpack_mutex
call mutex_unlock
popad
 
stdcall kernel_free, [km_file] ;we don't need packed file anymore
.exit:
mov eax, [um_file]
mov edx, [file_size]
 
pop ebx
pop edi
pop esi
ret
 
 
.raw_file: ; sometimes we load unpacked file
stdcall user_alloc, ebx ; allocate space from user heap
mov [um_file], eax
 
test eax, eax
jz .err_2
 
shr eax, 10 ; and remap pages.
 
mov ecx, [file_size]
add ecx, 4095
shr ecx, 12
 
mov esi, [km_file]
shr esi, 10
add esi, page_tabs
 
lea edi, [page_tabs+eax]
 
cld
@@:
lodsd
and eax, 0xFFFFF000
or eax, PG_USER
stosd
loop @B
 
stdcall free_kernel_space, [km_file] ; release allocated kernel space
jmp .exit ; physical pages still in use
 
.err_2:
stdcall kernel_free, [km_file]
.err_1:
xor eax, eax
xor edx, edx
 
pop ebx
pop edi
pop esi
ret
endp
 
 
uglobal
align 4
unpack_mutex MUTEX
515,37 → 559,31
endg
 
align 4
proc get_proc_ex stdcall, proc_name:dword, imports:dword
 
proc get_proc_ex stdcall uses ebx esi, proc_name:dword, imports:dword
mov ebx, [imports]
test ebx, ebx
jz .end
xor esi, esi
.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
mov eax, [ebx+32]
mov eax, [OS_BASE+eax+esi*4]
add eax, OS_BASE
stdcall strncmp, eax, [proc_name], 256
pop edx
test eax, eax
jz .ok
 
add edx, 8
jmp .next
.next_table:
add [imports], 4
jmp .look_up
.ok:
mov eax, [edx+4]
ret
inc esi
cmp esi, [ebx+24]
jb .look_up
.end:
xor eax, eax
ret
.ok:
mov eax, [ebx+28]
mov eax, [OS_BASE+eax+esi*4]
add eax, OS_BASE
ret
endp
 
align 4
713,8 → 751,6
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
 
803,13 → 839,10
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+COFF_HEADER.nSymbols], \
[strings], ebx
[strings], __exports
test eax, eax
jz .link_fail
 
911,8 → 944,6
img_base dd ?
endl
 
cli
 
; resolve file name
mov ebx, [file_name]
lea edi, [fullname+1]
923,6 → 954,8
 
; scan for required DLL in list of already loaded for this process,
; ignore timestamp
cli
 
mov esi, [CURRENT_TASK]
shl esi, 8
lea edi, [fullname]
946,6 → 979,7
mov eax, [ecx+DLLDESCR.exports]
sub eax, [ecx+DLLDESCR.defaultbase]
add eax, [esi+HDLL.base]
sti
ret
.next_in_process:
mov esi, [esi+HDLL.fd]
953,10 → 987,12
.not_in_process:
 
; scan in full list, compare timestamp
sti
lea eax, [fileinfo]
stdcall get_fileinfo, edi, eax
test eax, eax
jnz .fail
cli
mov esi, [dll_list.fd]
.scan_for_dlls:
cmp esi, dll_list
978,6 → 1014,7
 
; new DLL
.load_new:
sti
; load file
stdcall load_file, edi
test eax, eax
1005,13 → 1042,6
mov dword [esi+DLLDESCR.timestamp], eax
mov eax, dword [fileinfo+28]
mov dword [esi+DLLDESCR.timestamp+4], eax
; initialize DLLDESCR struct
and dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
mov [esi+DLLDESCR.fd], dll_list
mov eax, [dll_list.bk]
mov [dll_list.bk], esi
mov [esi+DLLDESCR.bk], eax
mov [eax+DLLDESCR.fd], esi
 
; calculate size of loaded DLL
mov edx, [coff]
1181,6 → 1211,14
 
stdcall kernel_free, [coff]
 
cli
; initialize DLLDESCR struct
and dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
mov [esi+DLLDESCR.fd], dll_list
mov eax, [dll_list.bk]
mov [dll_list.bk], esi
mov [esi+DLLDESCR.bk], eax
mov [eax+DLLDESCR.fd], esi
.dll_already_loaded:
inc [esi+DLLDESCR.refcount]
push esi
1253,6 → 1291,7
mov eax, [esi+DLLDESCR.exports]
sub eax, [esi+DLLDESCR.defaultbase]
add eax, [img_base]
sti
ret
.fail_and_free_data:
stdcall kernel_free, [esi+DLLDESCR.data]
1269,6 → 1308,7
.fail_and_dereference:
mov eax, 1 ; delete 1 reference
call dereference_dll
sti
xor eax, eax
ret
endp
/kernel/branches/Kolibri-acpi/core/exports.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7,204 → 7,117
 
$Revision$
 
 
iglobal
szKernel db 'KERNEL', 0
szVersion db 'version',0
endg
 
szRegService db 'RegService',0
szGetService db 'GetService',0
szServiceHandler db 'ServiceHandler',0
szAttachIntHandler db 'AttachIntHandler',0
; szGetIntHandler db 'GetIntHandler', 0
szFpuSave db 'FpuSave',0
szFpuRestore db 'FpuRestore',0
szReservePortArea db 'ReservePortArea',0
szBoot_Log db 'Boot_Log',0
 
szMutexInit db 'MutexInit',0
szMutexLock db 'MutexLock',0
szMutexUnlock db 'MutexUnlock',0
 
szPciApi db 'PciApi', 0
szPciRead32 db 'PciRead32', 0
szPciRead16 db 'PciRead16', 0
szPciRead8 db 'PciRead8', 0
szPciWrite8 db 'PciWrite8',0
szPciWrite16 db 'PciWrite16',0
szPciWrite32 db 'PciWrite32',0
 
szAllocPage db 'AllocPage',0
szAllocPages db 'AllocPages',0
szFreePage db 'FreePage',0
szGetPgAddr db 'GetPgAddr',0
szMapPage db 'MapPage',0
szMapSpace db 'MapSpace',0
szMapIoMem db 'MapIoMem',0
szCommitPages db 'CommitPages',0
szReleasePages db 'ReleasePages',0
 
szAllocKernelSpace db 'AllocKernelSpace',0
szFreeKernelSpace db 'FreeKernelSpace',0
szKernelAlloc db 'KernelAlloc',0
szKernelFree db 'KernelFree',0
szUserAlloc db 'UserAlloc',0
szUserFree db 'UserFree',0
szKmalloc db 'Kmalloc',0
szKfree db 'Kfree',0
szCreateRingBuffer db 'CreateRingBuffer',0
 
szGetPid db 'GetPid',0
szCreateObject db 'CreateObject',0
szDestroyObject db 'DestroyObject',0
szCreateEvent db 'CreateEvent',0
szRaiseEvent db 'RaiseEvent',0
szWaitEvent db 'WaitEvent',0
szDestroyEvent db 'DestroyEvent',0
szClearEvent db 'ClearEvent',0
 
szLoadCursor db 'LoadCursor',0
 
szSysMsgBoardStr db 'SysMsgBoardStr', 0
szSysMsgBoard db 'SysMsgBoard', 0
szGetCurrentTask db 'GetCurrentTask',0
szLFBAddress db 'LFBAddress',0
szLoadFile db 'LoadFile',0
szSendEvent db 'SendEvent',0
szSetMouseData db 'SetMouseData',0
szSetKeyboardData db 'SetKeyboardData',0
szRegKeyboard db 'RegKeyboard',0
szDelKeyboard db 'DelKeyboard',0
szSleep db 'Sleep',0
szGetTimerTicks db 'GetTimerTicks',0
 
szGetDisplay db 'GetDisplay',0
szSetScreen db 'SetScreen',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
 
szDiskAdd db 'DiskAdd',0
szDiskDel db 'DiskDel',0
szDiskMediaChanged db 'DiskMediaChanged',0
 
szTimerHS db 'TimerHS',0
szCancelTimerHS db 'CancelTimerHS',0
 
szRegUSBDriver db 'RegUSBDriver',0
szUSBOpenPipe db 'USBOpenPipe',0
szUSBClosePipe db 'USBClosePipe',0
szUSBNormalTransferAsync db 'USBNormalTransferAsync',0
szUSBControlTransferAsync db 'USBControlTransferAsync',0
 
szNetRegDev db 'NetRegDev',0
szNetUnRegDev db 'NetUnRegDev',0
szNetPtrToNum db 'NetPtrToNum',0
szNetLinkChanged db 'NetLinkChanged',0
szEth_input db 'Eth_input',0
 
align 16
kernel_export:
dd szRegService , reg_service
dd szGetService , get_service
dd szServiceHandler , srv_handler
dd szAttachIntHandler, attach_int_handler
; dd szGetIntHandler , get_int_handler
dd szFpuSave , fpu_save
dd szFpuRestore , fpu_restore
dd szReservePortArea , r_f_port_area
dd szBoot_Log , boot_log
 
dd szMutexInit , mutex_init ;gcc fastcall
dd szMutexLock , mutex_lock ;gcc fastcall
dd szMutexUnlock , mutex_unlock ;gcc fastcall
 
dd szPciApi , pci_api_drv
dd szPciRead32 , pci_read32
dd szPciRead16 , pci_read16
dd szPciRead8 , pci_read8
dd szPciWrite8 , pci_write8
dd szPciWrite16 , pci_write16
dd szPciWrite32 , pci_write32
 
dd szAllocPage , alloc_page ;stdcall
dd szAllocPages , alloc_pages ;stdcall
dd szFreePage , free_page
dd szMapPage , map_page ;stdcall
dd szMapSpace , map_space
dd szMapIoMem , map_io_mem ;stdcall
dd szGetPgAddr , get_pg_addr
dd szCommitPages , commit_pages ;not implemented
dd szReleasePages , release_pages
 
dd szAllocKernelSpace, alloc_kernel_space ;stdcall
dd szFreeKernelSpace , free_kernel_space ;stdcall
dd szKernelAlloc , kernel_alloc ;stdcall
dd szKernelFree , kernel_free ;stdcall
dd szUserAlloc , user_alloc ;stdcall
dd szUserFree , user_free ;stdcall
dd szKmalloc , malloc
dd szKfree , free
dd szCreateRingBuffer, create_ring_buffer ;stdcall
 
dd szGetPid , get_pid
dd szCreateObject , create_kernel_object
dd szDestroyObject , destroy_kernel_object
dd szCreateEvent , create_event ;see EVENT.inc for specification
dd szRaiseEvent , raise_event ;see EVENT.inc for specification
dd szWaitEvent , wait_event ;see EVENT.inc for specification
dd szDestroyEvent , destroy_event ;see EVENT.inc for specification
dd szClearEvent , clear_event ;see EVENT.inc for specification
 
dd szLoadCursor , load_cursor ;stdcall
 
dd szSysMsgBoardStr , sys_msg_board_str
dd szSysMsgBoard , sys_msg_board
dd szGetCurrentTask , get_curr_task
dd szLoadFile , load_file ;retval eax, ebx
dd szSendEvent , send_event ;see EVENT.inc for specification
dd szSetMouseData , set_mouse_data ;stdcall
dd szSetKeyboardData , set_keyboard_data
dd szRegKeyboard , register_keyboard
dd szDelKeyboard , delete_keyboard
dd szSleep , delay_ms
dd szGetTimerTicks , get_timer_ticks
 
dd szGetDisplay , get_display
dd szSetScreen , set_screen
 
dd szStrncat , strncat
dd szStrncpy , strncpy
dd szstrncmp , strncmp
dd szStrnlen , strnlen
dd szStrchr , strchr
dd szStrrchr , strrchr
 
dd szDiskAdd , disk_add
dd szDiskDel , disk_del
dd szDiskMediaChanged, disk_media_changed
 
dd szTimerHS , timer_hs
dd szCancelTimerHS , cancel_timer_hs
 
dd szRegUSBDriver , reg_usb_driver
dd szUSBOpenPipe , usb_open_pipe
dd szUSBClosePipe , usb_close_pipe
dd szUSBNormalTransferAsync, usb_normal_transfer_async
dd szUSBControlTransferAsync, usb_control_async
 
dd szNetRegDev , NET_add_device
dd szNetUnRegDev , NET_remove_device
dd szNetPtrToNum , NET_ptr_to_num
dd szNetLinkChanged , NET_link_changed
dd szEth_input , ETH_input
 
exp_lfb:
dd szLFBAddress , 0
dd 0 ;terminator, must be zero
 
endg
align 4
__exports:
export 'KERNEL', \
alloc_kernel_space, 'AllocKernelSpace', \ ; stdcall
alloc_page, 'AllocPage', \ ; gcc ABI
alloc_pages, 'AllocPages', \ ; stdcall
commit_pages, 'CommitPages', \ ; eax, ebx, ecx
\
disk_add, 'DiskAdd', \ ;stdcall
disk_del, 'DiskDel', \
disk_media_changed, 'DiskMediaChanged', \ ;stdcall
\
create_event, 'CreateEvent', \ ; ecx, esi
destroy_event, 'DestroyEvent', \ ;
raise_event, 'RaiseEvent', \ ; eax, ebx, edx, esi
wait_event, 'WaitEvent', \ ; eax, ebx
wait_event_timeout, 'WaitEventTimeout', \ ; eax, ebx, ecx
get_event_ex, 'GetEvent', \ ; edi
clear_event, 'ClearEvent', \ ;see EVENT.inc for specification
send_event, 'SendEvent', \ ;see EVENT.inc for specification
\
create_kernel_object, 'CreateObject', \
create_ring_buffer, 'CreateRingBuffer', \ ; stdcall
destroy_kernel_object, 'DestroyObject', \
free_kernel_space, 'FreeKernelSpace', \ ; stdcall
free_page, 'FreePage', \ ; eax
kernel_alloc, 'KernelAlloc', \ ; stdcall
kernel_free, 'KernelFree', \ ; stdcall
malloc, 'Kmalloc', \
free, 'Kfree', \
map_io_mem, 'MapIoMem', \ ; stdcall
map_page, 'MapPage', \ ; stdcall
get_pg_addr, 'GetPgAddr', \ ; eax
map_space, 'MapSpace', \
release_pages, 'ReleasePages', \
\
mutex_init, 'MutexInit', \ ; gcc fastcall
mutex_lock, 'MutexLock', \ ; gcc fastcall
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
\
get_display, 'GetDisplay', \
set_screen, 'SetScreen', \
window._.get_rect, 'GetWindowRect', \ ; gcc fastcall
pci_api_drv, 'PciApi', \
pci_read8, 'PciRead8', \ ; stdcall
pci_read16, 'PciRead16', \ ; stdcall
pci_read32, 'PciRead32', \ ; stdcall
pci_write8, 'PciWrite8', \ ; stdcall
pci_write16, 'PciWrite16', \ ; stdcall
pci_write32, 'PciWrite32', \ ; stdcall
\
get_pid, 'GetPid', \
get_service, 'GetService', \ ;
reg_service, 'RegService', \ ; stdcall
attach_int_handler, 'AttachIntHandler', \ ; stdcall
user_alloc, 'UserAlloc', \ ; stdcall
user_alloc_at, 'UserAllocAt', \ ; stdcall
user_free, 'UserFree', \ ; stdcall
unmap_pages, 'UnmapPages', \ ; eax, ecx
sys_msg_board_str, 'SysMsgBoardStr', \
sys_msg_board, 'SysMsgBoard', \
get_timer_ticks, 'GetTimerTicks', \
get_stack_base, 'GetStackBase', \
delay_hs, 'Delay', \ ; ebx
set_mouse_data, 'SetMouseData', \ ;
set_keyboard_data, 'SetKeyboardData', \ ; gcc fastcall
register_keyboard, 'RegKeyboard', \
delete_keyboard, 'DelKeyboard', \
get_cpu_freq, 'GetCpuFreq', \
\
srv_handler, 'ServiceHandler', \
fpu_save, 'FpuSave', \
fpu_restore, 'FpuRestore', \
r_f_port_area, 'ReservePortArea', \
boot_log, 'Boot_Log', \
\
load_cursor, 'LoadCursor', \ ;stdcall
\
get_curr_task, 'GetCurrentTask', \
load_file, 'LoadFile', \ ;retval eax, ebx
delay_ms, 'Sleep', \
\
strncat, 'strncat', \
strncpy, 'strncpy', \
strncmp, 'strncmp', \
strnlen, 'strnlen', \
strchr, 'strchr', \
strrchr, 'strrchr', \
\
timer_hs, 'TimerHS', \
cancel_timer_hs, 'CancelTimerHS', \
\
reg_usb_driver, 'RegUSBDriver', \
usb_open_pipe, 'USBOpenPipe', \
usb_close_pipe, 'USBClosePipe', \
usb_normal_transfer_async, 'USBNormalTransferAsync', \
usb_control_async, 'USBControlTransferAsync', \
usb_get_param, 'USBGetParam', \
\
NET_add_device, 'NetRegDev', \
NET_remove_device, 'NetUnRegDev', \
NET_ptr_to_num, 'NetPtrToNum', \
NET_link_changed, 'NetLinkChanged', \
ETH_input, 'Eth_input', \
\
0, 'LFBAddress' ; must be the last one
load kernel_exports_count dword from __exports + 24
load kernel_exports_addresses dword from __exports + 28
exp_lfb = OS_BASE + kernel_exports_addresses + (kernel_exports_count - 1) * 4 - 4
/kernel/branches/Kolibri-acpi/core/heap.inc
890,6 → 890,7
 
mov ebx, [offset]
and ebx, not 4095 ; is it required ?
add ebx, [base]
 
.unmap:
mov eax, [edx] ; get page addres
897,7 → 898,7
jz @F
test eax, PG_SHARED ; page shared ?
jnz @F
mov [page_tabs+edx*4], dword 2
mov [edx], dword 2
; mark page as reserved
invlpg [ebx] ; when we start using
call free_page ; empty c-o-w page instead this ?
/kernel/branches/Kolibri-acpi/core/irq.inc
51,6 → 51,8
.irqh dd ?
endl
 
DEBUGF 1, "K : Attach Interrupt %d Handler %x\n", [irq], [handler]
 
and [.irqh], 0
 
push ebx
154,25 → 156,6
cmp [v86_irqhooks+ebp*8], 0
jnz v86_irq
 
cmp bp, 6
jnz @f
push ebp
call [fdc_irq_func]
pop ebp
@@:
 
cmp bp, 14
jnz @f
push ebp
call [irq14_func]
pop ebp
@@:
cmp bp, 15
jnz @f
push ebp
call [irq15_func]
pop ebp
@@:
bts [irq_active_set], ebp
 
lea esi, [irqh_tab+ebp*8] ; esi= list head
217,14 → 200,6
; Note: this still isn't 100% correct, because two IRQs can fire simultaneously,
; the better way would be to find the correct IRQ, but I don't know how to do
; this in that case.
; Also, [fdc_irq_func], [irq14_func], [irq15_func] could process interrupt
; but do not return whether they did it, so just ignore IRQs 6, 14, 15.
cmp ebp, 6
jz .fail
cmp ebp, 14
jz .fail
cmp ebp, 15
jz .fail
push ebp
xor ebp, ebp
.try_other_irqs:
232,8 → 207,14
jz .try_next_irq
cmp ebp, 1
jz .try_next_irq
cmp ebp, 6
jz .try_next_irq
cmp ebp, 12
jz .try_next_irq
cmp ebp, 14
jz .try_next_irq
cmp ebp, 15
jz .try_next_irq
lea esi, [irqh_tab+ebp*8]
mov ebx, esi
.try_next_handler:
/kernel/branches/Kolibri-acpi/core/memory.inc
358,7 → 358,7
 
cmp dword [LFBAddress], -1
jne @f
mov [BOOT_VAR+BOOT_MTRR], byte 2
mov [BOOT_VARS+BOOT_MTRR], byte 2
; max VGA=640*480*4=1228800 bytes
; + 32*640*4=81920 bytes for mouse pointer
stdcall alloc_pages, ((1228800+81920)/4096)
378,7 → 378,7
@@:
test [SCR_MODE], word 0100000000000000b
jnz @f
mov [BOOT_VAR+BOOT_MTRR], byte 2
mov [BOOT_VARS+BOOT_MTRR], byte 2
ret
@@:
call init_mtrr
1199,7 → 1199,7
cmp ebx, 11
jb .fail
 
cmp ebx, 25
cmp ebx, 27
ja .fail
 
jmp dword [f68call+ebx*4-11*4]
1310,6 → 1310,15
mov [esp+32], eax
ret
 
.27:
cmp ecx, OS_BASE
jae .fail
 
stdcall load_file_umode, ecx
mov [esp+24], edx
mov [esp+32], eax
ret
 
.fail:
xor eax, eax
mov [esp+32], eax
1335,6 → 1344,7
dd f68.24 ; set exception handler
dd f68.25 ; unmask exception
dd f68.26 ; user_unmap
dd f68.27 ; load_file_umode
 
 
align 4
1361,7 → 1371,7
align 4
proc init_mtrr
 
cmp [BOOT_VAR+BOOT_MTRR], byte 2
cmp [BOOT_VARS+BOOT_MTRR], byte 2
je .exit
 
bt [cpu_caps], CAPS_MTRR
1456,7 → 1466,7
mov ebx, [size]
dec ebx
mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
mov edx, 0x00000000
sub eax, ebx
sbb edx, 0
or eax, 0x800
/kernel/branches/Kolibri-acpi/core/peload.inc
275,68 → 275,3
pop edi
pop ebp
ret 8
 
align 16
__exports:
export 'KERNEL', \
alloc_kernel_space, 'AllocKernelSpace', \ ; stdcall
alloc_page, 'AllocPage', \ ; gcc ABI
alloc_pages, 'AllocPages', \ ; stdcall
commit_pages, 'CommitPages', \ ; eax, ebx, ecx
\
disk_add, 'DiskAdd', \ ;stdcall
disk_media_changed, 'DiskMediaChanged', \ ;stdcall
\
create_event, 'CreateEvent', \ ; ecx, esi
destroy_event, 'DestroyEvent', \ ;
raise_event, 'RaiseEvent', \ ; eax, ebx, edx, esi
wait_event, 'WaitEvent', \ ; eax, ebx
wait_event_timeout, 'WaitEventTimeout', \ ; eax, ebx, ecx
get_event_ex, 'GetEvent', \ ; edi
\
create_kernel_object, 'CreateObject', \
create_ring_buffer, 'CreateRingBuffer', \ ; stdcall
destroy_kernel_object, 'DestroyObject', \
free_kernel_space, 'FreeKernelSpace', \ ; stdcall
free_page, 'FreePage', \ ; eax
kernel_alloc, 'KernelAlloc', \ ; stdcall
kernel_free, 'KernelFree', \ ; stdcall
malloc, 'Kmalloc', \
free, 'Kfree', \
map_io_mem, 'MapIoMem', \ ; stdcall
map_page, 'MapPage', \ ; stdcall
get_pg_addr, 'GetPgAddr', \ ; eax
\
mutex_init, 'MutexInit', \ ; gcc fastcall
mutex_lock, 'MutexLock', \ ; gcc fastcall
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
\
get_display, 'GetDisplay', \
set_screen, 'SetScreen', \
window._.get_rect, 'GetWindowRect', \ ; gcc fastcall
pci_api_drv, 'PciApi', \
pci_read8, 'PciRead8', \ ; stdcall
pci_read16, 'PciRead16', \ ; stdcall
pci_read32, 'PciRead32', \ ; stdcall
pci_write8, 'PciWrite8', \ ; stdcall
pci_write16, 'PciWrite16', \ ; stdcall
pci_write32, 'PciWrite32', \ ; stdcall
\
get_pid, 'GetPid', \
get_service, 'GetService', \ ;
reg_service, 'RegService', \ ; stdcall
attach_int_handler, 'AttachIntHandler', \ ; stdcall
user_alloc, 'UserAlloc', \ ; stdcall
user_free, 'UserFree', \ ; stdcall
unmap_pages, 'UnmapPages', \ ; eax, ecx
sys_msg_board_str, 'SysMsgBoardStr', \
get_timer_ticks, 'GetTimerTicks', \
get_stack_base, 'GetStackBase', \
delay_hs, 'Delay', \ ; ebx
set_mouse_data, 'SetMouseData', \ ;
set_keyboard_data, 'SetKeyboardData', \ ; gcc fastcall
timer_hs, 'TimerHs', \ ; stdcall
get_cpu_freq, 'GetCpuFreq'
 
 
 
/kernel/branches/Kolibri-acpi/core/sys32.inc
578,11 → 578,6
push esi ; remove hd1 & cd & flp reservation
shl esi, 5
mov esi, [esi+CURRENT_TASK+TASKDATA.pid]
cmp [hd1_status], esi
jnz @f
call free_hd_channel
and [hd1_status], 0
@@:
cmp [cd_status], esi
jnz @f
call free_cd_channel
/kernel/branches/Kolibri-acpi/core/syscall.inc
182,8 → 182,8
dd sys_apm ; 49-Advanced Power Management (APM)
dd syscall_set_window_shape ; 50-Window shape & scale
dd syscall_threads ; 51-Threads
dd undefined_syscall ; 52-Stack driver status
dd undefined_syscall ; 53-Socket interface
dd undefined_syscall ; 52- deprecated Stack driver status
dd undefined_syscall ; 53- deprecated Socket interface
dd undefined_syscall ; 54-reserved
dd sound_interface ; 55-Sound interface
dd undefined_syscall ; 56-reserved
/kernel/branches/Kolibri-acpi/core/taskman.inc
63,6 → 63,9
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
 
locals
cmdline_size dd ? ; +0 ; cmdline -12
cmdline_adr dd ? ; +4 ; cmdline -8
cmdline_flag dd ? ; +8 ; cmdline -4
cmdline rd 64 ;256/4
filename rd 256 ;1024/4
flags dd ?
127,15 → 130,73
jmp .final
 
.namecopied:
xor eax, eax
mov [cmdline_flag], eax
mov [cmdline_adr], eax
mov [cmdline_size], eax
 
mov [cmdline], ebx
test ebx, ebx
jz @F
jz .no_copy
;--------------------------------------
pushad
pushfd
mov esi, ebx
mov ecx, 65536 ; 64 Kb max for ext.cmdline
cld
@@:
dec ecx
jz .end_string
 
lodsb
test al, al
jnz @b
 
.end_string:
mov eax, 65536 ; 64 Kb max for ext.cmdline
sub eax, ecx
mov [cmdline_size], eax
cmp eax, 255
ja @f
 
popfd
popad
jmp .old_copy
 
@@:
xor eax, eax
dec eax
mov [cmdline_flag], eax
popfd
popad
; get memory for the extended command line
stdcall kernel_alloc, [cmdline_size] ;eax
test eax, eax
jz .old_copy ; get memory failed
 
mov [cmdline_adr], eax
 
pushad
pushfd
mov esi, ebx
mov edi, eax
mov ecx, [cmdline_size]
cld
rep movsb
popfd
popad
jmp .no_copy
 
.old_copy:
; clear flag because old method with 256 bytes
xor eax, eax
mov [cmdline_flag], eax
;--------------------------------------
lea eax, [cmdline]
mov dword [eax+252], 0
.copy:
stdcall strncpy, eax, ebx, 255
@@:
.no_copy:
lea eax, [filename]
stdcall load_file, eax
 
1055,10 → 1116,34
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
 
mov eax, [cmd_line]
 
cmp [edx], dword 0xffffffff ; extended destination tag
jne .no_ext_dest
 
mov edx, [edx+4] ; extended destination for cmdline
jmp .continue
 
.no_ext_dest:
mov [eax-12], dword 255
.continue:
mov byte [edx], 0 ;force empty string if no cmdline given
mov eax, [cmd_line]
 
test eax, eax
jz @f
;--------------------------------------
cmp [eax-4], dword 0xffffffff ; cmdline_flag
jne .old_copy
 
push eax
stdcall strncpy, edx, [eax-8], [eax-12]
pop eax
 
stdcall kernel_free, [eax-8]
jmp @f
 
.old_copy:
;--------------------------------------
stdcall strncpy, edx, eax, 256
@@:
mov edx, [params]
/kernel/branches/Kolibri-acpi/core/timers.inc
5,7 → 5,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2381 $
$Revision: 3598 $
 
; Simple implementation of timers. All timers are organized in a double-linked
; list, and the OS loop after every timer tick processes the list.
/kernel/branches/Kolibri-acpi/data32.inc
54,8 → 54,10
boot_v86machine: cp866 'Инициализация системы V86 машины',0
boot_inittimer: cp866 'Инициализация системного таймера (IRQ0)',0
boot_initapic: cp866 'Попытка инициализации APIC',0
boot_enableirq: cp866 'Включить прерывания 2, 6, 13, 14, 15',0
boot_enablint_ide:cp866 'Разрешение прерываний в контроллере IDE',0
boot_enableirq: cp866 'Включить прерывания 2, 13',0
boot_disabling_ide:cp866 'Запрещение прерываний в контроллере IDE',0
boot_enabling_ide:cp866 'Разрешение прерываний в контроллере IDE',0
boot_set_int_IDE: cp866 'Установка обработчиков прерываний IDE',0
boot_detectfloppy:cp866 'Поиск floppy дисководов',0
boot_detecthdcd: cp866 'Поиск жестких дисков и ATAPI приводов',0
boot_getcache: cp866 'Получение памяти для кэша',0
95,8 → 97,10
boot_v86machine db 'Initialize system V86 machine',0
boot_inittimer db 'Initialize system timer (IRQ0)',0
boot_initapic db 'Try to initialize APIC',0
boot_enableirq db 'Enable interrupts 2, 6, 13, 14, 15',0
boot_enablint_ide db 'Enable interrupts in IDE controller',0
boot_enableirq db 'Enable interrupts 2, 13',0
boot_disabling_ide db 'Disable interrupts in IDE controller',0
boot_enabling_ide db 'Enable interrupts in IDE controller',0
boot_set_int_IDE db 'Set handler of interrupts for IDE',0
boot_detectfloppy db 'Search floppy drives',0
boot_detecthdcd db 'Search hard drives and ATAPI drives',0
boot_getcache db 'Get memory for cache',0
164,8 → 168,6
ud_user_message db 'Error: unsupported processor instruction',0
end if
 
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db '/sys/drivers/VMODE.MDR',0
;vrr_m db 'VRR_M',0
kernel_file db 'KERNEL MNT'
335,8 → 337,6
mem_used_list rd 64*2
mem_hash_cnt rd 64
 
MEM_AMOUNT rd 1
 
cpu_freq rq 1
 
heap_mutex MUTEX
384,6 → 384,7
 
REDRAW_BACKGROUND rb 4
 
align 4
draw_data: rb 16*256
BPSLine_calc_area rd 1440
d_width_calc_area rd 1140
404,6 → 405,7
 
BTN_DOWN: rb 4
 
align 4
def_cursor rd 1
def_cursor_clock rd 1
current_cursor rd 1
435,17 → 437,6
 
current_slot rd 1
 
BTN_ADDR rd 1
BTN_COUNT rb 4
BTN_BUFF rd 255
 
KEY_COUNT rb 4
KEY_BUFF rb 128
 
 
SYS_SHUTDOWN rb 4
 
 
; status
hd1_status rd 1 ; 0 - free : other - pid
application_table_owner rd 1 ; 0 - free : other - pid
548,17 → 539,21
cache_ide3_appl_search_start rd 1
 
debug_step_pointer rd 1
 
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled
 
hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache
cd_appl_data rb 1 ; 0 = system cache, 1 - application cache
 
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled
timer_ticks_enable rb 1 ; for cd driver
 
align 4
NumBiosDisks rd 1
BiosDisksData rb 200h
BiosDiskCaches rb 80h*(cache_ide1-cache_ide0)
BiosDiskPartitions rd 80h
 
align 16
DRIVE_DATA: rb DRIVE_DATA_SIZE
 
583,22 → 578,6
BgrAuxTable rb 32768
BUTTON_INFO rb 64*1024
RESERVED_PORTS: rb 64*1024
BOOT_VAR: rb 64*1024
FLOPPY_BUFF: rb 18*512 ;one track
 
sys_pgmap: rb 1024*1024/8
 
align 4096
 
SLOT_BASE: rb 64*1024
FLOPPY_BUFF: rb 16*1024
 
 
window_data: rb 8192
CURRENT_TASK: rb 8192
WIN_STACK: rb 0x400
WIN_POS: rb 0x800
 
CDDataBuf: rb 4096
 
idts rq 0x41
 
 
/kernel/branches/Kolibri-acpi/data32sp.inc
3,8 → 3,10
boot_v86machine: cp850 'Inicializar sistema V86',0
boot_inittimer: cp850 'Inicializar reloj del sistema (IRQ0)',0
boot_initapic: cp850 'Prueba inicializar APIC',0
boot_enableirq: cp850 'Habilitar interrupciones 2, 6, 13, 14, 15',0
boot_enablint_ide:cp850 'Habiliar interrupciones en controladores IDE',0
boot_enableirq: cp850 'Habilitar interrupciones 2, 13',0
boot_disabling_ide:cp850 'Habiliar interrupciones en controladores IDE',0
boot_enabling_ide:cp850 'Habilitar interrupciones en controladores IDE',0
boot_set_int_IDE: cp850 'Configuración del controlador de interrupciones para el IDE',0
boot_detectfloppy:cp850 'Buscar unidades de disquete',0
boot_detecthdcd: cp850 'Buscar discos duros y unidades ATAPI',0
boot_getcache: cp850 'Tomar memoria para caché',0
/kernel/branches/Kolibri-acpi/detect/dev_fd.inc
30,8 → 30,8
mov [DRIVE_DATA], al
test al, al
jz @f
in al, 0x21
and al, 10111111b ; Enable IRQ6
out 0x21, al
 
stdcall attach_int_handler, 6, FDCInterrupt, 0
DEBUGF 1, "K : Set IDE IRQ6 return code %x\n", eax
@@:
 
/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc
17,6 → 17,9
;****************************************************
;* ПОИСК HDD и CD *
;****************************************************
cmp [IDEContrProgrammingInterface], 0
je EndFindHDD
 
FindHDD:
mov [ChannelNumber], 1
mov [DiskNumber], 0
79,6 → 82,14
popfd
popad
DEBUGF 1, "K : Dev: %s \n", dev_name
 
xor eax, eax
mov ax, [Sector512+64*2]
DEBUGF 1, "K : PIO mode %x\n", eax
mov ax, [Sector512+63*2]
DEBUGF 1, "K : Multiword DMA mode %x\n", eax
mov ax, [Sector512+88*2]
DEBUGF 1, "K : Ultra DMA mode %x\n", eax
FindHDD_2_2:
ret
 
/kernel/branches/Kolibri-acpi/detect/getcache.inc
37,64 → 37,26
mov [hdd_appl_data], 1;al
mov [cd_appl_data], 1
mov ch, [DRIVE_DATA+1]
mov cl, ch
and cl, 11b
test byte [DRIVE_DATA+1], 2
je .ide2
mov esi, cache_ide3
call get_cache_ide
.ide2:
mov cl, ch
shr cl, 2
and cl, 11b
test byte [DRIVE_DATA+1], 8
je .ide1
mov esi, cache_ide2
call get_cache_ide
.ide1:
mov cl, ch
shr cl, 4
and cl, 11b
test byte [DRIVE_DATA+1], 0x20
je .ide0
mov esi, cache_ide1
call get_cache_ide
.ide0:
mov cl, ch
shr cl, 6
and cl, 11b
test byte [DRIVE_DATA+1], 0x80
je @f
mov esi, cache_ide0
call get_cache_ide
@@:
xor ecx, ecx
cmp [NumBiosDisks], ecx
jz .endbd
mov esi, BiosDiskCaches
.loopbd:
push ecx
movsx ecx, byte [BiosDisksData+ecx*4+2]
inc ecx
jz .getbd
add ecx, ecx
movzx eax, byte [DRIVE_DATA+1]
shl eax, cl
and ah, 3
cmp ah, 1
jz .contbd
pop ecx
mov byte [BiosDisksData+ecx*4+2], -1
push ecx
.getbd:
mov eax, [cache_ide0_size]
mov [esi+cache_ide0_size-cache_ide0], eax
mov cl, 1
call get_cache_ide
.contbd:
pop ecx
add esi, cache_ide1-cache_ide0
inc ecx
cmp ecx, [NumBiosDisks]
jb .loopbd
.endbd:
jmp end_get_cache
 
get_cache_ide:
114,33 → 76,6
add ebx, edx
mov [esi+cache_ide0_data_pointer-cache_ide0], ebx
 
cmp cl, 10b
je .cd
push ecx
mov eax, [esi+cache_ide0_system_data_size-cache_ide0]
call calculate_for_hd
add eax, [esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0], eax
mov [esi+cache_ide0_system_sad_size-cache_ide0], ecx
 
push edi
mov edi, [esi+cache_ide0_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
mov eax, [esi+cache_ide0_appl_data_size-cache_ide0]
call calculate_for_hd
add eax, [esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0], eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0], ecx
 
push edi
mov edi, [esi+cache_ide0_data_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
pop ecx
ret
.cd:
push ecx
mov eax, [esi+cache_ide0_system_data_size-cache_ide0]
168,20 → 103,6
pop ecx
ret
 
calculate_for_hd:
push eax
mov ebx, eax
shr eax, 9
shl eax, 3
sub ebx, eax
shr ebx, 9
mov ecx, ebx
shl ebx, 9
pop eax
sub eax, ebx
dec ecx
ret
 
calculate_for_cd:
push eax
mov ebx, eax
/kernel/branches/Kolibri-acpi/detect/sear_par.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7,159 → 7,133
 
$Revision$
 
 
;****************************************************
; поиск логических дисков на обнаруженных HDD
; и занесение данных в область таблицы
; автор Mario79
;****************************************************
mov [transfer_adress], DRIVE_DATA+0xa
search_partitions_ide0:
search_partitions:
; 1. Fill missing parameters in HD_DATA structures.
mov eax, [hd_address_table]
mov [hd0_data.hdbase], eax ;0x1f0
mov [hd1_data.hdbase], eax
mov eax, [hd_address_table+16]
mov [hd2_data.hdbase], eax
mov [hd3_data.hdbase], eax
; 2. Notify the system about /hd* disks.
; For every existing disk, call ide_disk_add with correct parameters.
; Generate name "hdN" on the stack; this is 4 bytes including terminating zero.
; 2a. /hd0: exists if mask 0x40 in [DRIVE_DATA+1] is set,
; data: hd0_data,
; number of partitions: [DRIVE_DATA+2]
test [DRIVE_DATA+1], byte 0x40
jz search_partitions_ide1
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x0
mov [hdpos], 1
mov [known_part], 1
search_partitions_ide0_1:
call set_PARTITION_variables
test [problem_partition], 2
jnz search_partitions_ide1 ; not found part
test [problem_partition], 1
jnz @F ; not found known_part
;cmp [problem_partition],0
;jne search_partitions_ide1
inc byte [DRIVE_DATA+2]
call partition_data_transfer
add [transfer_adress], 100
jz @f
push 'hd0'
mov eax, esp ; name
mov edx, hd0_data
call ide_disk_add
mov [DRIVE_DATA+2], al
pop ecx ; restore the stack
@@:
inc [known_part]
jmp search_partitions_ide0_1
 
search_partitions_ide1:
; 2b. /hd1: exists if mask 0x10 in [DRIVE_DATA+1] is set,
; data: hd1_data,
; number of partitions: [DRIVE_DATA+3]
test [DRIVE_DATA+1], byte 0x10
jz search_partitions_ide2
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x10
mov [hdpos], 2
mov [known_part], 1
search_partitions_ide1_1:
call set_PARTITION_variables
test [problem_partition], 2
jnz search_partitions_ide2
test [problem_partition], 1
jnz @F
;cmp [problem_partition],0
;jne search_partitions_ide2
inc byte [DRIVE_DATA+3]
call partition_data_transfer
add [transfer_adress], 100
jz @f
push 'hd1'
mov eax, esp
mov edx, hd1_data
call ide_disk_add
mov [DRIVE_DATA+3], al
pop ecx
@@:
inc [known_part]
jmp search_partitions_ide1_1
 
search_partitions_ide2:
test [DRIVE_DATA+1], byte 0x4
jz search_partitions_ide3
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x0
mov [hdpos], 3
mov [known_part], 1
search_partitions_ide2_1:
call set_PARTITION_variables
test [problem_partition], 2
jnz search_partitions_ide3
test [problem_partition], 1
jnz @F
;cmp [problem_partition],0
;jne search_partitions_ide3
inc byte [DRIVE_DATA+4]
call partition_data_transfer
add [transfer_adress], 100
; 2c. /hd2: exists if mask 4 in [DRIVE_DATA+1] is set,
; data: hd2_data,
; number of partitions: [DRIVE_DATA+4]
test [DRIVE_DATA+1], byte 4
jz @f
push 'hd2'
mov eax, esp
mov edx, hd2_data
call ide_disk_add
mov [DRIVE_DATA+4], al
pop ecx
@@:
inc [known_part]
jmp search_partitions_ide2_1
 
search_partitions_ide3:
test [DRIVE_DATA+1], byte 0x1
jz end_search_partitions_ide
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10
mov [hdpos], 4
mov [known_part], 1
search_partitions_ide3_1:
call set_PARTITION_variables
test [problem_partition], 2
jnz end_search_partitions_ide
test [problem_partition], 1
jnz @F
;cmp [problem_partition],0
;jne end_search_partitions_ide
inc byte [DRIVE_DATA+5]
call partition_data_transfer
add [transfer_adress], 100
; 2d. /hd3: exists if mask 1 in [DRIVE_DATA+1] is set,
; data: hd3_data,
; number of partitions: [DRIVE_DATA+5]
test [DRIVE_DATA+1], byte 1
jz @f
push 'hd3'
mov eax, esp
mov edx, hd3_data
call ide_disk_add
mov [DRIVE_DATA+5], al
pop ecx
@@:
inc [known_part]
jmp search_partitions_ide3_1
 
end_search_partitions_ide:
mov [hdpos], 80h
mov ecx, [NumBiosDisks]
test ecx, ecx
jz end_search_partitions
start_search_partitions_bd:
push ecx
mov eax, [hdpos]
and [BiosDiskPartitions+(eax-80h)*4], 0
mov [known_part], 1
search_partitions_bd:
call set_PARTITION_variables
test [problem_partition], 2
jnz end_search_partitions_bd
test [problem_partition], 1
jnz @F
;cmp [problem_partition], 0
;jne end_search_partitions_bd
mov eax, [hdpos]
inc [BiosDiskPartitions+(eax-80h)*4]
call partition_data_transfer
add [transfer_adress], 100
; 3. Notify the system about /bd* disks.
; 3a. Check whether there are BIOS disks. If no, skip step 3.
xor esi, esi
cmp esi, [NumBiosDisks]
jz .nobd
; Loop over all disks.
push 0
push 'bd'
.bdloop:
; 3b. Get the drive number for using in /bd* name.
movzx eax, byte [BiosDisksData+esi*4]
sub al, 80h
; 3c. Convert eax to decimal and store starting with [esp+3].
; First 2 bytes in [esp] are "bd".
lea edi, [esp+2]
; store digits in the stack, ending with -'0'
push -'0'
@@:
inc [known_part]
jmp search_partitions_bd
end_search_partitions_bd:
pop ecx
inc [hdpos]
loop start_search_partitions_bd
xor edx, edx
iglobal
align 4
_10 dd 10
endg
div [_10]
push edx
test eax, eax
jnz @b
; restore digits from the stack, this reverses the order;
; add '0', stop, when zero is reached
@@:
pop eax
add al, '0'
stosb
jnz @b
; 3e. Call the API with userdata = 80h + ecx.
mov eax, esp
lea edx, [esi+80h]
stdcall disk_add, bd_callbacks, eax, edx, 0
test eax, eax
jz @f
stdcall disk_media_changed, eax, 1
@@:
; 3f. Continue the loop.
inc esi
cmp esi, [NumBiosDisks]
jnz .bdloop
pop ecx ecx ; restore stack after name
.nobd:
jmp end_search_partitions
 
problem_partition db 0 ; used for partitions search
 
include '../fs/part_set.inc'
 
partition_data_transfer:
mov edi, [transfer_adress]
mov esi, PARTITION_START ;start of file_system_data
mov ecx, (file_system_data_size+3)/4
rep movsd
; Helper procedure for search_partitions, adds one IDE disk.
; For compatibility, number of partitions for IDE disks is kept in a separate variable,
; so the procedure returns number of partitions.
; eax -> name, edx -> disk data
proc ide_disk_add
stdcall disk_add, ide_callbacks, eax, edx, 0
test eax, eax
jz @f
push eax
stdcall disk_media_changed, eax, 1
pop eax
mov eax, [eax+DISK.NumPartitions]
cmp eax, 255
jbe @f
mov eax, 255
@@:
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
endp
 
end_search_partitions:
 
/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt
2420,391 → 2420,6
* иначе eax = TID - идентификатор потока
 
======================================================================
= Функция 52, подфункция 0 - получить конфигурацию сетевого драйвера.
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 0 - номер подфункции
Возвращаемое значение:
* eax = двойное слово конфигурации
Замечания:
* Слово конфигурации можно установить подфункцией 2.
* Ядро не использует соответствующую переменную.
Ценность этой переменной и работающих с ней подфункций 0 и 2
представляется сомнительной.
 
======================================================================
======= Функция 52, подфункция 1 - получить локальный IP-адрес. ======
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 1 - номер подфункции
Возвращаемое значение:
* eax = IP-адрес (4 байта)
Замечания:
* Локальный IP-адрес устанавливается подфункцией 3.
 
======================================================================
Функция 52, подфункция 2 - установить конфигурацию сетевого драйвера.
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 2 - номер подфункции
* ecx = двойное слово конфигурации; если младшие 7 бит образуют
число 3, это воспринимается как запрос на [пере-]инициализацию
Ethernet-карты, в противном случае Ethernet выключается
Возвращаемое значение:
* если не запрошен Ethernet-интерфейс, то возвращается eax=2,
но это может измениться в будущих версиях ядра
* если запрошен Ethernet-интерфейс, то eax=0 означает ошибку
(отсутствие Ethernet-карты), а ненулевое значение - успех
Замечания:
* Слово конфигурации можно прочитать подфункцией 0.
* Ядро не использует соответствующую переменную.
Ценность этой переменной, подфункции 0 и части подфункции 2,
устанавливающей эту переменную, представляется сомнительной.
 
======================================================================
====== Функция 52, подфункция 3 - установить локальный IP-адрес. =====
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 3 - номер подфункции
* ecx = IP-адрес (4 байта)
Возвращаемое значение:
* текущая реализация возвращает eax=3, но это может быть изменено
в будущих версиях
Замечания:
* Локальный IP-адрес можно получить подфункцией 1.
 
======================================================================
= Функция 52, подфункция 6 - добавить данные в стек входной очереди. =
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 6 - номер подфункции
* edx = размер данных
* esi = указатель на данные
Возвращаемое значение:
* eax = -1 - ошибка
* eax = 0 - успешно
Замечания:
* Эта функция предназначена только для медленных сетевых драйверов
(PPP, SLIP).
* Размер данных не должен превосходить 1500 байт,
хотя проверок корректности не делается.
 
======================================================================
====================== Функция 52, подфункция 8 ======================
============= Прочитать данные из сетевой очереди вывода. ============
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 8 - номер подфункции
* esi = указатель на буфер размером 1500 байт
Возвращаемое значение:
* eax = число прочитанных байт (в текущей реализации
либо 0 = нет данных, либо 1500)
* данные скопированы в буфер
Замечания:
* Эта функция предназначена только для медленных сетевых драйверов
(PPP, SLIP).
 
======================================================================
=========== Функция 52, подфункция 9 - получить gateway IP. ==========
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 9 - номер подфункции
Возвращаемое значение:
* eax = gateway IP (4 байта)
 
======================================================================
========= Функция 52, подфункция 10 - получить маску подсети. ========
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 10 - номер подфункции
Возвращаемое значение:
* eax = маска подсети
 
======================================================================
========= Функция 52, подфункция 11 - установить gateway IP. =========
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 11 - номер подфункции
* ecx = gateway IP (4 байта)
Возвращаемое значение:
* текущая реализация возвращает eax=11, но это может быть изменено
в будущих реализациях
 
======================================================================
======== Функция 52, подфункция 12 - установить маску подсети. =======
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 12 - номер подфункции
* ecx = маска подсети
Возвращаемое значение:
* текущая реализация возвращает eax=12, но это может быть изменено
в будущих версиях
 
======================================================================
============ Функция 52, подфункция 13 - получить DNS IP. ============
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 13 - номер подфункции
Возвращаемое значение:
* eax = DNS IP (4 байта)
 
======================================================================
=========== Функция 52, подфункция 14 - установить DNS IP. ===========
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 14 - номер подфункции
* ecx = DNS IP (4 байта)
Возвращаемое значение:
* текущая реализация возвращает eax=14, но это может быть изменено
в следующих версиях
 
======================================================================
====== Функция 52, подфункция 15 - получить локальный MAC-адрес. =====
======================================================================
Параметры:
* eax = 52 - номер функции
* ebx = 15 - номер подфункции
* ecx = 0 - читать первые 4 байта,
ecx = 4 - читать последние 2 байта
Возвращаемое значение:
* для ecx=0: eax = первые 4 байта MAC-адреса
* для ecx=4: ax = последние 2 байта MAC-адреса,
старшая половина eax разрушается
* для других ecx: eax = -1 как признак ошибки
 
======================================================================
============ Функция 53, подфункция 0 - открыть UDP-сокет. ===========
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 0 - номер подфункции
* ecx = локальный порт (учитывается только младшее слово),
ecx = 0 - предоставить системе выбор локального порта
* edx = удалённый порт (учитывается только младшее слово)
* esi = удалённый IP
Возвращаемое значение:
* eax = -1 = 0xFFFFFFFF - ошибка; ebx разрушается
* eax = хэндл сокета (некоторое число, однозначно идентифицирующее
сокет и имеющее смысл только для системы) - успешно;
ebx разрушается
 
======================================================================
============ Функция 53, подфункция 1 - закрыть UDP-сокет. ===========
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 1 - номер подфункции
* ecx = хэндл сокета
Возвращаемое значение:
* eax = -1 - неверный хэндл
* eax = 0 - успешно
* ebx разрушается
Замечания:
* Текущая реализация не закрывает автоматически все сокеты потока
при его завершении. В частности, не следует прибивать поток
с кучей открытых сокетов - будет утечка ресурсов.
 
======================================================================
============== Функция 53, подфункция 2 - опрос сокета. ==============
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 2 - номер подфункции
* ecx = хэндл сокета
Возвращаемое значение:
* eax = число полученных байт, 0 для неверного хэндла
* ebx разрушается
 
======================================================================
======== Функция 53, подфункция 3 - прочитать байт из сокета. ========
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 3 - номер подфункции
* ecx = хэндл сокета
Возвращаемое значение:
* если нет принятых данных или указан неверный хэндл:
eax=0, bl=0, прочие байты ebx разрушаются
* если были принятые данные: eax=число оставшихся байт
(возможно, 0), bl=прочитанный байт, прочие байты ebx разрушаются
 
======================================================================
========== Функция 53, подфункция 4 - записать в UDP-сокет. ==========
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 4 - номер подфункции
* ecx = хэндл сокета
* edx = число байт для записи
* esi = указатель на данные для записи
Возвращаемое значение:
* eax = 0xffffffff - ошибка (неверный хэндл или недостаточно памяти)
* eax = 0 - успешно
* ebx разрушается
Замечания:
* Число байт для записи не может превышать 1500-28, хотя
соответствующей проверки не делается.
 
======================================================================
============ Функция 53, подфункция 5 - открыть TCP-сокет. ===========
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 5 - номер подфункции
* ecx = локальный порт (учитывается только младшее слово),
ecx = 0 - предоставить системе выбор локального порта
* edx = удалённый порт (учитывается только младшее слово)
* esi = удалённый IP
* edi = режим открытия: SOCKET_PASSIVE=0 или SOCKET_ACTIVE=1
Возвращаемое значение:
* eax = -1 = 0xFFFFFFFF - ошибка; ebx разрушается
* eax = хэндл сокета (некоторое число, однозначно идентифицирующее
сокет и имеющее смысл только для системы) - успешно;
ebx разрушается
 
======================================================================
====== Функция 53, подфункция 6 - получить состояние TCP-сокета. =====
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 6 - номер подфункции
* ecx = хэндл сокета
Возвращаемое значение:
* eax = 0 для неверного сокета или статус: одно из
* TCB_LISTEN = 1
* TCB_SYN_SENT = 2
* TCB_SYN_RECEIVED = 3
* TCB_ESTABLISHED = 4
* TCB_FIN_WAIT_1 = 5
* TCB_FIN_WAIT_2 = 6
* TCB_CLOSE_WAIT = 7
* TCB_CLOSING = 8
* TCB_LAST_ASK = 9
* TCB_TIME_WAIT = 10
* TCB_CLOSED = 11
* ebx разрушается
 
======================================================================
========== Функция 53, подфункция 7 - записать в TCP-сокет. ==========
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 7 - номер подфункции
* ecx = хэндл сокета
* edx = число байт для записи
* esi = указатель на данные для записи
Возвращаемое значение:
* eax = 0xffffffff - ошибка (неверный хэндл или недостаточно памяти)
* eax = 0 - успешно
* ebx разрушается
Замечания:
* Число байт для записи не может превышать 1500-40,
хотя соответствующей проверки не делается.
 
======================================================================
============ Функция 53, подфункция 8 - закрыть TCP-сокет. ===========
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 8 - номер подфункции
* ecx = хэндл сокета
Возвращаемое значение:
* eax = -1 - ошибка (неверный хэндл или
недостаточно памяти для пакета закрытия сокета)
* eax = 0 - успешно
* ebx разрушается
Замечания:
* Текущая реализация не закрывает автоматически все сокеты потока
при его завершении. В частности, не следует прибивать поток
с кучей открытых сокетов - будет утечка ресурсов.
 
======================================================================
== Функция 53, подфункция 9 - проверить, свободен ли локальный порт. =
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 9 - номер подфункции
* ecx = номер локального порта (используются только младшие 16 бит)
Возвращаемое значение:
* eax = 0 - порт используется
* eax = 1 - порт свободен
* ebx разрушается
 
======================================================================
==== Функция 53, подфункция 10 - получить статус кабеля Ethernet. ====
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 10 - номер подфункции
Возвращаемое значение:
* al = -1 - драйвер сетевой карты не загружен или
не поддерживает эту функцию
* al = 0 - кабель не подключён
* al = 1 - кабель подключён
* ebx разрушается
Замечания:
* Текущая реализация ядра поддерживает эту функцию
только для сетевых карт RTL8139.
 
======================================================================
==== Функция 53, подфункция 11 - прочитать данные сетевого стека. ====
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 11 - номер подфункции
* ecx = хэндл сокета
* edx = указатель на буфер
* esi = число байт для чтения;
* esi = 0 - читать все данные (максимум 4096 байт)
Возвращаемое значение:
* eax = число прочитанных байт (0 при неверном хэндле)
* ebx разрушается
 
======================================================================
Функция 53, подфункция 255 - отладочная информация сетевого драйвера.
======================================================================
Параметры:
* eax = 53 - номер функции
* ebx = 255 - номер подфункции
* ecx = тип запрашиваемой информации (смотри ниже)
Возвращаемое значение:
* eax = запрошенная информация
* ebx разрушается
Возможные значения ecx:
* 100: длина очереди 0 (empty queue)
* 101: длина очереди 1 (ip-out queue)
* 102: длина очереди 2 (ip-in queue)
* 103: длина очереди 3 (net1out queue)
* 200: число элементов в таблице ARP
* 201: размер таблицы ARP (в элементах) (20 в текущей версии)
* 202: прочитать элемент edx таблицы ARP во временный буфер, откуда
берут информацию 5 последующих типов;
в этом случае eax неопределён
* 203: IP-адрес, запомненный типом 202
* 204: старшее dword MAC-адреса, запомненного типом 202
* 205: младшее word MAC-адреса, запомненного типом 202
* 206: слово статуса, запомненное типом 202
* 207: слово ttl, запомненное типом 202
* 2: общее число полученных IP-пакетов
* 3: общее число переданных IP-пакетов
* 4: общее число сдампленных полученных пакетов
* 5: общее число полученных ARP-пакетов
* 6: статус драйвера пакетов, 0=неактивен,
ненулевое значение=активен
 
======================================================================
====================== Функция 55, подфункция 55 =====================
========== Начать проигрывать данные на встроенном спикере. ==========
======================================================================
4631,6 → 4246,213
* функция не возвращает значения
 
======================================================================
=================== Функция 74, подфункция -1 ========================
=========== Получить количество активных сетевых устройств. ==========
======================================================================
Параметры:
* eax = 74 - номер функции
* bl = -1 - номер подфункции
Возвращаемое значение:
* eax = количество активных сетевых устройств
 
======================================================================
==== Функция 74, подфункция 0, Получить тип сетевого устройства. =====
======================================================================
Параметры:
* eax = 74 - номер функции
* bl = 0 - номер подфункции
* bh = номер устройства
Возвращаемое значение:
* eax = тип устройства
 
======================================================================
==== Функция 74, подфункция 1, Получить имя сетевого устройства. =====
======================================================================
Параметры:
* eax = 74 - номер функции
* bl = 1 - номер подфункции
* bh = номер устройства
* ecx = указатель на буфера - 64 байт
Возвращаемое значение:
* eax = -1 для ошибки
* В случае успеха в буфер записывается имя сетевого устройства
 
======================================================================
======= Функция 74, подфункция 2, Сброс сетевого устройства. =========
======================================================================
Параметры:
* eax = 74 - номер функции
* bl = 2 - номер подфункции
* bh = номер устройства
Возвращаемое значение:
* eax = -1 для ошибки
 
======================================================================
====== Функция 74, подфункция 3, Остановить сетевое устройство. ======
======================================================================
Параметры:
* eax = 74 - номер функции
* bl = 3 - номер подфункции
* bh = номер устройства
Возвращаемое значение:
* eax = -1 для ошибки
 
======================================================================
======= Функция 75, подфункция 0, Open socket (Открыть сокет). =======
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 0 - номер подфункции
* ecx = домен
* edx = тип
* esi = протокол
Возвращаемое значение:
* eax = номер сокета, -1 для ошибки
* ebx = код ошибки
 
======================================================================
======= Функция 75, подфункция 1, Close socket (Закрыть сокет). ======
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 1 - номер подфункции
* ecx = номер сокета
Возвращаемое значение:
* eax = -1 для ошибки
* ebx = код ошибки
 
======================================================================
============= Функция 75, подфункция 2, Bind (Привязка). =============
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 2 - номер подфункции
* ecx = номер сокета
* edx = указатель на структуру sockaddr
* esi = длина структуры sockaddr
Возвращаемое значение:
* eax = -1 для ошибки
* ebx = код ошибки
 
======================================================================
============ Функция 75, подфункция 3, Listen (Слушать). =============
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 3 - номер подфункции
* ecx = номер сокета
* edx = backlog (возвращаемый лог)
Возвращаемое значение:
* eax = -1 для ошибки
* ebx = код ошибки
 
======================================================================
========== Функция 75, подфункция 4, Connect (Соединение). ===========
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 4 - номер подфункции
* ecx = номер сокета
* edx = указатель на структуру sockaddr
* esi = длина структуры sockaddr
Возвращаемое значение:
* eax = -1 для ошибки
* ebx = код ошибки
 
======================================================================
=========== Функция 75, подфункция 5, Accept (Соглашение). ===========
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 5 - номер подфункции
* ecx = номер сокета
* edx = указатель на структуру sockaddr
* esi = длина структуры sockaddr
Возвращаемое значение:
* eax = номер сокета из принятого сокета, -1 для ошибки
* ebx = код ошибки
 
======================================================================
============= Функция 75, подфункция 6, Send (Послать). ==============
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 6 - номер подфункции
* ecx = номер сокета
* edx = указатель на буфер
* esi = длина буфера
* edi = флаги
Возвращаемое значение:
* eax = количество скопированных байтов, -1 для ошибки
* ebx = код ошибки
 
======================================================================
============ Функция 75, подфункция 7, Receive (Получить). ===========
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 7 - номер подфункции
* ecx = номер сокета
* edx = указатель на буфер
* esi = длина буфера
* edi = флаги
Возвращаемое значение:
* eax = количество скопированных байтов, -1 для ошибки
* ebx = код ошибки
 
======================================================================
= Функция 75, подфункция 8, Set socket options (Задать опции сокета) =
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 8 - номер подфункции
* ecx = номер сокета
* edx = указатель на optstruct
Возвращаемое значение:
* eax = -1 для ошибки
* ebx = код ошибки
Замечания:
 
Optstruct: dd level
dd optionname
dd optlength
db options...
 
======================================================================
= Функция 75, подфункция 9, Get socket options(Получить опции сокета)
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 9 - номер подфункции
* ecx = номер сокета
* edx = указатель на optstruct
Возвращаемое значение:
* eax = -1 для ошибки
* ebx = код ошибки
Замечания:
 
Optstruct: dd level
dd optionname
dd optlength
db options...
 
======================================================================
= Функция 75, подфункция 10, Get socketpair (Получить парный сокет). =
======================================================================
Параметры:
* eax = 75 - номер функции
* bl = 10 - номер подфункции
Возвращаемое значение:
* eax = socketnum1, -1 для ошибки
* ebx = socketnum2, код ошибки в случае ошибки
Замечания:
 
Optstruct: dd level
dd optionname
dd optlength
db options...
 
======================================================================
========== Функция -1 - завершить выполнение потока/процесса =========
======================================================================
Параметры:
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
2411,408 → 2411,6
</UL>
 
======================================================================
=========================== Function 52 ==============================
======================================================================
 
WARNING: This function is obsolete and is only present in the
documentation as a guide to understand/port the older network
applications. For new programs, use function 74
 
======================================================================
=== 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 ==============================
======================================================================
 
WARNING: This function is obsolete and is only present in the
documentation as a guide to understand/port the older network
applications. For new programs, use function 75.
 
======================================================================
============ Function 53, subfunction 0 - open UDP-socket. ===========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 0 - subfunction number
* ecx = local port (only low word is taken into account),
ecx = 0 - let the system choose a port
* edx = remote port (only low word is taken into account)
* esi = remote IP
Returned value:
* eax = -1 = 0xFFFFFFFF - error; ebx destroyed
* eax = socket handle (some number which unambiguously identifies
socket and have sense only for the system) - success;
ebx destroyed
 
======================================================================
=========== Function 53, subfunction 1 - close UDP-socket. ===========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 1 - subfunction number
* ecx = socket handle
Returned value:
* eax = -1 - incorrect handle
* eax = 0 - success
* ebx destroyed
Remarks:
* The current implementation does not close automatically all
sockets of a thread at termination. In particular, one should not
kill a thread with many opened sockets - there will be an outflow
of resources.
 
======================================================================
============== Function 53, subfunction 2 - poll socket. =============
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 2 - subfunction number
* ecx = socket handle
Returned value:
* eax = number of read bytes, 0 for incorrect handle
* ebx destroyed
 
======================================================================
========= Function 53, subfunction 3 - read byte from socket. ========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 3 - subfunction number
* ecx = socket handle
Returned value:
* if there is no read data or handle is incorrect: eax=0, bl=0,
other bytes of ebx are destroyed
* if there are read data: eax=number of rest bytes
(possibly 0), bl=read byte, other bytes of ebx are destroyed
 
======================================================================
========== Function 53, subfunction 4 - write to UDP-socket. =========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 4 - subfunction number
* ecx = socket handle
* edx = number of bytes to write
* esi = pointer to data to write
Returned value:
* eax = 0xffffffff - error (invalid handle or not enough memory)
* eax = 0 - success
* ebx destroyed
Remarks:
* Number of bytes to write must not exceed 1500-28, though
the appropriate check is not made.
 
======================================================================
============ Function 53, subfunction 5 - open TCP-socket. ===========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 5 - subfunction number
* ecx = local port (only low word is taken into account),
ecx = 0 - let the system choose a port
* edx = remote port (only low word is taken into account)
* esi = remote IP
* edi = open mode: SOCKET_PASSIVE=0 or SOCKET_ACTIVE=1
Returned value:
* eax = -1 = 0xFFFFFFFF - error; ebx destroys
* eax = socket handle (some number which unambiguously identifies
socket and have sense only for the system) - success;
ebx destroyed
 
======================================================================
========= Function 53, subfunction 6 - get TCP-socket status. ========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 6 - subfunction number
* ecx = socket handle
Returned value:
* eax = 0 for incorrect handle or socket status: one of
* TCB_LISTEN = 1
* TCB_SYN_SENT = 2
* TCB_SYN_RECEIVED = 3
* TCB_ESTABLISHED = 4
* TCB_FIN_WAIT_1 = 5
* TCB_FIN_WAIT_2 = 6
* TCB_CLOSE_WAIT = 7
* TCB_CLOSING = 8
* TCB_LAST_ASK = 9
* TCB_TIME_WAIT = 10
* TCB_CLOSED = 11
* ebx destroyed
 
======================================================================
========== Function 53, subfunction 7 - write to TCP-socket. =========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 7 - subfunction number
* ecx = socket handle
* edx = number of bytes to write
* esi = pointer to data to write
Returned value:
* eax = 0xffffffff - error (invalid handle or not enough memory)
* eax = 0 - success
* ebx destroyed
Remarks:
* Number of bytes to write must not exceed 1500-40, though
the appropriate check is not made.
 
======================================================================
=========== Function 53, subfunction 8 - close TCP-socket. ===========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 8 - subfunction number
* ecx = socket handle
Returned value:
* eax = -1 - error (invalid handle or
not enough memory for socket close packet)
* eax = 0 - success
* ebx destroyed
Remarks:
* The current implementation does not close automatically all
sockets of a thread at termination. In particular, one should not
kill a thread with many opened sockets - there will be an outflow
of resources.
 
======================================================================
=== Function 53, subfunction 9 - check whether local port is free. ===
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 9 - subfunction number
* ecx = local port number (low 16 bits are used only)
Returned value:
* eax = 0 - port is used
* eax = 1 - port is free
* ebx destroyed
 
======================================================================
===== Function 53, subfunction 10 - query Ethernet cable status. =====
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 10 - subfunction number
Returned value:
* al = -1 - a network driver is not loaded or
does not support this function
* al = 0 - Ethernet cable is unplugged
* al = 1 - Ethernet cable is plugged
* ebx destroyed
Remarks:
* The current kernel implementation supports this function
only for RTL8139 network cards.
 
======================================================================
======= Function 53, subfunction 11 - read network stack data. =======
======================================================================
Paramters:
* eax = 53 - function number
* ebx = 11 - subfunction number
* ecx = socket handle
* edx = pointer to buffer
* esi = number of bytes to read;
* esi = 0 - read all data (maximum 4096 bytes)
Returned value:
* eax = number of bytes read (0 for incorrect handle)
* ebx destroyed
 
======================================================================
= Function 53, subfunction 255 - debug information of network driver.
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 255 - subfunction number
* ecx = type of requested information (see below)
Returned value:
* eax = requested information
* ebx destroyed
Possible values for ecx:
* 100: length of queue 0 (empty queue)
* 101: length of queue 1 (ip-out queue)
* 102: length of queue 2 (ip-in queue)
* 103: length of queue 3 (net1out queue)
* 200: number of items in the ARP table
* 201: size of the ARP table (in items) (20 for current version)
* 202: read item at edx of the ARP table to the temporary buffer,
whence 5 following types take information;
in this case eax is not defined
* 203: IP-address saved by type 202
* 204: high dword of MAC-address saved by type 202
* 205: low word of MAC-address saved by type 202
* 206: status word saved by type 202
* 207: ttl word saved by type 202
* 2: total number of received IP-packets
* 3: total number of transferred IP-packets
* 4: total number of dumped received packets
* 5: total number of received ARP-packets
* 6: status of packet driver, 0=inactive, nonzero=active
 
======================================================================
Function 55, subfunction 55 - begin to play data on built-in speaker.
======================================================================
Parameters:
3879,6 → 3477,32
is changed. Signal number corresponds to exception number.
 
======================================================================
====== Function 68, subfunction 26 - release memory pages ============
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 26 - subfunction number
* ecx = pointer to the memory block, allocated by subfunction 12
* edx = offset from the block beginnings
* esi = the size of the region of memory to release, in bytes
Remarks:
* function release range of pages from ecx+edx to ecx+edx+esi
and set virtual memory into reserved state.
 
======================================================================
========== Function 68, subfunction 27 - load file ===================
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 27 - subfunction number
* ecx = pointer to ASCIIZ-string with the filename
Returned value:
* eax = pointer to the loaded file, or zero
* edx = size of the loaded file, or zero
Remarks:
* function loads file and unpacks, if necessary
 
======================================================================
====================== Function 69 - debugging. ======================
======================================================================
A process can load other process as debugged by set of corresponding
4676,6 → 4300,7
* esi = protocol
Returned value:
* eax = socket number, -1 on error
* ebx = errorcode
 
======================================================================
============= Function 75, Subfunction 1, Close socket. ==============
4686,6 → 4311,7
* ecx = socket number
Returned value:
* eax = -1 on error
* ebx = errorcode
 
======================================================================
================== Function 75, Subfunction 2, Bind. =================
4698,6 → 4324,7
* esi = length of sockaddr structure
Returned value:
* eax = -1 on error
* ebx = errorcode
 
======================================================================
================= Function 75, Subfunction 3, Listen. ================
4709,6 → 4336,7
* edx = backlog
Returned value:
* eax = -1 on error
* ebx = errorcode
 
======================================================================
================ Function 75, Subfunction 4, Connect. ================
4721,6 → 4349,7
* esi = length of sockaddr structure
Returned value:
* eax = -1 on error
* ebx = errorcode
 
======================================================================
================= Function 75, Subfunction 5, Accept. ================
4732,7 → 4361,8
* edx = pointer to sockaddr structure
* esi = length of sockaddr structure
Returned value:
* eax = -1 on error
* eax = socket number of accepted socket, -1 on error
* ebx = errorcode
 
======================================================================
================== Function 75, Subfunction 6, Send. =================
4743,8 → 4373,10
* ecx = socket number
* edx = pointer to buffer
* esi = length of buffer
* edi = flags
Returned value:
* eax = number of bytes copied, -1 on error
* ebx = errorcode
 
======================================================================
================ Function 75, Subfunction 7, Receive. ================
4758,6 → 4390,7
* edi = flags
Returned value:
* eax = number of bytes copied, -1 on error
* ebx = errorcode
 
======================================================================
=========== Function 75, Subfunction 8, Set socket options. ==========
4769,6 → 4402,7
* edx = pointer to optstruct
Returned value:
* eax = -1 on error
* ebx = errorcode
Remarks:
 
Optstruct: dd level
4786,6 → 4420,7
* edx = pointer to optstruct
Returned value:
* eax = -1 on error
* ebx = errorcode
Remarks:
 
Optstruct: dd level
4801,7 → 4436,7
* bl = 10 - subfunction number
Returned value:
* eax = socketnum1, -1 on error
* ebx = socketnum2
* ebx = socketnum2, errorcode on error
Remarks:
 
Optstruct: dd level
/kernel/branches/Kolibri-acpi/docs/usbapi.txt
60,8 → 60,7
The returned value NULL means that the initialization has failed.
Any other value means that configuration was successful; the kernel does not
try to interpret the value. It can be, for example, pointer to the internal
data allocated with Kmalloc, or index in some internal table. Remember that
Kmalloc() is NOT stdcall, it destroys ebx.
data allocated with Kmalloc, or index in some internal table.
 
The driver can implement the function
 
184,9 → 183,7
USB_STATUS_OVERRUN = 8 ; too many data from endpoint
USB_STATUS_UNDERRUN = 9 ; too few data from endpoint
USB_STATUS_BUFOVERRUN = 12 ; overflow of internal controller buffer
; possible only for isochronous transfers
USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer
; possible only for isochronous transfers
USB_STATUS_CLOSED = 16 ; pipe closed, either explicitly with USBClosePipe
; or due to device disconnect
 
196,3 → 193,13
implicitly due to device disconnect, all callback functions are called
with USB_STATUS_CLOSED. The call to DeviceDisconnected() occurs after
all callbacks.
 
void* __stdcall USBGetParam(void* pipe0, int param);
Returns miscellaneous parameters of the device.
pipe0 is the pointer to the config pipe.
param = 0: return pointer to device descriptor
param = 1: return pointer to config descriptor, same as passed to AddDevice
param = 2: return speed at which the device is operating, one of
USB_SPEED_FS = 0 ; full-speed
USB_SPEED_LS = 1 ; low-speed
USB_SPEED_HS = 2 ; high-speed
/kernel/branches/Kolibri-acpi/drivers/imports.inc
101,6 → 101,7
USBOpenPipe,\
USBNormalTransferAsync,\
USBControlTransferAsync,\
USBGetParam,\
\
DiskAdd,\
DiskMediaChanged,\
/kernel/branches/Kolibri-acpi/drivers/sound.asm
11,7 → 11,9
 
include 'proc32.inc'
include 'imports.inc'
include '../struct.inc'
 
 
VID_INTEL = 0x8086
VID_NVIDIA = 0x10DE
VID_VIA = 0x1106
149,10 → 151,24
public service_proc
public version
 
struct SRV
srv_name rb 16 ;ASCIIZ string
magic dd ? ;+0x10 ;'SRV '
size dd ? ;+0x14 ;size of structure SRV
fd dd ? ;+0x18 ;next SRV descriptor
bk dd ? ;+0x1C ;prev SRV descriptor
base dd ? ;+0x20 ;service base address
entry dd ? ;+0x24 ;service START function
srv_proc dd ? ;+0x28 ;user mode service handler
srv_proc_ex dd ? ;+0x2C ;kernel mode service handler
ends
 
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
mov eax, [srv_entry]
cmp [state], 1
jne .stop
 
161,9 → 177,16
call SysMsgBoardStr
end if
 
test eax, eax
jnz .done
call detect_controller
ret
.stop:
test eax, eax
jz .done
leave
jmp eax
.done:
xor eax, eax
ret
endp
237,7 → 260,11
end if
 
stdcall GetService, dword[edi+4]
test eax, eax
jz .err
 
mov edx, [eax+SRV.entry]
mov [srv_entry], edx
ret
 
.err:
377,6 → 404,8
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
srv_entry dd 0
 
intelac97 db 'INTELAC97', 0
vt823x db 'VT823X', 0
sis db 'SIS', 0
390,4 → 419,5
msgLoading db 'Loading ',0
msgNewline db 13,10,0
 
 
section '.data' data readable writable align 16
/kernel/branches/Kolibri-acpi/fs/ext2.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; 02.02.2010 turbanoff - support 70.5 ;;
;; 23.01.2010 turbanoff - support 70.0 70.1 ;;
177,14 → 177,50
ei_unused dw ? ;RUS: зарезервировано ;ENG: reserved
ends
 
ext2_test_superblock:
cmp [fs_type], 0x83
jne .no
struct EXTFS PARTITION
Lock MUTEX
log_block_size dd ?
block_size dd ?
count_block_in_block dd ?
blocks_per_group dd ?
global_desc_table dd ?
root_inode dd ? ; pointer to root inode in memory
inode_size dd ?
count_pointer_in_block dd ? ; block_size / 4
count_pointer_in_block_square dd ? ; (block_size / 4)**2
ext2_save_block dd ? ;RUS: блок на глобальную 1 процедуру ;ENG: block for 1 global procedure
ext2_temp_block dd ? ;RUS: блок для мелких процедур ;ENG: block for small procedures
ext2_save_inode dd ? ;RUS: inode на глобальную процедуру ;ENG: inode for global procedure
ext2_temp_inode dd ? ;RUS: inode для мелких процедур ;ENG: inode for small procedures
groups_count dd ?
superblock rd 512/4
ends
 
mov eax, [PARTITION_START]
add eax, 2 ;superblock start at 1024b
call hd_read
iglobal
align 4
ext2_user_functions:
dd ext2_free
dd (ext2_user_functions_end - ext2_user_functions - 4) / 4
dd ext2_Read
dd ext2_ReadFolder
dd ext2_Rewrite
dd ext2_Write
dd ext2_SetFileEnd
dd ext2_GetFileInfo
dd ext2_SetFileInfo
dd 0
dd ext2_Delete
dd ext2_CreateFolder
ext2_user_functions_end:
endg
 
proc ext2_create_partition
push ebx
 
mov eax, 2 ;superblock start at 1024b
add ebx, 512 ; get pointer to fs-specific buffer
call fs_read32_sys
 
cmp [ebx + EXT2_SB_STRUC.log_block_size], 3 ;0,1,2,3
ja .no
cmp [ebx + EXT2_SB_STRUC.magic], 0xEF53
198,27 → 234,41
test eax, EXT2_FEATURE_INCOMPAT_FILETYPE
jz .no
test eax, not EXT4_FEATURE_INCOMPAT_SUPP
jnz .no
jz ext2_setup
 
; OK, this is correct EXT2 superblock
clc
ret
.no:
; No, this superblock isn't EXT2
stc
pop ebx
xor eax, eax
ret
 
; OK, this is correct EXT2 superblock
ext2_setup:
mov [fs_type], 2
movi eax, sizeof.EXTFS
call malloc
test eax, eax
jz ext2_create_partition.no
 
push 512
call kernel_alloc ; mem for superblock
mov ecx, dword [ebp+PARTITION.FirstSector]
mov dword [eax+EXTFS.FirstSector], ecx
mov ecx, dword [ebp+PARTITION.FirstSector+4]
mov dword [eax+EXTFS.FirstSector+4], ecx
mov ecx, dword [ebp+PARTITION.Length]
mov dword [eax+EXTFS.Length], ecx
mov ecx, dword [ebp+PARTITION.Length+4]
mov dword [eax+EXTFS.Length+4], ecx
mov ecx, [ebp+PARTITION.Disk]
mov [eax+EXTFS.Disk], ecx
mov [eax+EXTFS.FSUserFunctions], ext2_user_functions
push ebp esi edi
mov ebp, eax
lea ecx, [eax+EXTFS.Lock]
call mutex_init
 
mov esi, ebx
mov edi, eax
lea edi, [ebp+EXTFS.superblock]
mov ecx, 512/4
rep movsd ; copy sb to reserved mem
mov ebx, eax
mov [ext2_data.sb], eax
 
mov eax, [ebx + EXT2_SB_STRUC.blocks_count]
sub eax, [ebx + EXT2_SB_STRUC.first_data_block]
226,72 → 276,103
xor edx, edx
div [ebx + EXT2_SB_STRUC.blocks_per_group]
inc eax
mov [ext2_data.groups_count], eax
mov [ebp+EXTFS.groups_count], eax
 
mov ecx, [ebx + EXT2_SB_STRUC.log_block_size]
inc ecx
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
mov [ebp+EXTFS.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
 
mov eax, 1
shl eax, cl
mov [ext2_data.count_block_in_block], eax
mov [ebp+EXTFS.count_block_in_block], eax
 
shl eax, 7
mov [ext2_data.count_pointer_in_block], eax
mov [ebp+EXTFS.count_pointer_in_block], eax
mov edx, eax ;RUS: потом еще квадрат найдем ;ENG: we'll find a square later
 
shl eax, 2
mov [ext2_data.block_size], eax
mov [ebp+EXTFS.block_size], eax
 
push eax eax ; 2 kernel_alloc
 
mov eax, edx
mul edx
mov [ext2_data.count_pointer_in_block_square], eax
mov [ebp+EXTFS.count_pointer_in_block_square], eax
 
call kernel_alloc
mov [ext2_data.ext2_save_block], eax ; and for temp block
mov [ebp+EXTFS.ext2_save_block], eax ; and for temp block
call kernel_alloc
mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc
mov [ebp+EXTFS.ext2_temp_block], eax ; and for get_inode proc
 
movzx ebp, word [ebx + EXT2_SB_STRUC.inode_size]
movzx eax, word [ebx + EXT2_SB_STRUC.inode_size]
mov ecx, [ebx + EXT2_SB_STRUC.blocks_per_group]
 
mov [ext2_data.inode_size], ebp
mov [ext2_data.blocks_per_group], ecx
mov [ebp+EXTFS.inode_size], eax
mov [ebp+EXTFS.blocks_per_group], ecx
 
push ebp ebp ebp ;3 kernel_alloc
push eax eax eax ;3 kernel_alloc
call kernel_alloc
mov [ext2_data.ext2_save_inode], eax
mov [ebp+EXTFS.ext2_save_inode], eax
call kernel_alloc
mov [ext2_data.ext2_temp_inode], eax
mov [ebp+EXTFS.ext2_temp_inode], eax
call kernel_alloc
mov [ext2_data.root_inode], eax
mov [ebp+EXTFS.root_inode], eax
 
mov ebx, eax
mov eax, EXT2_ROOT_INO
call ext2_get_inode ; read root inode
 
jmp return_from_part_set
mov eax, ebp ; return pointer to EXTFS
pop edi esi ebp ebx
ret
endp
 
proc ext2_free
push ebp
xchg ebp, eax
stdcall kernel_free, [ebp+EXTFS.ext2_save_block]
stdcall kernel_free, [ebp+EXTFS.ext2_temp_block]
stdcall kernel_free, [ebp+EXTFS.ext2_save_inode]
stdcall kernel_free, [ebp+EXTFS.ext2_temp_inode]
stdcall kernel_free, [ebp+EXTFS.root_inode]
xchg ebp, eax
call free
pop ebp
ret
endp
 
proc ext2_lock
lea ecx, [ebp+EXTFS.Lock]
jmp mutex_lock
endp
 
proc ext2_unlock
lea ecx, [ebp+EXTFS.Lock]
jmp mutex_unlock
endp
 
;==================================================================
;read ext2 block form FS to memory
;in: eax = i_block (address of block in ext2 terms)
; ebx = pointer to return memory
; ebp = pointer to EXTFS
;out: eax - error code (0 = no_error)
ext2_get_block:
push ebx ecx
mov ecx, [ext2_data.log_block_size]
mov ecx, [ebp+EXTFS.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
mov ecx, eax
push [ebp+EXTFS.count_block_in_block]
@@:
call hd_read
cmp [hd_error], 0
mov eax, ecx
call fs_read32_sys
test eax, eax
jnz .fail
inc eax
inc ecx
add ebx, 512
loop @B
dec dword [esp]
jnz @B
pop ecx
xor eax, eax
@@:
pop ecx ebx
304,16 → 385,17
;===================================================================
;RUS: получает номер блока из extent inode ;ENG: receives block number from extent inode
;RUS: in: ecx = номер блока по порядку ;ENG: in: ecx = consecutive block number
;RUS: ebp = адрес extent header`а ;ENG: ebp = address of extent header
;RUS: esi = адрес extent header`а ;ENG: esi = address of extent header
;RUS: ebp = указатель на структуру EXTFS ;ENG: ebp = pointer to EXTFS
;RUS: out: ecx - адрес очередного блока в случае успеха ;ENG: out: ecx - address of next block, if successful
;RUS: eax - номер ошибки (если равно 0, то ошибки нет) ;ENG: eax - error number (0 - no error)
ext4_block_recursive_search:
cmp word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
cmp word [esi + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC
jne .fail
movzx ebx, [ebp + EXT4_EXTENT_HEADER.eh_entries]
add ebp, sizeof.EXT4_EXTENT_HEADER
cmp word [ebp - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0
movzx ebx, [esi + EXT4_EXTENT_HEADER.eh_entries]
add esi, sizeof.EXT4_EXTENT_HEADER
cmp word [esi - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0
je .leaf_block ;листовой ли это блок?
;не листовой блок, а индексный ; eax - ext4_extent_idx
325,48 → 407,48
cmp ebx, 1 ;у индексов не хранится длина,
je .end_search_index ;поэтому, если остался последний - то это нужный
cmp ecx, [ebp + EXT4_EXTENT_IDX.ei_block]
cmp ecx, [esi + EXT4_EXTENT_IDX.ei_block]
jb .fail
cmp ecx, [ebp + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса
cmp ecx, [esi + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса
jb .end_search_index ;следующий дальше - значит текущий, то что нам нужен
add ebp, sizeof.EXT4_EXTENT_IDX
add esi, sizeof.EXT4_EXTENT_IDX
dec ebx
jmp @B
.end_search_index:
;ebp указывает на нужный extent_idx, считываем следующий блок
mov ebx, [ext2_data.ext2_temp_block]
mov eax, [ebp + EXT4_EXTENT_IDX.ei_leaf_lo]
mov ebx, [ebp+EXTFS.ext2_temp_block]
mov eax, [esi + EXT4_EXTENT_IDX.ei_leaf_lo]
call ext2_get_block
test eax, eax
jnz .fail
mov ebp, ebx
mov esi, ebx
jmp ext4_block_recursive_search ;рекурсивно прыгаем в начало
.leaf_block: ;листовой блок ebp - ext4_extent
.leaf_block: ;листовой блок esi - ext4_extent
;цикл по экстентам
@@:
test ebx, ebx
jz .fail ;ни один узел не подошел - ошибка
 
mov edx, [ebp + EXT4_EXTENT.ee_block]
mov edx, [esi + EXT4_EXTENT.ee_block]
cmp ecx, edx
jb .fail ;если меньше, значит он был в предыдущих блоках -> ошибка
 
movzx edi, [ebp + EXT4_EXTENT.ee_len]
movzx edi, [esi + EXT4_EXTENT.ee_len]
add edx, edi
cmp ecx, edx
jb .end_search_extent ;нашли нужный блок
add ebp, sizeof.EXT4_EXTENT
add esi, sizeof.EXT4_EXTENT
dec ebx
jmp @B
.end_search_extent:
mov edx, [ebp + EXT4_EXTENT.ee_start_lo]
sub ecx, [ebp + EXT4_EXTENT.ee_block] ;разница в ext4 блоках
mov edx, [esi + EXT4_EXTENT.ee_start_lo]
sub ecx, [esi + EXT4_EXTENT.ee_block] ;разница в ext4 блоках
add ecx, edx
xor eax, eax
ret
378,15 → 460,16
;===================================================================
;получает адрес ext2 блока из inode с определнным номером
;RUS: in: ecx = номер блока в inode (0..) ;ENG: in: ecx = number of block in inode (0..)
;RUS: ebp = адрес inode ;ENG: ebp = inode address
;RUS: esi = адрес inode ;ENG: esi = inode address
;RUS: ebp = указатель на структуру EXTFS;ENG: ebp = pointer to EXTFS
;RUS: out: ecx = адрес очередного блока ;ENG: out: ecx = next block address
;RUS: eax - error code ;ENG: eax - error code
ext2_get_inode_block:
test [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
test [esi + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL
jz @F
 
pushad
add ebp, EXT2_INODE_STRUC.i_block ;ebp - extent_header
add esi, EXT2_INODE_STRUC.i_block ;esi - extent_header
call ext4_block_recursive_search
mov PUSHAD_ECX, ecx
mov PUSHAD_EAX, eax
398,19 → 481,19
jb .get_direct_block
 
sub ecx, 12
cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect blocks
cmp ecx, [ebp+EXTFS.count_pointer_in_block] ; 12.. - indirect blocks
jb .get_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block]
cmp ecx, [ext2_data.count_pointer_in_block_square]
sub ecx, [ebp+EXTFS.count_pointer_in_block]
cmp ecx, [ebp+EXTFS.count_pointer_in_block_square]
jb .get_double_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block_square]
sub ecx, [ebp+EXTFS.count_pointer_in_block_square]
;triple indirect block
push edx ebx
 
mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
mov ebx, [ext2_data.ext2_temp_block]
mov eax, [esi + EXT2_INODE_STRUC.i_block + 14*4]
mov ebx, [ebp+EXTFS.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
417,7 → 500,7
 
xor edx, edx
mov eax, ecx
div [ext2_data.count_pointer_in_block_square]
div [ebp+EXTFS.count_pointer_in_block_square]
 
;RUS: eax - номер в полученном блоке edx - номер дальше
;ENG: eax - current block number, edx - next block number
432,8 → 515,8
.get_double_indirect_block:
push edx ebx
 
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
mov ebx, [ext2_data.ext2_temp_block]
mov eax, [esi + EXT2_INODE_STRUC.i_block + 13*4]
mov ebx, [ebp+EXTFS.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
441,7 → 524,7
mov eax, ecx
@@:
xor edx, edx
div [ext2_data.count_pointer_in_block]
div [ebp+EXTFS.count_pointer_in_block]
 
mov eax, [ebx + eax*4]
call ext2_get_block
455,8 → 538,8
 
.get_indirect_block:
push ebx
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
mov ebx, [ext2_data.ext2_temp_block]
mov eax, [esi + EXT2_INODE_STRUC.i_block + 12*4]
mov ebx, [ebp+EXTFS.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz @F ;RUS: если не было ошибки ;ENG: if there was no error
467,7 → 550,7
ret
 
.get_direct_block:
mov ecx, [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
mov ecx, [esi + EXT2_INODE_STRUC.i_block + ecx*4]
xor eax, eax
ret
 
475,6 → 558,7
;get content inode by num
;in: eax = inode_num
; ebx = address of inode content
; ebp = pointer to EXTFS
;out: eax - error code
ext2_get_inode:
pushad
482,8 → 566,7
dec eax
xor edx, edx
mov ecx, [ext2_data.sb]
div [ecx + EXT2_SB_STRUC.inodes_per_group]
div [ebp + EXT2_SB_STRUC.inodes_per_group + EXTFS.superblock]
 
push edx ;locale num in group
 
494,10 → 577,10
;RUS: найдем блок в котором он находится
;ENG: in eax - inode group offset relative to global descriptor table start
;ENG: let's find the block this inode is in
div [ext2_data.block_size]
add eax, [ecx + EXT2_SB_STRUC.first_data_block]
div [ebp+EXTFS.block_size]
add eax, [ebp + EXT2_SB_STRUC.first_data_block + EXTFS.superblock]
inc eax
mov ebx, [ext2_data.ext2_temp_block]
mov ebx, [ebp+EXTFS.ext2_temp_block]
call ext2_get_block
test eax, eax
jnz .fail
505,27 → 588,28
add ebx, edx ;RUS: локальный номер в блоке ;ENG: local number inside block
mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table] ;RUS: номер блока - в терминах ext2
;ENG: block number - in ext2 terms
mov ecx, [ext2_data.log_block_size]
mov ecx, [ebp+EXTFS.log_block_size]
shl eax, cl
add eax, [PARTITION_START] ;RUS: а старт раздела - в терминах hdd (512)
;ENG: partition start - in HDD terms (512)
;RUS: eax - указывает на таблицу inode-ов на hdd ;ENG: eax - points to inode table on HDD
mov esi, eax ;RUS: сохраним его пока в esi ;ENG: let's save it in esi for now
 
;RUS: прибавим локальный адрес inode-а ;ENG: add local address of inode
pop eax ; index
mov ecx, [ext2_data.inode_size]
mov ecx, [ebp+EXTFS.inode_size]
mul ecx ; (index * inode_size)
mov ebp, 512
div ebp ;RUS: поделим на размер блока ;ENG: divide by block size
;RUS: поделим на размер блока ;ENG: divide by block size
mov ecx, eax
and ecx, 512 - 1
shrd eax, edx, 9
 
add eax, esi ;RUS: нашли адрес блока для чтения ;ENG: found block address to read
mov ebx, [ext2_data.ext2_temp_block]
call hd_read
cmp [hd_error], 0
mov ebx, [ebp+EXTFS.ext2_temp_block]
call fs_read32_sys
test eax, eax
jnz .fail
 
mov esi, edx ;RUS: добавим "остаток" ;ENG: add the "remainder"
mov esi, ecx ;RUS: добавим "остаток" ;ENG: add the "remainder"
mov ecx, [ebp+EXTFS.inode_size]
add esi, ebx ;RUS: к адресу ;ENG: to the address
rep movsb ;RUS: копируем inode ;ENG: copy inode
xor eax, eax
535,55 → 619,47
ret
 
;----------------------------------------------------------------
;
; ext2_HdReadFolder - read disk folder
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ext2_HdReadFolder:
; ext2_ReadFolder - EXT2FS implementation of reading a folder
; in: ebp = pointer to EXTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ext2_ReadFolder:
call ext2_lock
cmp byte [esi], 0
jz .root_folder
 
push ebx ecx edx
call ext2_find_lfn ;вернет в ebp адрес inode
pop edx ecx ebx
push ebx
stdcall ext2_find_lfn, [esp+4+4] ;вернет в esi адрес inode
pop ebx
test eax, eax
jnz .error_ret
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .error_not_found
jmp @F
 
.root_folder:
mov ebp, [ext2_data.root_inode]
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
mov esi, [ebp+EXTFS.root_inode]
test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .error_root
;придется копировать inode
push ecx
mov esi, ebp
mov edi, [ext2_data.ext2_save_inode]
mov ecx, [ext2_data.inode_size]
mov edi, [ebp+EXTFS.ext2_save_inode]
mov ecx, [ebp+EXTFS.inode_size]
shr ecx, 2
mov ebp, edi
push edi
rep movsd
pop ecx
pop esi
@@:
cmp [ebp + EXT2_INODE_STRUC.i_size], 0 ;папка пуста
cmp [esi + EXT2_INODE_STRUC.i_size], 0 ;папка пуста
je .error_empty_dir
mov edx, [ebx + 16]
push edx ;адрес результата [edi + 28]
push 0 ;конец очередного блока папки [edi + 24]
push ecx ;сколько файлов нужно прочитать [edi + 20]
push dword [ebx] ;первый "нужный" файл [edi + 16]
push dword [ebx + 4];флаги [edi + 12]
push dword [ebx +12];сколько файлов нужно прочитать [edi + 20]
push dword [ebx + 4];первый "нужный" файл [edi + 16]
push dword [ebx + 8];флаги [edi + 12]
push 0 ;[EXT2_read_in_folder] [edi + 8]
push 0 ;[EXT2_files_in_folder] [edi + 4]
push 0 ;номер блока по порядку [edi]
601,14 → 677,14
jnz .error_get_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
mov ebx, [ebp+EXTFS.ext2_save_block]
call ext2_get_block ; и считываем блок с hdd
test eax, eax
jnz .error_get_block
 
mov esi, ebx ; esi = current dir record
add ebx, [ext2_data.block_size]
mov [edi + 24], ebx ; запомним конец очередного блока
mov eax, ebx ; ebx = current dir record
add eax, [ebp+EXTFS.block_size]
mov [edi + 24], eax ; запомним конец очередного блока
 
mov ecx, [edi + 16] ; ecx = first wanted (flags ommited)
 
615,26 → 691,26
.find_wanted_start:
jecxz .find_wanted_end
.find_wanted_cycle:
cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz @F
inc dword [edi + 4] ; EXT2_files_in_folder
dec ecx
@@:
movzx ebx, [esi + EXT2_DIR_STRUC.rec_len]
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
 
cmp ebx, 12 ; минимальная длина записи
cmp eax, 12 ; минимальная длина записи
jb .error_bad_len
test ebx, 0x3 ; длина записи должна делиться на 4
test eax, 0x3 ; длина записи должна делиться на 4
jnz .error_bad_len
 
sub [ebp + EXT2_INODE_STRUC.i_size], ebx ;вычитаем напрямую из структуры inode
add esi, ebx ; к следующей записи
cmp esi, [edi + 24] ; сравниваем с концом блока
sub [esi + EXT2_INODE_STRUC.i_size], eax ;вычитаем напрямую из структуры inode
add ebx, eax ; к следующей записи
cmp ebx, [edi + 24] ; сравниваем с концом блока
jb .find_wanted_start
 
push .find_wanted_start
.end_block: ;вылетели из цикла
cmp [ebp + EXT2_INODE_STRUC.i_size], 0
cmp [esi + EXT2_INODE_STRUC.i_size], 0
jle .end_dir
 
inc dword [edi] ;получаем новый блок
645,15 → 721,15
jnz .error_get_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
mov ebx, [ebp+EXTFS.ext2_save_block]
call ext2_get_block
test eax, eax
jnz .error_get_block
 
pop ecx
mov esi, ebx
add ebx, [ext2_data.block_size]
mov [edi + 24], ebx ;запомним конец блока
mov eax, ebx
add eax, [ebp+EXTFS.block_size]
mov [edi + 24], eax ;запомним конец блока
ret ; опять в цикл
 
.wanted_end:
664,7 → 740,7
mov ecx, [edi + 20]
.wanted_start: ; ищем first_wanted+count
jecxz .wanted_end
cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
cmp [ebx + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz .empty_rec
inc dword [edi + 8]
inc dword [edi + 4]
676,9 → 752,9
rep stosd
pop ecx edi
 
push esi edi edx
mov eax, [esi + EXT2_DIR_STRUC.inode] ;получим дочерний inode
mov ebx, [ext2_data.ext2_temp_inode]
push ebx edi edx
mov eax, [ebx + EXT2_DIR_STRUC.inode] ;получим дочерний inode
mov ebx, [ebp+EXTFS.ext2_temp_inode]
call ext2_get_inode
test eax, eax
jnz .error_read_subinode
716,13 → 792,14
xor dword [edx], FS_FT_DIR ;помечаем, что это файл
 
;теперь скопируем имя, сконвертировав из UTF-8 в CP866
push ecx ;edi и esi уже сохранены в стеке
push ecx esi ;edi уже сохранен в стеке
mov esi, [esp+12]
movzx ecx, [esi + EXT2_DIR_STRUC.name_len]
lea edi, [edx + 40]
lea esi, [esi + EXT2_DIR_STRUC.name]
call utf8_to_cp866
and byte [edi], 0
pop ecx edi esi
pop esi ecx edi ebx
 
cmp byte [edx + 40], '.' ; в linux файл, начинающийся с точки - скрытый
jne @F
732,15 → 809,15
add edx, 40 + 264 ; go to next record
dec ecx ; если запись пустая ecx не надо уменьшать
.empty_rec:
movzx ebx, [esi + EXT2_DIR_STRUC.rec_len]
cmp ebx, 12 ; минимальная длина записи
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
cmp eax, 12 ; минимальная длина записи
jb .error_bad_len
test ebx, 0x3 ; длина записи должна делиться на 4
test eax, 0x3 ; длина записи должна делиться на 4
jnz .error_bad_len
 
sub [ebp + EXT2_INODE_STRUC.i_size], ebx ;вычитаем напрямую из структуры inode
add esi, ebx
cmp esi, [edi + 24] ;дошли ли до конца блока?
sub [esi + EXT2_INODE_STRUC.i_size], eax ;вычитаем напрямую из структуры inode
add ebx, eax
cmp ebx, [edi + 24] ;дошли ли до конца блока?
jb .wanted_start
 
push .wanted_start ; дошли
747,6 → 824,7
jmp .end_block
 
.end_dir: ;конец папки, когда еще не дошли до нужного файла
call ext2_unlock
mov edx, [edi + 28] ;адрес структуры результата
mov ebx, [edi + 8] ;EXT2_read_in_folder
mov ecx, [edi + 4] ;EXT2_files_in_folder
770,6 → 848,9
lea esp, [edi + 32]
.error_ret:
or ebx, -1
push eax
call ext2_unlock
pop eax
ret
.error_empty_dir: ;RUS: inode папки без блоков ;ENG: inode of folder without blocks
834,84 → 915,76
ret
 
;----------------------------------------------------------------
;
; ext2_HdRead - read hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
 
;--------------------------------------------------------------
ext2_HdRead:
; ext2_Read - EXT2FS implementation of reading a file
; in: ebp = pointer to FAT structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ext2_Read:
call ext2_lock
cmp byte [esi], 0
jnz @F
 
.this_is_nofile:
call ext2_unlock
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
push ecx ebx edx
call ext2_find_lfn
pop edx ebx ecx
push ebx
stdcall ext2_find_lfn, [esp+4+4]
pop ebx
test eax, eax
jz @F
 
call ext2_unlock
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
@@:
mov ax, [ebp + EXT2_INODE_STRUC.i_mode]
mov ax, [esi + EXT2_INODE_STRUC.i_mode]
and ax, EXT2_S_IFMT ;оставляем только тип inode в ax
cmp ax, EXT2_S_IFREG
jne .this_is_nofile
 
mov edi, edx ; edi = pointer to return mem
mov edi, [ebx+16] ; edi = pointer to return mem
mov ecx, [ebx+12]
 
test ebx, ebx
jz @F
mov esi, ebx ; esi = pointer to first_wanted
mov ebx, [esi+4]
mov eax, [esi] ;RUS: ebx : eax - стартовый номер байта ;ENG: ebx : eax - start byte number
mov eax, [ebx+4]
mov edx, [ebx+8] ;RUS: edx : eax - стартовый номер байта ;ENG: edx : eax - start byte number
 
;RUS: ///// сравним хватит ли нам файла или нет ;ENG: ///// check if file is big enough for us
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx
ja .size_great
jb .size_less
 
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
cmp [esi + EXT2_INODE_STRUC.i_size], eax
ja .size_great
 
.size_less:
call ext2_unlock
xor ebx, ebx
mov eax, ERROR_END_OF_FILE
ret
@@:
xor ebx, ebx
xor eax, eax
.size_great:
add eax, ecx ;RUS: add to first_wanted кол-во байт для чтения
;ENG: add to first_wanted number of bytes to read
adc ebx, 0
adc edx, 0
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
cmp [esi + EXT2_INODE_STRUC.i_dir_acl], edx
ja .size_great_great
jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
cmp [esi + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great ; and if it's equal, no matter where we jump
 
.size_great_less:
push 1 ;RUS: читаем по границе размера ;ENG: reading till the end of file
mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;RUS: (размер - старт) = сколько читать ;ENG: to read = (size - start)
mov ecx, [esi + EXT2_INODE_STRUC.i_size]
sub ecx, [ebx+4] ;RUS: (размер - старт) = сколько читать ;ENG: to read = (size - start)
jmp @F
 
.size_great_great:
923,13 → 996,11
;esi -> first wanted
 
push ecx ;количество считанных байт
test esi, esi
jz .zero_start
 
;получим кусок из первого блока
mov edx, [esi+4]
mov eax, [esi]
div [ext2_data.block_size]
mov edx, [ebx+8]
mov eax, [ebx+4]
div [ebp+EXTFS.block_size]
 
push eax ;счетчик блоков ложим в стек
938,7 → 1009,7
call ext2_get_inode_block
test eax, eax
jnz .error_at_first_block
mov ebx, [ext2_data.ext2_save_block]
mov ebx, [ebp+EXTFS.ext2_save_block]
mov eax, ecx
call ext2_get_block
test eax, eax
947,7 → 1018,7
add ebx, edx
 
neg edx
add edx, [ext2_data.block_size] ;RUS: block_size - стартовый байт = сколько байт 1-го блока
add edx, [ebp+EXTFS.block_size] ;RUS: block_size - стартовый байт = сколько байт 1-го блока
;ENG: block_size - start byte = number of bytes in 1st block
cmp ecx, edx
jbe .only_one_block
956,18 → 1027,16
sub eax, edx
mov ecx, edx
 
push esi
mov esi, ebx
rep movsb ;RUS: кусок 1-го блока ;ENG: part of 1st block
jmp .calc_blocks_count
pop esi
 
.zero_start:
mov eax, ecx
push 0 ;счетчик блоков ложим в стек
;теперь в eax кол-во оставшихся байт для чтения
.calc_blocks_count:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx
div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx
div [ebp+EXTFS.block_size] ;кол-во байт в последнем блоке (остаток) в edx
mov edi, eax ;кол-во целых блоков в edi
@@:
test edi, edi
982,7 → 1051,7
call ext2_get_block
test eax, eax
jnz .error_at_read_cycle
add ebx, [ext2_data.block_size]
add ebx, [ebp+EXTFS.block_size]
 
dec edi
jmp @B
999,7 → 1068,7
 
mov edi, ebx
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
mov ebx, [ebp+EXTFS.ext2_save_block]
call ext2_get_block
test eax, eax
jnz .error_at_finish_block
1013,6 → 1082,7
pop ecx ;счетчик блоков, который хранился в стеке
@@:
pop ebx ;количество считанных байт
call ext2_unlock
pop eax ; 1 или 0 - достигли ли конца файла
test eax, eax
jz @F
1035,17 → 1105,21
.error_at_finish_block:
pop ecx edx
or ebx, -1
push eax
call ext2_unlock
pop eax
ret
 
;----------------------------------------------------------------
; in: esi = file path
; ebx = pointer to dir block
; ebp = pointer to EXTFS structure
; out: esi - name without parent or not_changed
; ebx - dir_rec of inode children
ext2_test_block_by_name:
sub esp, 256 ;EXT2_filename
mov edx, ebx
add edx, [ext2_data.block_size] ;RUS: запомним конец блока ;ENG: save block end
add edx, [ebp+EXTFS.block_size] ;RUS: запомним конец блока ;ENG: save block end
 
.start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0
1097,32 → 1171,37
 
;========================
;Ищет inode по строке пути
;in: esi = name
;in: esi+[esp+4] = name
; ebp = pointer to EXTFS
;out: eax - error code
; ebp = inode
; esi = inode
; dl - первый байт из имени файла/папки
ext2_find_lfn:
mov ebp, [ext2_data.root_inode]
cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0
mov edx, [ebp+EXTFS.root_inode]
cmp [edx + EXT2_INODE_STRUC.i_blocks], 0
je .error_empty_root
.next_path_part:
push [ebp + EXT2_INODE_STRUC.i_blocks]
push [edx + EXT2_INODE_STRUC.i_blocks]
xor ecx, ecx
.folder_block_cycle:
push ecx
xchg esi, edx
call ext2_get_inode_block
xchg esi, edx
test eax, eax
jnz .error_get_inode_block
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record
mov ebx, [ebp+EXTFS.ext2_save_block] ;ebx = cur dir record
call ext2_get_block
test eax, eax
jnz .error_get_block
push esi
push edx
call ext2_test_block_by_name
pop edx
pop edi ecx
 
cmp edi, esi ;RUS: нашли имя? ;ENG: did we find a name?
1130,24 → 1209,29
cmp byte [esi], 0 ;RUS: дошли до "конца" пути -> возваращаемся
;ENG: reached the "end" of path -> returning
jnz @f
cmp dword [esp+8], 0
jz .get_inode_ret
mov esi, [esp+8]
mov dword [esp+8], 0
@@:
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;RUS: нашли, но это не папка
jne .not_found ;ENG: found, but it's not a folder
 
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] ;RUS: все же папка. ;ENG: it's a folder afterall
mov ebx, [ebp+EXTFS.ext2_save_inode] ;RUS: все же папка. ;ENG: it's a folder afterall
call ext2_get_inode
test eax, eax
jnz .error_get_inode
pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks
mov ebp, ebx
mov edx, ebx
jmp .next_path_part
.next_folder_block:
;к следующему блоку в текущей папке
pop eax ;RUS: счетчик блоков ;ENG: blocks counter
sub eax, [ext2_data.count_block_in_block]
sub eax, [ebp+EXTFS.count_block_in_block]
jle .not_found
push eax
1156,17 → 1240,17
 
.not_found:
mov eax, ERROR_FILE_NOT_FOUND
ret
ret 4
 
.get_inode_ret:
pop ecx ;RUS: в стеке лежит кол-во блоков ;ENG: stack top contains number of blocks
mov dl, [ebx + EXT2_DIR_STRUC.name] ;RUS: в dl - первый символ () ;ENG: ???
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode]
mov ebx, [ebp+EXTFS.ext2_save_inode]
call ext2_get_inode
mov ebp, ebx
mov esi, ebx
xor eax, eax
ret
ret 4
 
.error_get_inode_block:
.error_get_block:
1175,30 → 1259,35
pop ebx
.error_empty_root:
mov eax, ERROR_FS_FAIL
ret
ret 4
 
;----------------------------------------------------------------
;ext2_HdGetFileInfo - read file info from block device
;
;in: esi points to filename
; edx mem location to return data
;--------------------------------------------------------------
ext2_HdGetFileInfo:
xchg bx, bx
; ext2_GetFileInfo - EXT2 implementation of getting file info
; in: ebp = pointer to EXTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ext2_GetFileInfo:
call ext2_lock
mov edx, [ebx+16]
cmp byte [esi], 0
jz .is_root
 
push edx
call ext2_find_lfn
stdcall ext2_find_lfn, [esp+4+4]
mov ebx, edx
pop edx
test eax, eax
jz @F
push eax
call ext2_unlock
pop eax
ret
 
.is_root:
xor ebx, ebx ;RUS: root не может быть скрытым ;ENG: root cannot be hidden
mov ebp, [ext2_data.root_inode]
mov esi, [ebp+EXTFS.root_inode]
@@:
xor eax, eax
mov edi, edx
1210,10 → 1299,10
or dword [edx], FS_FT_HIDDEN
@@:
 
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
test [esi + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jnz @F
mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size
mov ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ;high size
mov eax, [esi + EXT2_INODE_STRUC.i_size] ;low size
mov ebx, [esi + EXT2_INODE_STRUC.i_dir_acl] ;high size
mov dword [edx+32], eax
mov dword [edx+36], ebx
xor dword [edx], FS_FT_DIR
1221,33 → 1310,34
xor dword [edx], FS_FT_DIR
 
lea edi, [edx + 8]
mov eax, [ebp + EXT2_INODE_STRUC.i_ctime]
mov eax, [esi + EXT2_INODE_STRUC.i_ctime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebp + EXT2_INODE_STRUC.i_atime]
mov eax, [esi + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebp + EXT2_INODE_STRUC.i_mtime]
mov eax, [esi + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
call ext2_unlock
xor eax, eax
ret
 
ext2_HdRewrite:
ext2_HdWrite:
ext2_HdSetFileEnd:
ext2_HdSetFileInfo:
ext2_HdDelete:
ext2_HdCreateFolder:
ext2_Rewrite:
ext2_Write:
ext2_SetFileEnd:
ext2_SetFileInfo:
ext2_Delete:
ext2_CreateFolder:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
/kernel/branches/Kolibri-acpi/fs/fat12.inc
221,7 → 221,7
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
354,7 → 354,6
mov [FDD_Track], 0; Цилиндр
mov [FDD_Head], 0; Сторона
mov [FDD_Sector], 1; Сектор
call SetUserInterrupts
call FDDMotorON
call RecalibrateFDD
cmp [FDC_Status], 0
409,7 → 408,6
cmp [FDD_Sector], 16
jne save_flp_root_1
unnecessary_root_save:
mov [fdc_irq_func], fdc_null
popa
ret
 
445,7 → 443,6
jne unnecessary_flp_fat_save
mov [root_read], 0
unnecessary_flp_fat_save:
mov [fdc_irq_func], fdc_null
popa
ret
 
1703,7 → 1700,7
; 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
1794,7 → 1791,6
and dword [esp], 0
jmp .write_loop
.done:
mov [fdc_irq_func], fdc_null
jmp .ret
 
floppy_extend_file.zero_size:
1948,7 → 1944,6
mov al, 11
@@:
.doret:
mov [fdc_irq_func], fdc_null
ret
.expand:
push ecx
1981,7 → 1976,6
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:
2074,7 → 2068,7
add eax, 31
and edi, 0x1FF
jz .truncate_done
call SetUserInterrupts
 
pusha
call read_chs_sector
popa
/kernel/branches/Kolibri-acpi/fs/fat32.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; FAT32.INC ;;
58,8 → 58,7
PUSHAD_EDI equ [esp+0]
 
; Internal data for every FAT partition.
struct FAT
p PARTITION ; must be the first item
struct FAT PARTITION
fs_type db ?
fat16_root db 0 ; flag for fat16 rootdir
fat_change db 0 ; 1=fat has changed
121,6 → 120,7
iglobal
align 4
fat_user_functions:
dd free
dd (fat_user_functions_end - fat_user_functions - 4) / 4
dd fat_Read
dd fat_ReadFolder
138,10 → 138,8
; these labels are located before the main function to make
; most of jumps to these be short
fat_create_partition.free_return0:
push ebx
mov eax, ebp
call free
pop ebx
pop ebp
fat_create_partition.return0:
xor eax, eax
148,7 → 146,7
ret
fat_create_partition:
; bootsector must have been successfully read
cmp dword [esp+4], 1
cmp dword [esp+4], 0
jnz .return0
; bootsector signature must be correct
cmp word [ebx+0x1fe], 0xaa55
170,16 → 168,17
call malloc
test eax, eax
jz .return0
mov ecx, [ebp+8]
mov dword [eax+FAT.p.FirstSector], ecx
mov ecx, [ebp+12]
mov dword [eax+FAT.p.FirstSector+4], ecx
mov ecx, [ebp+16]
mov dword [eax+FAT.p.Length], ecx
mov ecx, [ebp+20]
mov dword [eax+FAT.p.Length+4], ecx
mov [eax+FAT.p.Disk], esi
mov [eax+FAT.p.FSUserFunctions], fat_user_functions
mov ecx, dword [ebp+PARTITION.FirstSector]
mov dword [eax+FAT.FirstSector], ecx
mov ecx, dword [ebp+PARTITION.FirstSector+4]
mov dword [eax+FAT.FirstSector+4], ecx
mov ecx, dword [ebp+PARTITION.Length]
mov dword [eax+FAT.Length], ecx
mov ecx, dword [ebp+PARTITION.Length+4]
mov dword [eax+FAT.Length+4], ecx
mov ecx, [ebp+PARTITION.Disk]
mov [eax+FAT.Disk], ecx
mov [eax+FAT.FSUserFunctions], fat_user_functions
or [eax+FAT.fat_in_cache], -1
mov [eax+FAT.fat_change], 0
push ebp
226,8 → 225,8
jnz @f
mov eax, [ebx+0x20] ; total sector count
@@:
mov dword [ebp+FAT.p.Length], eax
and dword [ebp+FAT.p.Length+4], 0
mov dword [ebp+FAT.Length], eax
and dword [ebp+FAT.Length+4], 0
sub eax, [ebp+FAT.DATA_START] ; eax = count of data sectors
xor edx, edx
div [ebp+FAT.SECTORS_PER_CLUSTER]
262,7 → 261,6
mov [ebp+FAT.fatEND], 0x0FFFFFF8
mov [ebp+FAT.fatMASK], 0x0FFFFFFF
mov al, 32
mov [fs_type], al
mov [ebp+FAT.fs_type], al
mov eax, ebp
pop ebp
274,7 → 272,6
mov [ebp+FAT.fatEND], 0x0000FFF8
mov [ebp+FAT.fatMASK], 0x0000FFFF
mov al, 16
mov [fs_type], al
mov [ebp+FAT.fs_type], al
mov eax, ebp
pop ebp
769,42 → 766,6
ret 4
 
;----------------------------------------------------------------
;
; fs_HdRead - LFN variant for reading hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_HdRead:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdRead
cmp [fs_type], 2
jz ext2_HdRead
or ebx, -1
mov eax, ERROR_UNKNOWN_FS
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_Read
pop ebp
ret
 
;----------------------------------------------------------------
; fat_Read - FAT16/32 implementation of reading a file
; in: ebp = pointer to FAT structure
; in: esi+[esp+4] = name
944,43 → 905,6
jmp .reteof
 
;----------------------------------------------------------------
;
; fs_HdReadFolder - LFN variant for reading hard disk folder
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; 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], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdReadFolder
cmp [fs_type], 2
jz ext2_HdReadFolder
movi eax, ERROR_UNSUPPORTED_FS
or ebx, -1
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_ReadFolder
pop ebp
ret
 
;----------------------------------------------------------------
; fat_ReadFolder - FAT16/32 implementation of reading a folder
; in: ebp = pointer to FAT structure
; in: esi+[esp+4] = name
1377,52 → 1301,6
pop ecx
ret
 
;----------------------------------------------------------------
;
; fs_HdRewrite - LFN variant for writing hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; 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
;
;--------------------------------------------------------------
fs_HdCreateFolder:
mov al, 1
jmp fs_HdRewrite.common
 
fs_HdRewrite:
xor eax, eax
.common:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdRewrite
cmp [fs_type], 2
jz ext2_HdRewrite
mov eax, ERROR_UNKNOWN_FS
xor ebx, ebx
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
test eax, eax
mov eax, fat_CreateFolder
jnz @f
mov eax, fat_Rewrite
@@:
call eax
pop ebp
ret
 
fshrad:
call fat_unlock
mov eax, ERROR_ACCESS_DENIED
1441,7 → 1319,7
jmp fat_Rewrite.common
 
;----------------------------------------------------------------
; fat_HdRewrite - FAT16/32 implementation of creating a new file
; fat_Rewrite - FAT16/32 implementation of creating a new file
; in: ebp = pointer to FAT structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
1988,52 → 1866,17
mov [edi-32+20], cx
jmp .writedircont
 
;----------------------------------------------------------------
;
; fs_HdWrite - LFN variant for writing to hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; 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
;
;--------------------------------------------------------------
fat_Write.access_denied:
push ERROR_ACCESS_DENIED
fs_HdWrite.ret0:
fat_Write.ret0:
pop eax
xor ebx, ebx
ret
 
fs_HdWrite.ret11:
fat_Write.ret11:
push ERROR_DEVICE
jmp fs_HdWrite.ret0
jmp fat_Write.ret0
 
fs_HdWrite:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdWrite
cmp [fs_type], 2
jz ext2_HdWrite
push ERROR_UNKNOWN_FS
jmp .ret0
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_Write
pop ebp
ret
 
;----------------------------------------------------------------
; fat_Write - FAT16/32 implementation of writing to file
; in: ebp = pointer to FAT structure
2051,7 → 1894,7
pop edi
push eax
call fat_unlock
jmp fs_HdWrite.ret0
jmp .ret0
.found:
; FAT does not support files larger than 4GB
cmp dword [ebx+8], 0
2060,7 → 1903,7
pop edi
push ERROR_END_OF_FILE
call fat_unlock
jmp fs_HdWrite.ret0
jmp .ret0
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
2362,39 → 2205,6
ret
 
;----------------------------------------------------------------
;
; fs_HdSetFileEnd - set end of file on hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; 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], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdSetFileEnd
cmp [fs_type], 2
jz ext2_HdSetFileEnd
movi eax, ERROR_UNKNOWN_FS
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_SetFileEnd
pop ebp
ret
 
;----------------------------------------------------------------
; fat_SetFileEnd - FAT16/32 implementation of setting end-of-file
; in: ebp = pointer to FAT structure
; in: esi+[esp+4] = name
2634,25 → 2444,6
movi eax, ERROR_FAT_TABLE
ret
 
fs_HdGetFileInfo:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdGetFileInfo
cmp [fs_type], 2
jz ext2_HdGetFileInfo
mov eax, ERROR_UNKNOWN_FS
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_GetFileInfo
pop ebp
ret
 
;----------------------------------------------------------------
; fat_GetFileInfo - FAT16/32 implementation of getting file info
; in: ebp = pointer to FAT structure
2687,25 → 2478,6
pop edi
ret
 
fs_HdSetFileInfo:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdSetFileInfo
cmp [fs_type], 2
jz ext2_HdSetFileInfo
mov eax, ERROR_UNKNOWN_FS
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_SetFileInfo
pop ebp
ret
 
;----------------------------------------------------------------
; fat_SetFileInfo - FAT16/32 implementation of setting file info
; in: ebp = pointer to FAT structure
2742,36 → 2514,6
ret
 
;----------------------------------------------------------------
;
; fs_HdDelete - delete file or empty folder from hard disk
;
; Obsolete, will be replaced with filesystem-specific functions.
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_HdDelete:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdDelete
cmp [fs_type], 2
jz ext2_HdDelete
movi eax, ERROR_UNKNOWN_FS
ret
@@:
sub ebx, 4
push ebp
mov ebp, [fs_dependent_data_start.partition]
call fat_Delete
pop ebp
ret
 
;----------------------------------------------------------------
; fat_Delete - FAT16/32 implementation of deleting a file/folder
; in: ebp = pointer to FAT structure
; in: esi+[esp+4] = name
/kernel/branches/Kolibri-acpi/fs/fs.inc
318,86 → 318,6
fs_noflpdisk:
;*****************************************************************
 
mov eax, [edi+1]
cmp eax, 'HD0 '
je fs_yesharddisk_IDE0
cmp eax, 'HD1 '
je fs_yesharddisk_IDE1
cmp eax, 'HD2 '
je fs_yesharddisk_IDE2
cmp eax, 'HD3 '
je fs_yesharddisk_IDE3
jmp old_path_harddisk
fs_yesharddisk_IDE0:
call reserve_hd1
mov [hdbase], 0x1f0
mov [hdid], 0x0
mov [hdpos], 1
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE1:
call reserve_hd1
mov [hdbase], 0x1f0
mov [hdid], 0x10
mov [hdpos], 2
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE2:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x0
mov [hdpos], 3
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE3:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x10
mov [hdpos], 4
fs_yesharddisk_partition:
call reserve_hd_channel
; call choice_necessity_partition
; jmp fs_yesharddisk_all
jmp fs_for_new_semantic
 
choice_necessity_partition:
mov eax, [edi+1+12]
call StringToNumber
mov [fat32part], eax
choice_necessity_partition_1:
mov ecx, [hdpos]
xor eax, eax
mov [hd_entries], eax; entries in hd cache
mov edx, DRIVE_DATA+2
cmp ecx, 0x80
jb search_partition_array
mov ecx, 4
search_partition_array:
mov bl, [edx]
movzx ebx, bl
add eax, ebx
inc edx
loop search_partition_array
mov ecx, [hdpos]
mov edx, BiosDiskPartitions
sub ecx, 0x80
jb .s
je .f
@@:
mov ebx, [edx]
add edx, 4
add eax, ebx
loop @b
jmp .f
.s:
sub eax, ebx
.f:
add eax, [known_part]; add eax,[fat32part]
dec eax
xor edx, edx
imul eax, 100
add eax, DRIVE_DATA+0xa
mov [transfer_adress], eax
call partition_data_transfer_1
ret
 
old_path_harddisk:
mov eax, [edi+1]
cmp eax, 'HD '
416,28 → 336,8
 
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
@@:
 
call free_hd_channel
and [hd1_status], 0
 
fs_noharddisk:
; \begin{diamond}[18.03.2006]
mov eax, 5 ; file not found
542,7 → 442,10
 
lbarl1:
 
call reserve_hd1
pushad
mov ecx, ide_mutex
call mutex_lock
popad
 
push eax
push ecx
633,6 → 536,10
mov [hd_error], 0
mov [hd1_status], 0
add esp, 2*4
pushad
mov ecx, ide_mutex
call mutex_unlock
popad
 
ret
 
/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc
42,18 → 42,6
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
76,14 → 64,6
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
97,7 → 77,6
dd 0
 
fs_additional_handlers:
dd biosdisk_handler, biosdisk_enum_root
dd dyndisk_handler, dyndisk_enum_root
; add new handlers here
dd 0
523,84 → 502,6
dd fs_FloppyCreateFolder
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
 
fs_OnHd0:
call reserve_hd1
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1F0
mov [hdid], 0
push 1
jmp fs_OnHd
fs_OnHd1:
call reserve_hd1
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1F0
mov [hdid], 0x10
push 2
jmp fs_OnHd
fs_OnHd2:
call reserve_hd1
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0
push 3
jmp fs_OnHd
fs_OnHd3:
call reserve_hd1
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10
push 4
fs_OnHd:
call reserve_hd_channel
pop eax
mov [hdpos], eax
cmp ecx, 0x100
jae fs_OnHdAndBd.nf
cmp cl, [DRIVE_DATA+1+eax]
fs_OnHdAndBd:
jbe @f
.nf:
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 5 ; not found
ret
@@:
mov [known_part], ecx ; mov [fat32part], ecx
push ebx esi
call choice_necessity_partition_1
pop esi ebx
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
mov eax, [ebx]
cmp eax, fs_NumHdServices
jae .not_impl
add ebx, 4
call dword [fs_HdServices + eax*4]
call free_hd_channel
and [hd1_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_HdServices:
dd fs_HdRead
dd fs_HdReadFolder
dd fs_HdRewrite
dd fs_HdWrite
dd fs_HdSetFileEnd
dd fs_HdGetFileInfo
dd fs_HdSetFileInfo
dd 0
dd fs_HdDelete
dd fs_HdCreateFolder
fs_NumHdServices = ($ - fs_HdServices)/4
 
;*******************************************************
fs_OnCd0:
call reserve_cd
691,22 → 592,6
cmp byte [DRIVE_DATA], 0
setnz al
ret
fs_HasHd0:
test byte [DRIVE_DATA+1], 01000000b
setnz al
ret
fs_HasHd1:
test byte [DRIVE_DATA+1], 00010000b
setnz al
ret
fs_HasHd2:
test byte [DRIVE_DATA+1], 00000100b
setnz al
ret
fs_HasHd3:
test byte [DRIVE_DATA+1], 00000001b
setnz al
ret
 
;*******************************************************
fs_HasCd0:
762,27 → 647,6
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
795,147 → 659,6
ret
;*******************************************************
 
; Additional FS handlers.
; This handler gets the control each time when fn 70 is called
; with unknown item of root subdirectory.
; in: esi -> name
; ebp = 0 or rest of name relative to esi
; out: if the handler processes path, he must not return in file_system_lfn,
; but instead pop return address and return directly to the caller
; otherwise simply return
 
; here we test for /bd<N>/... - BIOS disks
biosdisk_handler:
cmp [NumBiosDisks], 0
jz .ret
mov al, [esi]
or al, 20h
cmp al, 'b'
jnz .ret
mov al, [esi+1]
or al, 20h
cmp al, 'd'
jnz .ret
push esi
inc esi
inc esi
cmp byte [esi], '0'
jb .ret2
cmp byte [esi], '9'
ja .ret2
xor edx, edx
@@:
lodsb
test al, al
jz .ok
cmp al, '/'
jz .ok
sub al, '0'
cmp al, 9
ja .ret2
lea edx, [edx*5]
lea edx, [edx*2+eax]
jmp @b
.ret2:
pop esi
.ret:
ret
.ok:
cmp al, '/'
jz @f
dec esi
@@:
add dl, 80h
xor ecx, ecx
@@:
cmp dl, [BiosDisksData+ecx*4]
jz .ok2
inc ecx
cmp ecx, [NumBiosDisks]
jb @b
jmp .ret2
.ok2:
add esp, 8
test al, al
jnz @f
mov esi, fs_BdNext
jmp file_system_lfn.maindir_noesi
@@:
push ecx
push ecx
push biosdisk_cleanup
push fs_OnBd
mov edi, esp
jmp file_system_lfn.found2
 
fs_BdNext:
cmp eax, [BiosDiskPartitions+ecx*4]
inc eax
cmc
biosdisk_cleanup:
ret
 
fs_OnBd:
pop edx edx edx edx
; edx = disk number, ecx = partition number
; esi+ebp = name
call reserve_hd1
add edx, 0x80
mov [hdpos], edx
cmp ecx, [BiosDiskPartitions+(edx-0x80)*4]
jmp fs_OnHdAndBd
 
; This handler is called when virtual root is enumerated
; and must return all items which can be handled by this.
; It is called several times, first time with eax=0
; in: eax = 0 for first call, previously returned value for subsequent calls
; out: eax = 0 => no more items
; eax != 0 => buffer pointed to by edi contains name of item
 
; here we enumerate existing BIOS disks /bd<N>
biosdisk_enum_root:
cmp eax, [NumBiosDisks]
jae .end
push eax
movzx eax, byte [BiosDisksData+eax*4]
sub al, 80h
push eax
mov al, 'b'
stosb
mov al, 'd'
stosb
pop eax
cmp al, 10
jae .big
add al, '0'
stosb
mov byte [edi], 0
pop eax
inc eax
ret
.end:
xor eax, eax
ret
.big:
push ecx edx
push -'0'
mov ecx, 10
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
xchg eax, edx
@@:
pop eax
add al, '0'
stosb
jnz @b
pop edx ecx
pop eax
inc eax
ret
;-----------------------------------------------------------------------------
process_replace_file_name:
; in
/kernel/branches/Kolibri-acpi/fs/iso9660.inc
42,26 → 42,18
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_2
.reserve_ok_1:
pushad
mov ecx, ide_channel1_mutex
call mutex_lock
mov [IDE_Channel_1], 1
sti
popad
ret
.reserve_ok_2:
.IDE_Channel_2:
pushad
mov ecx, ide_channel2_mutex
call mutex_lock
mov [IDE_Channel_2], 1
sti
popad
ret
 
free_cd_channel:
69,11 → 61,17
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
sti
pushad
mov ecx, ide_channel1_mutex
call mutex_unlock
popad
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
sti
pushad
mov ecx, ide_channel2_mutex
call mutex_unlock
popad
ret
 
uglobal
/kernel/branches/Kolibri-acpi/fs/ntfs.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7,7 → 7,65
 
$Revision$
 
struct NTFS PARTITION
Lock MUTEX ? ; currently operations with one partition
; can not be executed in parallel since the
; legacy code is not ready; this mutex guards
; all operations
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 ?
 
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
 
cur_subnode_size dd ?
ntfs_attr_iRecord dd ?
ntfs_attr_iBaseRecord dd ?
ntfs_attr_offs dd ?
ntfs_attr_list dd ?
ntfs_attr_size dq ?
ntfs_cur_tail dd ?
 
ntfs_attrlist_buf rb 0x400
ntfs_attrlist_mft_buf rb 0x400
ntfs_bitmap_buf rb 0x400
ends
 
iglobal
align 4
ntfs_user_functions:
dd ntfs_free
dd (ntfs_user_functions_end - ntfs_user_functions - 4) / 4
dd ntfs_Read
dd ntfs_ReadFolder
dd ntfs_Rewrite
dd ntfs_Write
dd ntfs_SetFileEnd
dd ntfs_GetFileInfo
dd ntfs_SetFileInfo
dd 0
dd ntfs_Delete
dd ntfs_CreateFolder
ntfs_user_functions_end:
endg
 
ntfs_test_bootsec:
; in: ebx->buffer, edx=size of partition
; out: CF set <=> invalid
93,25 → 151,66
stc
ret
 
ntfs_setup: ; CODE XREF: part_set.inc
proc ntfs_create_partition
mov edx, dword [ebp+PARTITION.Length]
cmp dword [esp+4], 0
jz .boot_read_ok
add ebx, 512
lea eax, [edx-1]
call fs_read32_sys
test eax, eax
jnz @f
call ntfs_test_bootsec
jnc .ntfs_setup
@@:
mov eax, edx
shr eax, 1
call fs_read32_sys
test eax, eax
jnz .nope ; no chance...
.boot_read_ok:
call ntfs_test_bootsec
jnc .ntfs_setup
.nope:
xor eax, eax
jmp .exit
 
.ntfs_setup:
; By given bootsector, initialize some NTFS variables
; call ntfs_test_bootsec ; checking boot sector was already
; jc problem_fat_dec_count
movi eax, sizeof.NTFS
call malloc
test eax, eax
jz .exit
mov ecx, dword [ebp+PARTITION.FirstSector]
mov dword [eax+NTFS.FirstSector], ecx
mov ecx, dword [ebp+PARTITION.FirstSector+4]
mov dword [eax+NTFS.FirstSector+4], ecx
mov ecx, dword [ebp+PARTITION.Length]
mov dword [eax+NTFS.Length], ecx
mov ecx, dword [ebp+PARTITION.Length+4]
mov dword [eax+NTFS.Length+4], ecx
mov ecx, [ebp+PARTITION.Disk]
mov [eax+NTFS.Disk], ecx
mov [eax+NTFS.FSUserFunctions], ntfs_user_functions
push ebx ebp esi
mov ebp, eax
 
lea ecx, [ebp+NTFS.Lock]
call mutex_init
 
movzx eax, byte [ebx+13]
mov [ntfs_data.sectors_per_cluster], eax
mov [ebp+NTFS.sectors_per_cluster], eax
mov eax, [ebx+0x28]
add eax, [PARTITION_START]
dec eax
mov [PARTITION_END], eax
mov [fs_type], 1
mov dword [ebp+NTFS.Length], eax
and dword [ebp+NTFS.Length+4], 0
mov eax, [ebx+0x30]
mov [ntfs_data.mft_cluster], eax
mov [ebp+NTFS.mft_cluster], eax
mov eax, [ebx+0x38]
mov [ntfs_data.mftmirr_cluster], eax
mov [ebp+NTFS.mftmirr_cluster], eax
movsx eax, byte [ebx+0x40]
test eax, eax
js .1
mul [ntfs_data.sectors_per_cluster]
mul [ebp+NTFS.sectors_per_cluster]
shl eax, 9
jmp .2
.1:
120,11 → 219,11
mov eax, 1
shl eax, cl
.2:
mov [ntfs_data.frs_size], eax
mov [ebp+NTFS.frs_size], eax
movsx eax, byte [ebx+0x44]
test eax, eax
js .3
mul [ntfs_data.sectors_per_cluster]
mul [ebp+NTFS.sectors_per_cluster]
shl eax, 9
jmp .4
.3:
133,21 → 232,21
mov eax, 1
shl eax, cl
.4:
mov [ntfs_data.iab_size], eax
mov [ebp+NTFS.iab_size], eax
; allocate space for buffers
add eax, [ntfs_data.frs_size]
add eax, [ebp+NTFS.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
jz .fail_free
mov [ebp+NTFS.frs_buffer], eax
add eax, [ebp+NTFS.frs_size]
mov [ebp+NTFS.iab_buffer], eax
; read $MFT disposition
mov eax, [ntfs_data.mft_cluster]
mul [ntfs_data.sectors_per_cluster]
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
call ntfs_read_frs_sector
cmp [hd_error], 0
test eax, eax
jnz .usemirr
cmp dword [ebx], 'FILE'
jnz .usemirr
154,11 → 253,10
call ntfs_restore_usa_frs
jnc .mftok
.usemirr:
and [hd_error], 0
mov eax, [ntfs_data.mftmirr_cluster]
mul [ntfs_data.sectors_per_cluster]
mov eax, [ebp+NTFS.mftmirr_cluster]
mul [ebp+NTFS.sectors_per_cluster]
call ntfs_read_frs_sector
cmp [hd_error], 0
test eax, eax
jnz @f
cmp dword [ebx], 'FILE'
jnz @f
167,11 → 265,22
@@:
; $MFT and $MFTMirr invalid!
.fail_free_frs:
push [ntfs_data.frs_buffer]
push [ebp+NTFS.frs_buffer]
call kernel_free
jmp problem_fat_dec_count
.fail_free:
mov eax, ebp
call free
xor eax, eax
.pop_exit:
pop esi ebp ebx
.exit:
cmp dword [esp+4], 0
jz @f
sub ebx, 512
@@:
ret
.fail_free_mft:
push [ntfs_data.mft_retrieval]
push [ebp+NTFS.mft_retrieval]
call kernel_free
jmp .fail_free_frs
.mftok:
183,9 → 292,9
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
mov [ebp+NTFS.mft_retrieval], eax
and [ebp+NTFS.mft_retrieval_size], 0
mov [ebp+NTFS.mft_retrieval_alloc], 0x1000/8
; $MFT base record must contain unnamed non-resident $DATA attribute
movzx eax, word [ebx+14h]
add eax, ebx
204,7 → 313,7
jz .fail_free_mft
; load first portion of $DATA attribute retrieval information
mov edx, [eax+0x18]
mov [ntfs_data.mft_retrieval_end], edx
mov [ebp+NTFS.mft_retrieval_end], edx
mov esi, eax
movzx eax, word [eax+0x20]
add esi, eax
217,7 → 326,7
mov [eax], edx
mov edx, [esp+8] ; block addr (relative)
mov [eax+4], edx
inc [ntfs_data.mft_retrieval_size]
inc [ebp+NTFS.mft_retrieval_size]
jmp .scanmcb
.scanmcbend:
add esp, 10h
224,25 → 333,24
; 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
mov [ebp+NTFS.cur_index_size], 0x1000/0x200
push 0x1000
call kernel_alloc
test eax, eax
jz .fail_free_mft
mov [ntfs_data.cur_index_buf], eax
mov [ebp+NTFS.cur_index_buf], eax
 
popad
call free_hd_channel
and [hd1_status], 0
ret
mov eax, ebp
jmp .pop_exit
endp
 
.get_mft_retrieval_ptr:
pushad
mov eax, [ntfs_data.mft_retrieval_size]
cmp eax, [ntfs_data.mft_retrieval_alloc]
mov eax, [ebp+NTFS.mft_retrieval_size]
cmp eax, [ebp+NTFS.mft_retrieval_alloc]
jnz .ok
add eax, 0x1000/8
mov [ntfs_data.mft_retrieval_alloc], eax
mov [ebp+NTFS.mft_retrieval_alloc], eax
shl eax, 3
push eax
call kernel_alloc
252,83 → 360,88
add esp, 14h
jmp .fail_free_mft
@@:
mov esi, [ntfs_data.mft_retrieval]
mov esi, [ebp+NTFS.mft_retrieval]
mov edi, eax
mov ecx, [ntfs_data.mft_retrieval_size]
mov ecx, [ebp+NTFS.mft_retrieval_size]
add ecx, ecx
rep movsd
push [ntfs_data.mft_retrieval]
mov [ntfs_data.mft_retrieval], eax
push [ebp+NTFS.mft_retrieval]
mov [ebp+NTFS.mft_retrieval], eax
call kernel_free
mov eax, [ntfs_data.mft_retrieval_size]
mov eax, [ebp+NTFS.mft_retrieval_size]
.ok:
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
add eax, [ebp+NTFS.mft_retrieval]
mov [esp+28], eax
popad
ret
 
proc ntfs_free
push ebx
xchg ebx, eax
stdcall kernel_free, [ebx+NTFS.frs_buffer]
stdcall kernel_free, [ebx+NTFS.mft_retrieval]
stdcall kernel_free, [ebx+NTFS.cur_index_buf]
xchg ebx, eax
call free
pop ebx
ret
endp
 
proc ntfs_lock
lea ecx, [ebp+NTFS.Lock]
jmp mutex_lock
endp
 
proc ntfs_unlock
lea ecx, [ebp+NTFS.Lock]
jmp mutex_unlock
endp
 
ntfs_read_frs_sector:
push eax ecx
add eax, [PARTITION_START]
mov ecx, [ntfs_data.frs_size]
push ecx
mov ebx, [ebp+NTFS.frs_buffer]
push ebx
mov ecx, [ebp+NTFS.frs_size]
shr ecx, 9
mov ebx, [ntfs_data.frs_buffer]
push ebx
push ecx
mov ecx, eax
@@:
call hd_read
cmp [hd_error], 0
mov eax, ecx
call fs_read32_sys
test eax, eax
jnz .fail
add ebx, 0x200
inc eax
loop @b
inc ecx
dec dword [esp]
jnz @b
pop eax
.fail:
pop ebx
pop ecx eax
pop ecx
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]
; in: variables in ebp+NTFS.*
; out: [ebp+NTFS.ntfs_cur_read]
; out: CF=1 => notfound, in this case eax=0 => disk ok, otherwise eax=disk error code
xor eax, eax
pushad
and [ntfs_cur_read], 0
cmp [ntfs_cur_iRecord], 0
and [ebp+NTFS.ntfs_cur_read], 0
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz .nomft
cmp [ntfs_cur_attr], 0x80
cmp [ebp+NTFS.ntfs_cur_attr], 0x80
jnz .nomft
mov eax, [ntfs_data.mft_retrieval_end]
mov eax, [ebp+NTFS.mft_retrieval_end]
inc eax
mul [ntfs_data.sectors_per_cluster]
cmp eax, [ntfs_cur_offs]
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfs_cur_offs]
jbe .nomft
; precalculated part of $Mft $DATA
mov esi, [ntfs_data.mft_retrieval]
mov eax, [ntfs_cur_offs]
mov esi, [ebp+NTFS.mft_retrieval]
mov eax, [ebp+NTFS.ntfs_cur_offs]
xor edx, edx
div [ntfs_data.sectors_per_cluster]
div [ebp+NTFS.sectors_per_cluster]
; eax = VCN, edx = offset in sectors from beginning of cluster
xor ecx, ecx ; ecx will contain LCN
.mftscan:
337,9 → 450,9
jb @f
add esi, 8
push eax
mov eax, [ntfs_data.mft_retrieval_end]
mov eax, [ebp+NTFS.mft_retrieval_end]
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
add eax, [ebp+NTFS.mft_retrieval]
cmp eax, esi
pop eax
jnz .mftscan
350,42 → 463,43
add ecx, [esi]
push eax
push edx
mov eax, [ntfs_data.sectors_per_cluster]
mov eax, [ebp+NTFS.sectors_per_cluster]
mul ecx
; eax = sector on partition
add eax, [PARTITION_START]
pop edx
add eax, edx
mov ebx, [ntfs_cur_buf]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
pop ecx
neg ecx
imul ecx, [ntfs_data.sectors_per_cluster]
imul ecx, [ebp+NTFS.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ntfs_cur_size]
cmp ecx, [ebp+NTFS.ntfs_cur_size]
jb @f
mov ecx, [ntfs_cur_size]
mov ecx, [ebp+NTFS.ntfs_cur_size]
@@:
; ecx = number of sequential sectors to read
call hd_read
cmp [hd_error], 0
push eax
call fs_read32_sys
pop edx
test eax, eax
jnz .errread
add [ntfs_cur_read], 0x200
dec [ntfs_cur_size]
inc [ntfs_cur_offs]
add [ebp+NTFS.ntfs_cur_read], 0x200
dec [ebp+NTFS.ntfs_cur_size]
inc [ebp+NTFS.ntfs_cur_offs]
add ebx, 0x200
mov [ntfs_cur_buf], ebx
inc eax
mov [ebp+NTFS.ntfs_cur_buf], ebx
lea eax, [edx+1]
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ntfs_cur_size], eax
cmp [ebp+NTFS.ntfs_cur_size], eax
jz @f
add esi, 8
push eax
mov eax, [ntfs_data.mft_retrieval_end]
mov eax, [ebp+NTFS.mft_retrieval_end]
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
add eax, [ebp+NTFS.mft_retrieval]
cmp eax, esi
pop eax
jz .nomft
396,6 → 510,7
.errread:
pop ecx
.errret:
mov [esp+28], eax
stc
popad
ret
402,17 → 517,16
.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
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov [ebp+NTFS.ntfs_attr_iRecord], eax
and [ebp+NTFS.ntfs_attr_list], 0
or dword [ebp+NTFS.ntfs_attr_size], -1
or dword [ebp+NTFS.ntfs_attr_size+4], -1
or [ebp+NTFS.ntfs_attr_iBaseRecord], -1
call ntfs_read_file_record
test eax, eax
jz .errret
jc .errret
; 2. Find required attribute.
mov eax, [ntfs_data.frs_buffer]
mov eax, [ebp+NTFS.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
422,27 → 536,26
; test eax, eax
; jz @f
.beginfindattr:
mov [ntfs_attr_iRecord], eax
mov [ebp+NTFS.ntfs_attr_iRecord], eax
call ntfs_read_file_record
test eax, eax
jz .errret
jc .errret
@@:
; b) Scan for required attribute and for $ATTR_LIST
mov eax, [ntfs_data.frs_buffer]
mov eax, [ebp+NTFS.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ntfs_cur_attr]
and [ntfs_attr_offs], 0
mov ecx, [ebp+NTFS.ntfs_cur_attr]
and [ebp+NTFS.ntfs_attr_offs], 0
.scanattr:
cmp dword [eax], -1
jz .scandone
cmp dword [eax], ecx
jz .okattr
cmp [ntfs_attr_iBaseRecord], -1
cmp [ebp+NTFS.ntfs_attr_iBaseRecord], -1
jnz .scancont
cmp dword [eax], 0x20 ; $ATTR_LIST
jnz .scancont
mov [ntfs_attr_list], eax
mov [ebp+NTFS.ntfs_attr_list], eax
jmp .scancont
.okattr:
; ignore named $DATA attributes (aka NTFS streams)
451,30 → 564,30
cmp byte [eax+9], 0
jnz .scancont
@@:
mov [ntfs_attr_offs], eax
mov [ebp+NTFS.ntfs_attr_offs], eax
.scancont:
add eax, [eax+4]
jmp .scanattr
.continue:
pushad
and [ntfs_cur_read], 0
and [ebp+NTFS.ntfs_cur_read], 0
.scandone:
; c) Check for required offset and length
mov ecx, [ntfs_attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
jecxz .noattr
push [ntfs_cur_size]
push [ntfs_cur_read]
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_read]
call .doreadattr
pop edx
pop eax
pop ecx
jc @f
cmp [ntfs_bCanContinue], 0
cmp [ebp+NTFS.ntfs_bCanContinue], 0
jz @f
sub edx, [ntfs_cur_read]
sub edx, [ebp+NTFS.ntfs_cur_read]
neg edx
shr edx, 9
sub eax, edx
mov [ntfs_cur_size], eax
sub ecx, edx
mov [ebp+NTFS.ntfs_cur_size], ecx
jnz .not_in_cur
@@:
popad
481,13 → 594,14
ret
.noattr:
.not_in_cur:
cmp [ntfs_cur_attr], 0x20
cmp [ebp+NTFS.ntfs_cur_attr], 0x20
jz @f
mov ecx, [ntfs_attr_list]
mov ecx, [ebp+NTFS.ntfs_attr_list]
test ecx, ecx
jnz .lookattr
.ret_is_attr:
cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0
and dword [esp+28], 0
cmp [ebp+NTFS.ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0
popad
ret
.lookattr:
494,49 → 608,49
; 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]
mov eax, [ebp+NTFS.ntfs_attr_iBaseRecord]
cmp eax, -1
jz @f
call ntfs_read_file_record
test eax, eax
jz .errret
or [ntfs_attr_iBaseRecord], -1
jc .errret
or [ebp+NTFS.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
push [ebp+NTFS.ntfs_cur_offs]
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_read]
push [ebp+NTFS.ntfs_cur_buf]
push dword [ebp+NTFS.ntfs_attr_size]
push dword [ebp+NTFS.ntfs_attr_size+4]
or dword [ebp+NTFS.ntfs_attr_size], -1
or dword [ebp+NTFS.ntfs_attr_size+4], -1
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 2
and [ebp+NTFS.ntfs_cur_read], 0
lea eax, [ebp+NTFS.ntfs_attrlist_buf]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz @f
mov eax, ntfs_attrlist_mft_buf
lea eax, [ebp+NTFS.ntfs_attrlist_mft_buf]
@@:
mov [ntfs_cur_buf], eax
mov [ebp+NTFS.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]
pop dword [ebp+NTFS.ntfs_attr_size+4]
pop dword [ebp+NTFS.ntfs_attr_size]
mov ecx, [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_buf]
pop [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_size]
pop [ebp+NTFS.ntfs_cur_offs]
jc .errret
or edi, -1
lea ebp, [ebp+esi-1Ah]
lea ecx, [ecx+esi-1Ah]
.scanliststart:
mov eax, [ntfs_cur_attr]
push ecx
mov eax, [ebp+NTFS.ntfs_cur_attr]
.scanlist:
cmp esi, ebp
cmp esi, [esp]
jae .scanlistdone
cmp eax, [esi]
jz @f
555,26 → 669,28
mov eax, [esi+8]
test eax, eax
jnz .testf
mov eax, dword [ntfs_attr_size]
and eax, dword [ntfs_attr_size+4]
mov eax, dword [ebp+NTFS.ntfs_attr_size]
and eax, dword [ebp+NTFS.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
jnc @f
.errret_pop:
pop eax
pop ecx ecx
jmp .errret
.errret2_pop:
xor eax, eax
jmp .errret_pop
@@:
mov eax, [ntfs_data.frs_buffer]
mov eax, [ebp+NTFS.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ntfs_cur_attr]
mov ecx, [ebp+NTFS.ntfs_cur_attr]
@@:
cmp dword [eax], -1
jz .errret_pop
jz .errret2_pop
cmp dword [eax], ecx
jz @f
.l1:
589,24 → 705,25
cmp byte [eax+8], 0
jnz .sdnores
mov eax, [eax+10h]
mov dword [ntfs_attr_size], eax
and dword [ntfs_attr_size+4], 0
mov dword [ebp+NTFS.ntfs_attr_size], eax
and dword [ebp+NTFS.ntfs_attr_size+4], 0
jmp .testfz
.sdnores:
mov ecx, [eax+30h]
mov dword [ntfs_attr_size], ecx
mov dword [ebp+NTFS.ntfs_attr_size], ecx
mov ecx, [eax+34h]
mov dword [ntfs_attr_size+4], ecx
mov dword [ebp+NTFS.ntfs_attr_size+4], ecx
.testfz:
xor eax, eax
.testf:
imul eax, [ntfs_data.sectors_per_cluster]
cmp eax, [ntfs_cur_offs]
imul eax, [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfs_cur_offs]
pop eax
ja @f
mov edi, [esi+10h] ; keep previous iRecord
jmp .scanlistcont
@@:
pop ecx
.scanlistfound:
cmp edi, -1
jnz @f
613,30 → 730,28
popad
ret
@@:
mov eax, [ntfs_cur_iRecord]
mov [ntfs_attr_iBaseRecord], eax
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov [ebp+NTFS.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
pop ecx
sub ecx, ebp
sub ecx, NTFS.ntfs_attrlist_buf-1Ah
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz @f
sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf
sub ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
@@:
cmp ebp, 0x400
cmp ecx, 0x400
jnz .scanlistfound
inc edx
push esi edi
mov esi, ntfs_attrlist_buf+0x200
mov edi, ntfs_attrlist_buf
cmp [ntfs_cur_iRecord], 0
lea esi, [ebp+NTFS.ntfs_attrlist_buf+0x200]
lea edi, [ebp+NTFS.ntfs_attrlist_buf]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz @f
mov esi, ntfs_attrlist_mft_buf+0x200
mov edi, ntfs_attrlist_mft_buf
lea esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200]
lea edi, [ebp+NTFS.ntfs_attrlist_mft_buf]
@@:
mov ecx, 0x200/4
rep movsd
643,43 → 758,43
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
push [ebp+NTFS.ntfs_cur_offs]
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_read]
push [ebp+NTFS.ntfs_cur_buf]
push dword [ebp+NTFS.ntfs_attr_size]
push dword [ebp+NTFS.ntfs_attr_size+4]
or dword [ebp+NTFS.ntfs_attr_size], -1
or dword [ebp+NTFS.ntfs_attr_size+4], -1
mov [ebp+NTFS.ntfs_cur_offs], edx
mov [ebp+NTFS.ntfs_cur_size], 1
and [ebp+NTFS.ntfs_cur_read], 0
mov [ebp+NTFS.ntfs_cur_buf], eax
mov ecx, [ebp+NTFS.ntfs_attr_list]
push esi edx edi
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]
pop edi edx esi
mov ecx, [ebp+NTFS.ntfs_cur_read]
pop dword [ebp+NTFS.ntfs_attr_size+4]
pop dword [ebp+NTFS.ntfs_attr_size]
pop [ebp+NTFS.ntfs_cur_buf]
pop [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_size]
pop [ebp+NTFS.ntfs_cur_offs]
jc .errret
add ebp, ntfs_attrlist_buf+0x200-0x1A
cmp [ntfs_cur_iRecord], 0
lea ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz .scanliststart
add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf
add ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
jmp .scanliststart
 
.doreadattr:
mov [ntfs_bCanContinue], 0
mov [ebp+NTFS.ntfs_bCanContinue], 0
cmp byte [ecx+8], 0
jnz .nonresident
mov eax, [ecx+10h] ; length
mov esi, eax
mov edx, [ntfs_cur_offs]
mov edx, [ebp+NTFS.ntfs_cur_offs]
shr eax, 9
cmp eax, edx
jb .okret
688,7 → 803,7
movzx eax, word [ecx+14h]
add edx, eax
add edx, ecx ; edx -> data
mov eax, [ntfs_cur_size]
mov eax, [ebp+NTFS.ntfs_cur_size]
cmp eax, (0xFFFFFFFF shr 9)+1
jbe @f
mov eax, (0xFFFFFFFF shr 9)+1
699,17 → 814,17
mov eax, esi
@@:
; eax = length, edx -> data
mov [ntfs_cur_read], eax
mov [ebp+NTFS.ntfs_cur_read], eax
mov ecx, eax
mov eax, edx
mov ebx, [ntfs_cur_buf]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
call memmove
and [ntfs_cur_size], 0 ; CF=0
and [ebp+NTFS.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]
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov edx, dword [ebp+NTFS.ntfs_attr_size+4]
push eax
and eax, edx
cmp eax, -1
717,34 → 832,34
jnz @f
mov eax, [ecx+30h] ; FileSize
mov edx, [ecx+34h]
mov dword [ntfs_attr_size], eax
mov dword [ntfs_attr_size+4], edx
mov dword [ebp+NTFS.ntfs_attr_size], eax
mov dword [ebp+NTFS.ntfs_attr_size+4], edx
@@:
add eax, 0x1FF
adc edx, 0
shrd eax, edx, 9
sub eax, [ntfs_cur_offs]
sub eax, [ebp+NTFS.ntfs_cur_offs]
ja @f
; return with nothing read
and [ntfs_cur_size], 0
and [ebp+NTFS.ntfs_cur_size], 0
.okret:
clc
ret
@@:
; reduce read length
and [ntfs_cur_tail], 0
cmp [ntfs_cur_size], eax
and [ebp+NTFS.ntfs_cur_tail], 0
cmp [ebp+NTFS.ntfs_cur_size], eax
jb @f
mov [ntfs_cur_size], eax
mov eax, dword [ntfs_attr_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, dword [ebp+NTFS.ntfs_attr_size]
and eax, 0x1FF
mov [ntfs_cur_tail], eax
mov [ebp+NTFS.ntfs_cur_tail], eax
@@:
cmp [ntfs_cur_size], 0
cmp [ebp+NTFS.ntfs_cur_size], 0
jz .okret
mov eax, [ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_offs]
xor edx, edx
div [ntfs_data.sectors_per_cluster]
div [ebp+NTFS.sectors_per_cluster]
sub eax, [ecx+10h] ; first_vbo
jb .okret
; eax = cluster, edx = starting sector
751,51 → 866,60
sub esp, 10h
movzx esi, word [ecx+20h] ; mcb_info_ofs
add esi, ecx
xor ebp, ebp
xor edi, edi
.readloop:
call ntfs_decode_mcb_entry
jnc .break
add ebp, [esp+8]
add edi, [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, edi
imul eax, [ebp+NTFS.sectors_per_cluster]
add eax, edx
add eax, [PARTITION_START]
pop ecx
neg ecx
imul ecx, [ntfs_data.sectors_per_cluster]
imul ecx, [ebp+NTFS.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ntfs_cur_size]
cmp ecx, [ebp+NTFS.ntfs_cur_size]
jb @f
mov ecx, [ntfs_cur_size]
mov ecx, [ebp+NTFS.ntfs_cur_size]
@@:
mov ebx, [ntfs_cur_buf]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
@@:
call hd_read
cmp [hd_error], 0
push eax
cmp [ebp+NTFS.ntfs_cur_attr], 0x80
jnz .sys
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jz .sys
call fs_read32_app
jmp .appsys
.sys:
call fs_read32_sys
.appsys:
pop edx
test eax, eax
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]
mov [ebp+NTFS.ntfs_cur_buf], ebx
lea eax, [edx+1]
add [ebp+NTFS.ntfs_cur_read], 0x200
dec [ebp+NTFS.ntfs_cur_size]
inc [ebp+NTFS.ntfs_cur_offs]
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ntfs_cur_size], 0
cmp [ebp+NTFS.ntfs_cur_size], 0
jnz .readloop
add esp, 10h
mov eax, [ntfs_cur_tail]
mov eax, [ebp+NTFS.ntfs_cur_tail]
test eax, eax
jz @f
sub eax, 0x200
add [ntfs_cur_read], eax
add [ebp+NTFS.ntfs_cur_read], eax
@@:
clc
ret
806,58 → 930,57
ret
.break:
add esp, 10h ; CF=0
mov [ntfs_bCanContinue], 1
mov [ebp+NTFS.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]
; out: [ebp+NTFS.frs_buffer] contains information
; CF=1 - failed, in this case eax=0 => something with FS, eax nonzero => disk error
; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size]
push ecx edx
mov ecx, [ntfs_data.frs_size]
mov ecx, [ebp+NTFS.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
jnz .errret
push [ebp+NTFS.ntfs_attr_iRecord]
push [ebp+NTFS.ntfs_attr_iBaseRecord]
push [ebp+NTFS.ntfs_attr_offs]
push [ebp+NTFS.ntfs_attr_list]
push dword [ebp+NTFS.ntfs_attr_size+4]
push dword [ebp+NTFS.ntfs_attr_size]
push [ebp+NTFS.ntfs_cur_iRecord]
push [ebp+NTFS.ntfs_cur_attr]
push [ebp+NTFS.ntfs_cur_offs]
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_buf]
push [ebp+NTFS.ntfs_cur_read]
mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA
and [ebp+NTFS.ntfs_cur_iRecord], 0 ; $Mft
mov [ebp+NTFS.ntfs_cur_offs], eax
shr ecx, 9
mov [ntfs_cur_size], ecx
mov eax, [ntfs_data.frs_buffer]
mov [ntfs_cur_buf], eax
mov [ebp+NTFS.ntfs_cur_size], ecx
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.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]
mov edx, [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_buf]
pop [ebp+NTFS.ntfs_cur_size]
pop [ebp+NTFS.ntfs_cur_offs]
pop [ebp+NTFS.ntfs_cur_attr]
pop [ebp+NTFS.ntfs_cur_iRecord]
pop dword [ebp+NTFS.ntfs_attr_size]
pop dword [ebp+NTFS.ntfs_attr_size+4]
pop [ebp+NTFS.ntfs_attr_list]
pop [ebp+NTFS.ntfs_attr_offs]
pop [ebp+NTFS.ntfs_attr_iBaseRecord]
pop [ebp+NTFS.ntfs_attr_iRecord]
jc .ret
cmp edx, [ebp+NTFS.frs_size]
jnz .errret
mov eax, [ntfs_data.frs_buffer]
mov eax, [ebp+NTFS.frs_buffer]
cmp dword [eax], 'FILE'
jnz .errret
push ebx
864,18 → 987,18
mov ebx, eax
call ntfs_restore_usa_frs
pop ebx
setnc al
movzx eax, al
jc .errret
.ret:
pop edx ecx
ret
.err:
.errret:
pop edx ecx
.errret:
xor eax, eax
stc
ret
 
ntfs_restore_usa_frs:
mov eax, [ntfs_data.frs_size]
mov eax, [ebp+NTFS.frs_size]
ntfs_restore_usa:
pushad
shr eax, 9
955,82 → 1078,83
ret
 
ntfs_find_lfn:
; in: esi+ebp -> name
; in: esi+[esp+4] -> 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
; else CF=0, [ebp+NTFS.ntfs_cur_iRecord] valid, eax->record in parent directory
mov [ebp+NTFS.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
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.ntfs_cur_offs], 0
mov eax, [ebp+NTFS.cur_index_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr
jnc @f
.ret:
ret
ret 4
@@:
cmp [ntfs_cur_read], 0x20
xor eax, eax
cmp [ebp+NTFS.ntfs_cur_read], 0x20
jc .ret
pushad
mov esi, [ntfs_data.cur_index_buf]
mov esi, [ebp+NTFS.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ntfs_cur_read], eax
cmp [ebp+NTFS.ntfs_cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
cmp eax, [ntfs_data.cur_index_size]
cmp eax, [ebp+NTFS.cur_index_size]
ja @f
.stc_ret:
popad
stc
ret
ret 4
@@:
; reallocate
push eax
push [ntfs_data.cur_index_buf]
push [ebp+NTFS.cur_index_buf]
call kernel_free
pop eax
mov [ntfs_data.cur_index_size], eax
mov [ebp+NTFS.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
and [ebp+NTFS.cur_index_size], 0
and [ebp+NTFS.cur_index_buf], 0
jmp .stc_ret
@@:
mov [ntfs_data.cur_index_buf], eax
mov [ebp+NTFS.cur_index_buf], eax
popad
jmp .doit2
.readok1:
mov ebp, [esi+8] ; subnode_size
shr ebp, 9
cmp ebp, [ntfs_data.cur_index_size]
mov edx, [esi+8] ; subnode_size
shr edx, 9
cmp edx, [ebp+NTFS.cur_index_size]
jbe .ok2
push esi ebp
push ebp
push esi edx
push edx
call kernel_alloc
pop ebp esi
pop edx esi
test eax, eax
jz .stc_ret
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
mov ecx, [ebp+NTFS.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]
mov [ebp+NTFS.cur_index_size], edx
push esi edx
push [ebp+NTFS.cur_index_buf]
call kernel_free
pop ebp esi
mov [ntfs_data.cur_index_buf], esi
pop edx esi
mov [ebp+NTFS.cur_index_buf], esi
.ok2:
add esi, 10h
mov edi, [esp+4]
; edi -> name, esi -> current index data, ebp = subnode size
; edi -> name, esi -> current index data, edx = subnode size
.scanloop:
add esi, [esi]
.scanloopint:
1070,17 → 1194,19
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]
imul eax, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION
mov [ebp+NTFS.ntfs_cur_size], edx
mov eax, [ebp+NTFS.cur_index_buf]
mov esi, eax
mov [ntfs_cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
push edx
call ntfs_read_attr
mov eax, ebp
pop edx
mov eax, edx
shl eax, 9
cmp [ntfs_cur_read], eax
cmp [ebp+NTFS.ntfs_cur_read], eax
jnz .notfound
cmp dword [esi], 'INDX'
jnz .notfound
1092,7 → 1218,7
.notfound:
popad
stc
ret
ret 4
.found:
cmp byte [edi], 0
jz .done
1106,7 → 1232,7
pop esi
pop esi
mov eax, [esi]
mov [ntfs_cur_iRecord], eax
mov [ebp+NTFS.ntfs_cur_iRecord], eax
mov [esp+1Ch], esi
mov [esp+4], edi
popad
1113,29 → 1239,22
inc esi
cmp byte [esi-1], 0
jnz .doit2
test ebp, ebp
cmp dword [esp+4], 0
jz @f
mov esi, ebp
xor ebp, ebp
mov esi, [esp+4]
mov dword [esp+4], 0
jmp .doit2
@@:
ret
ret 4
 
;----------------------------------------------------------------
;
; 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:
; ntfs_Read - NTFS implementation of reading a file
; in: ebp = pointer to NTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ntfs_Read:
cmp byte [esi], 0
jnz @f
or ebx, -1
1142,17 → 1261,20
movi eax, ERROR_ACCESS_DENIED
ret
@@:
call ntfs_find_lfn
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jnc .found
call ntfs_unlock
or ebx, -1
movi eax, ERROR_FILE_NOT_FOUND
ret
.found:
mov [ntfs_cur_attr], 0x80 ; $DATA
and [ntfs_cur_offs], 0
and [ntfs_cur_size], 0
mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA
and [ebp+NTFS.ntfs_cur_offs], 0
and [ebp+NTFS.ntfs_cur_size], 0
call ntfs_read_attr
jnc @f
call ntfs_unlock
or ebx, -1
movi eax, ERROR_ACCESS_DENIED
ret
1160,9 → 1282,7
pushad
and dword [esp+10h], 0
xor eax, eax
test ebx, ebx
jz .zero1
cmp dword [ebx+4], 0x200
cmp dword [ebx+8], 0x200
jb @f
.eof0:
popad
1169,23 → 1289,29
xor ebx, ebx
.eof:
movi eax, ERROR_END_OF_FILE
push eax
call ntfs_unlock
pop eax
ret
@@:
mov eax, [ebx]
mov ecx, [ebx+12]
mov edx, [ebx+16]
mov eax, [ebx+4]
test eax, 0x1FF
jz .alignedstart
push edx
mov edx, [ebx+4]
mov edx, [ebx+8]
shrd eax, edx, 9
pop edx
mov [ntfs_cur_offs], eax
mov [ntfs_cur_size], 1
mov [ntfs_cur_buf], ntfs_bitmap_buf
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 1
lea eax, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr.continue
mov eax, [ebx]
mov eax, [ebx+4]
and eax, 0x1FF
lea esi, [ntfs_bitmap_buf+eax]
sub eax, [ntfs_cur_read]
lea esi, [ebp+NTFS.ntfs_bitmap_buf+eax]
sub eax, [ebp+NTFS.ntfs_cur_read]
jae .eof0
neg eax
push ecx
1202,115 → 1328,113
jnz @f
.retok:
popad
call ntfs_unlock
xor eax, eax
ret
@@:
cmp [ntfs_cur_read], 0x200
cmp [ebp+NTFS.ntfs_cur_read], 0x200
jz .alignedstart
.eof_ebx:
popad
jmp .eof
.alignedstart:
mov eax, [ebx]
mov eax, [ebx+4]
push edx
mov edx, [ebx+4]
mov edx, [ebx+8]
add eax, 511
adc edx, 0
shrd eax, edx, 9
pop edx
.zero1:
mov [ntfs_cur_offs], eax
mov [ntfs_cur_buf], edx
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_buf], edx
mov eax, ecx
shr eax, 9
mov [ntfs_cur_size], eax
add eax, [ntfs_cur_offs]
mov [ebp+NTFS.ntfs_cur_size], eax
add eax, [ebp+NTFS.ntfs_cur_offs]
push eax
call ntfs_read_attr.continue
pop [ntfs_cur_offs]
mov eax, [ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_read]
add [esp+10h], eax
mov eax, ecx
and eax, not 0x1FF
cmp [ntfs_cur_read], eax
cmp [ebp+NTFS.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
add edx, [ebp+NTFS.ntfs_cur_read]
mov [ebp+NTFS.ntfs_cur_size], 1
lea eax, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr.continue
cmp [ntfs_cur_read], ecx
cmp [ebp+NTFS.ntfs_cur_read], ecx
jb @f
mov [ntfs_cur_read], ecx
mov [ebp+NTFS.ntfs_cur_read], ecx
@@:
xchg ecx, [ntfs_cur_read]
xchg ecx, [ebp+NTFS.ntfs_cur_read]
push ecx
mov edi, edx
mov esi, ntfs_bitmap_buf
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
add [esp+10h+4], ecx
rep movsb
pop ecx
xor eax, eax
cmp ecx, [ntfs_cur_read]
cmp ecx, [ebp+NTFS.ntfs_cur_read]
jz @f
mov al, ERROR_END_OF_FILE
@@:
mov [esp+1Ch], eax
call ntfs_unlock
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:
; ntfs_ReadFolder - NTFS implementation of reading a folder
; in: ebp = pointer to NTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ntfs_ReadFolder:
call ntfs_lock
mov eax, 5 ; root cluster
cmp byte [esi], 0
jz .doit
call ntfs_find_lfn
stdcall ntfs_find_lfn, [esp+4]
jnc .doit2
.notfound:
or ebx, -1
push ERROR_FILE_NOT_FOUND
.pop_ret:
call ntfs_unlock
pop eax
ret
.doit:
mov [ntfs_cur_iRecord], eax
mov [ebp+NTFS.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
mov [ebp+NTFS.ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 1
lea eax, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
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
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.ntfs_cur_offs], 0
mov eax, [ebp+NTFS.cur_index_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr
jnc .ok
cmp [hd_error], 0
test eax, eax
jz .notfound
or ebx, -1
push 11
jmp .pop_ret
.ok:
cmp [ntfs_cur_read], 0x20
cmp [ebp+NTFS.ntfs_cur_read], 0x20
jae @f
or ebx, -1
.fserr:
1318,14 → 1442,14
jmp .pop_ret
@@:
pushad
mov esi, [ntfs_data.cur_index_buf]
mov esi, [ebp+NTFS.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ntfs_cur_read], eax
cmp [ebp+NTFS.ntfs_cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
cmp eax, [ntfs_data.cur_index_size]
cmp eax, [ebp+NTFS.cur_index_size]
ja @f
popad
jmp .fserr
1332,53 → 1456,51
@@:
; reallocate
push eax
push [ntfs_data.cur_index_buf]
push [ebp+NTFS.cur_index_buf]
call kernel_free
pop eax
mov [ntfs_data.cur_index_size], eax
mov [ebp+NTFS.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
and [ebp+NTFS.cur_index_size], 0
and [ebp+NTFS.cur_index_buf], 0
.nomem:
call ntfs_unlock
popad
or ebx, -1
movi eax, 12
ret
@@:
mov [ntfs_data.cur_index_buf], eax
mov [ebp+NTFS.cur_index_buf], eax
popad
jmp .doit2
.readok1:
mov ebp, [esi+8] ; subnode_size
shr ebp, 9
cmp ebp, [ntfs_data.cur_index_size]
mov edx, [esi+8] ; subnode_size
shr edx, 9
mov [ebp+NTFS.cur_subnode_size], edx
cmp edx, [ebp+NTFS.cur_index_size]
jbe .ok2
push esi ebp
push ebp
push esi edx
push edx
call kernel_alloc
pop ebp esi
pop edx esi
test eax, eax
jz .nomem
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
mov ecx, [ebp+NTFS.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]
mov [ebp+NTFS.cur_index_size], edx
push [ebp+NTFS.cur_index_buf]
call kernel_free
pop ebp esi
mov [ntfs_data.cur_index_buf], esi
mov [ebp+NTFS.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]
mov edx, [ebx+16]
push dword [ebx+8] ; read ANSI/UNICODE name
; init header
mov edi, edx
mov ecx, 32/4
1385,13 → 1507,14
xor eax, eax
rep stosd
mov byte [edx], 1 ; version
mov ecx, [esp+4+18h]
mov ecx, [ebx+12]
mov ebx, [ebx+4]
push edx
mov edx, esp
; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block,
; edi -> BDFE, esi -> current index data, ebx = first wanted block,
; ecx = number of blocks to read
; edx -> parameters block: dd <output>, dd <flags>
cmp [ntfs_cur_iRecord], 5
cmp [ebp+NTFS.ntfs_cur_iRecord], 5
jz .skip_specials
; dot and dotdot entries
push esi
1413,38 → 1536,39
.dump_root_done:
; now dump all subnodes
push ecx edi
mov edi, ntfs_bitmap_buf
mov [ntfs_cur_buf], edi
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.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
mov [ebp+NTFS.ntfs_cur_attr], 0xB0 ; $BITMAP
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 2
call ntfs_read_attr
pop edi ecx
push 0 ; save offset in $BITMAP attribute
and [ntfs_cur_offs], 0
and [ebp+NTFS.ntfs_cur_offs], 0
.dumploop:
mov [ntfs_cur_attr], 0xA0
mov [ntfs_cur_size], ebp
mov eax, [ntfs_data.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_attr], 0xA0
mov eax, [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, [ebp+NTFS.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
mov [ebp+NTFS.ntfs_cur_buf], eax
push [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_offs]
imul eax, [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.ntfs_cur_offs], eax
call ntfs_read_attr
pop [ntfs_cur_offs]
mov eax, ebp
pop [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.cur_subnode_size]
shl eax, 9
cmp [ntfs_cur_read], eax
cmp [ebp+NTFS.ntfs_cur_read], eax
jnz .done
push eax
mov eax, [ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_offs]
and eax, 0x400*8-1
bt dword [ntfs_bitmap_buf], eax
bt dword [ebp+NTFS.ntfs_bitmap_buf], eax
pop eax
jnc .dump_subnode_done
cmp dword [esi], 'INDX'
1464,26 → 1588,26
add esi, eax
jmp .dump_subnode
.dump_subnode_done:
inc [ntfs_cur_offs]
test [ntfs_cur_offs], 0x400*8-1
inc [ebp+NTFS.ntfs_cur_offs]
test [ebp+NTFS.ntfs_cur_offs], 0x400*8-1
jnz .dumploop
mov [ntfs_cur_attr], 0xB0
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
push ecx edi
mov edi, ntfs_bitmap_buf
mov [ntfs_cur_buf], edi
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
pop edi ecx
pop eax
push [ntfs_cur_offs]
push [ebp+NTFS.ntfs_cur_offs]
inc eax
mov [ntfs_cur_offs], eax
mov [ntfs_cur_size], 2
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 2
push eax
call ntfs_read_attr
pop eax
pop [ntfs_cur_offs]
pop [ebp+NTFS.ntfs_cur_offs]
push eax
jmp .dumploop
.done:
1498,6 → 1622,7
@@:
mov [esp+1Ch], eax
mov [esp+10h], ebx
call ntfs_unlock
popad
ret
 
1517,14 → 1642,14
stosd
scasd
push edx
mov eax, dword [ntfs_bitmap_buf]
mov edx, dword [ntfs_bitmap_buf+4]
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+4]
call ntfs_datetime_to_bdfe
mov eax, dword [ntfs_bitmap_buf+0x18]
mov edx, dword [ntfs_bitmap_buf+0x1C]
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C]
call ntfs_datetime_to_bdfe
mov eax, dword [ntfs_bitmap_buf+8]
mov edx, dword [ntfs_bitmap_buf+0xC]
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+8]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC]
call ntfs_datetime_to_bdfe
pop edx
xor eax, eax
1733,90 → 1858,69
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:
; ntfs_Rewrite - NTFS implementation of creating a new file
; in: ebp = pointer to NTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ntfs_Rewrite:
ntfs_CreateFolder:
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:
; ntfs_Write - NTFS implementation of writing to file
; in: ebp = pointer to NTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ntfs_Write:
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:
ntfs_SetFileEnd:
ntfs_SetFileInfo:
ntfs_Delete:
mov eax, ERROR_UNSUPPORTED_FS
ret
 
ntfs_HdGetFileInfo:
;----------------------------------------------------------------
; ntfs_GetFileInfo - NTFS implementation of getting file info
; in: ebp = pointer to NTFS structure
; in: esi+[esp+4] = name
; in: ebx = pointer to parameters from sysfunc 70
; out: eax, ebx = return values for sysfunc 70
;----------------------------------------------------------------
ntfs_GetFileInfo:
cmp byte [esi], 0
jnz @f
movi eax, 2
ret
@@:
call ntfs_find_lfn
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jnc .doit
test eax, eax
movi eax, ERROR_FILE_NOT_FOUND
cmp [hd_error], 0
jz @f
mov al, 11
@@:
push eax
call ntfs_unlock
pop eax
ret
.doit:
push esi edi
mov esi, eax
mov edi, edx
mov edi, [ebx+16]
xor eax, eax
call ntfs_direntry_to_bdfe
pop edi esi
call ntfs_unlock
xor eax, eax
ret
 
/kernel/branches/Kolibri-acpi/init.inc
15,7 → 15,7
align 4
proc mem_test
; if we have BIOS with fn E820, skip the test
cmp dword [BOOT_VAR-OS_BASE + 0x9100], 0
cmp dword [BOOT_VARS-OS_BASE + 0x9100], 0
jnz .ret
 
mov eax, cr0
35,12 → 35,12
 
and eax, not (CR0_CD+CR0_NW) ;enable caching
mov cr0, eax
inc dword [BOOT_VAR-OS_BASE + 0x9100]
inc dword [BOOT_VARS-OS_BASE + 0x9100]
xor eax, eax
mov [BOOT_VAR-OS_BASE + 0x9104], eax
mov [BOOT_VAR-OS_BASE + 0x9108], eax
mov [BOOT_VAR-OS_BASE + 0x910C], edi
mov [BOOT_VAR-OS_BASE + 0x9110], eax
mov [BOOT_VARS-OS_BASE + 0x9104], eax
mov [BOOT_VARS-OS_BASE + 0x9108], eax
mov [BOOT_VARS-OS_BASE + 0x910C], edi
mov [BOOT_VARS-OS_BASE + 0x9110], eax
.ret:
ret
endp
48,7 → 48,7
align 4
proc init_mem
; calculate maximum allocatable address and number of allocatable pages
mov edi, BOOT_VAR-OS_BASE + 0x9104
mov edi, BOOT_VARS-OS_BASE + 0x9104
mov ecx, [edi-4]
xor esi, esi; esi will hold total amount of memory
xor edx, edx; edx will hold maximum allocatable address
195,7 → 195,7
rep stosd
 
; scan through memory map and mark free areas as available
mov ebx, BOOT_VAR-OS_BASE + 0x9104
mov ebx, BOOT_VARS-OS_BASE + 0x9104
mov edx, [ebx-4]
.scanmap:
cmp [ebx+16], byte 1
/kernel/branches/Kolibri-acpi/kernel.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.
;; PROGRAMMING:
;; Ivan Poddubny
;; Marat Zakiyanov (Mario79)
79,8 → 79,6
 
; Enabling the next line will enable serial output console
;debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used
; The following constant, if nonzero, duplicates debug output to the screen.
debug_direct_print equ 0
 
include "proc32.inc"
include "kglobals.inc"
88,10 → 86,17
include "encoding.inc"
 
include "const.inc"
 
iglobal
; The following variable, if equal to 1, duplicates debug output to the screen.
debug_direct_print db 0
; Start the first app (LAUNCHER) after kernel is loaded? (1=yes, 2 or 0=no)
launcher_start db 1
endg
 
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)
265,13 → 270,12
 
; SAVE & CLEAR 0-0xffff
 
xor esi, esi
mov edi, (BOOT_VAR-OS_BASE)
mov ecx, 0x10000 / 4
rep movsd
mov edi, 0x1000
mov ecx, 0xf000 / 4
mov ecx, 0x8000 / 4
rep stosd
mov edi, 0xa000
mov ecx, 0x6000 / 4
rep stosd
 
call test_cpu
bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc
357,54 → 361,93
mov ecx, application_table_mutex
call mutex_init
 
mov ecx, ide_mutex
call mutex_init
mov ecx, ide_channel1_mutex
call mutex_init
mov ecx, ide_channel2_mutex
call mutex_init
;-----------------------------------------------------------------------------
; SAVE REAL MODE VARIABLES
;-----------------------------------------------------------------------------
save_variables_IDE_controller:
xor eax, eax
mov ax, [BOOT_VAR + BOOT_IDE_PI_16]
mov ax, [BOOT_VARS + BOOT_IDE_INTERR_16]
mov [IDE_Interrupt], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_PI_16]
mov [IDEContrProgrammingInterface], ax
mov ax, [BOOT_VAR + BOOT_IDE_BASE_ADDR]
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BASE_ADDR]
mov [IDEContrRegsBaseAddr], ax
mov ax, [BOOT_VAR + BOOT_IDE_BAR0_16]
mov [IDE_BAR0_val], ax
 
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BAR0_16]
cmp ax, 0
je @f
 
cmp ax, 1
je @f
 
and ax, 0xfff0
jne .no_PATA_BAR0
@@:
mov ax, 0x1F0
jmp @f
.no_PATA_BAR0:
and ax, 0xFFFC
@@:
mov [StandardATABases], ax
mov [hd_address_table], eax
mov [hd_address_table+8], eax
mov [IDE_BAR0_val], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BAR1_16]
cmp ax, 0
je @f
cmp ax, 1
jne .no_PATA_BAR1
@@:
mov ax, [BOOT_VAR + BOOT_IDE_BAR1_16]
mov ax, 0x3F4
jmp @f
.no_PATA_BAR1:
and ax, 0xFFFC
@@:
mov [IDE_BAR1_val], ax
mov ax, [BOOT_VAR + BOOT_IDE_BAR2_16]
mov [IDE_BAR2_val], ax
 
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BAR2_16]
cmp ax, 0
je @f
 
cmp ax, 1
je @f
 
and ax, 0xfff0
jne .no_PATA_BAR2
@@:
mov ax, 0x170
jmp @f
.no_PATA_BAR2:
and ax, 0xFFFC
@@:
mov [StandardATABases+2], ax
mov [hd_address_table+16], eax
mov [hd_address_table+24], eax
mov [IDE_BAR2_val], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BAR3_16]
cmp ax, 0
je @f
cmp ax, 1
jne .no_PATA_BAR3
@@:
mov ax, [BOOT_VAR + BOOT_IDE_BAR3_16]
mov ax, 0x374
jmp @f
.no_PATA_BAR3:
and ax, 0xFFFC
@@:
mov [IDE_BAR3_val], ax
 
; --------------- APM ---------------------
 
; init selectors
mov ebx, [BOOT_VAR+BOOT_APM_ENTRY] ; offset of APM entry point
movzx eax, word [BOOT_VAR+BOOT_APM_CODE_32] ; real-mode segment base address of
mov ebx, [BOOT_VARS+BOOT_APM_ENTRY] ; offset of APM entry point
movzx eax, word [BOOT_VARS+BOOT_APM_CODE_32] ; real-mode segment base address of
; protected-mode 32-bit code segment
movzx ecx, word [BOOT_VAR+BOOT_APM_CODE_16]; real-mode segment base address of
movzx ecx, word [BOOT_VARS+BOOT_APM_CODE_16]; real-mode segment base address of
; protected-mode 16-bit code segment
movzx edx, word [BOOT_VAR+BOOT_APM_DATA_16]; real-mode segment base address of
movzx edx, word [BOOT_VARS+BOOT_APM_DATA_16]; real-mode segment base address of
; protected-mode 16-bit data segment
 
shl eax, 4
425,28 → 468,31
mov dword[apm_entry], ebx
mov word [apm_entry + 4], apm_code_32 - gdts
 
mov eax, [BOOT_VAR + BOOT_APM_VERSION] ; version & flags
mov eax, [BOOT_VARS + BOOT_APM_VERSION] ; version & flags
mov [apm_vf], eax
; -----------------------------------------
mov al, [BOOT_VAR+BOOT_DMA] ; DMA access
mov al, [BOOT_VARS+BOOT_DMA] ; DMA access
mov [allow_dma_access], al
movzx eax, byte [BOOT_VAR+BOOT_BPP] ; bpp
movzx eax, byte [BOOT_VARS+BOOT_BPP] ; bpp
mov [_display.bpp], eax
mov [_display.vrefresh], 60
 
movzx eax, word [BOOT_VAR+BOOT_X_RES]; X max
mov al, [BOOT_VARS+BOOT_DEBUG_PRINT] ; If nonzero, duplicates debug output to the screen
mov [debug_direct_print], al
mov al, [BOOT_VARS+BOOT_LAUNCHER_START] ; Start the first app (LAUNCHER) after kernel is loaded?
mov [launcher_start], al
movzx eax, word [BOOT_VARS+BOOT_X_RES]; X max
mov [_display.width], eax
mov [display_width_standard], eax
dec eax
mov [Screen_Max_X], eax
mov [screen_workarea.right], eax
movzx eax, word [BOOT_VAR+BOOT_Y_RES]; Y max
movzx eax, word [BOOT_VARS+BOOT_Y_RES]; Y max
mov [_display.height], eax
mov [display_height_standard], eax
dec eax
mov [Screen_Max_Y], eax
mov [screen_workarea.bottom], eax
movzx eax, word [BOOT_VAR+BOOT_VESA_MODE] ; screen mode
movzx eax, word [BOOT_VARS+BOOT_VESA_MODE] ; screen mode
mov dword [SCR_MODE], eax
; mov eax, [BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add
; mov [BANK_SWITCH], eax
455,7 → 501,7
je @f
cmp [SCR_MODE], word 0x12 ; VGA 640x480
je @f
movzx eax, word[BOOT_VAR+BOOT_PITCH] ; for other modes
movzx eax, word[BOOT_VARS+BOOT_PITCH] ; for other modes
@@:
mov [_display.pitch], eax
mov eax, [_display.width]
468,7 → 514,7
; equal to [_display.width] * [ScreenBPP] / 8
call calculate_fast_getting_offset_for_LFB
 
mov esi, BOOT_VAR+0x9080
mov esi, BOOT_VARS+0x9080
movzx ecx, byte [esi-1]
mov [NumBiosDisks], ecx
mov edi, BiosDisksData
476,7 → 522,7
 
; GRAPHICS ADDRESSES
 
mov eax, [BOOT_VAR+BOOT_LFB]
mov eax, [BOOT_VARS+BOOT_LFB]
mov [LFBAddress], eax
 
cmp [SCR_MODE], word 0100000000000000b
709,24 → 755,32
 
mov esi, boot_enableirq
call boot_log
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
; Enable timer IRQ (IRQ0) and co-processor IRQ (IRQ13)
; they are used: when partitions are scanned, hd_read relies on timer
call unmask_timer
stdcall enable_irq, 2 ; @#$%! PIC
stdcall enable_irq, 6 ; FDD
stdcall enable_irq, 13 ; co-processor
stdcall enable_irq, 14
stdcall enable_irq, 15
 
mov esi, boot_enablint_ide
cmp [IDEContrProgrammingInterface], 0
je @f
 
mov esi, boot_disabling_ide
call boot_log
; Enable interrupts in IDE controller
mov al, 0
mov dx, 0x3F6
;--------------------------------------
; Disable IDE interrupts, because the search
; for IDE partitions is in the PIO mode.
;--------------------------------------
.disable_IDE_interrupt:
; Disable interrupts in IDE controller for PIO
mov al, 2
mov dx, [IDE_BAR1_val] ;0x3F4
add dx, 2 ;0x3F6
out dx, al
mov dl, 0x76
mov dx, [IDE_BAR3_val] ;0x374
add dx, 2 ;0x376
out dx, al
 
@@:
;-----------------------------------------------------------------------------
;!!!!!!!!!!!!!!!!!!!!!!!!!!
; mov esi, boot_detectdisks
; call boot_log
919,24 → 973,12
[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP
 
; LOAD FIRST APPLICATION
cmp byte [launcher_start], 1 ; Check if starting LAUNCHER is selected on blue screen (1 = yes)
jnz first_app_found
 
cli
 
; cmp byte [BOOT_VAR+0x9030],1
; jne no_load_vrr_m
 
; mov ebp, vrr_m
; call fs_execute_from_sysdir
;
;; cmp eax,2 ; if vrr_m app found (PID=2)
; sub eax,2
; jz first_app_found
;
;no_load_vrr_m:
 
mov ebp, firstapp
call fs_execute_from_sysdir
 
; cmp eax,2 ; continue if a process has been loaded
test eax, eax
jns first_app_found
 
989,6 → 1031,7
call set_lights
;// mike.dld ]
stdcall attach_int_handler, 1, irq1, 0
DEBUGF 1, "K : IRQ1 error code %x\n", eax
.no_keyboard:
 
; SET MOUSE
1056,6 → 1099,7
DEBUGF 1, "K : BAR3 %x \n", [IDE_BAR3_val]:4
DEBUGF 1, "K : BAR4 %x \n", [IDEContrRegsBaseAddr]:4
DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", [IDEContrProgrammingInterface]:4
DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4
; START MULTITASKING
 
; A 'All set - press ESC to start' messages if need
1068,9 → 1112,84
jne .bll1
end if
 
push eax edx
mov dx, [IDEContrRegsBaseAddr]
xor eax, eax
add dx, 2
in al, dx
DEBUGF 1, "K : Primary Bus Master IDE Status Register %x\n", eax
 
add dx, 8
in al, dx
DEBUGF 1, "K : Secondary Bus Master IDE Status Register %x\n", eax
pop edx eax
 
cmp [IDEContrRegsBaseAddr], 0
setnz [dma_hdd]
 
cmp [IDEContrProgrammingInterface], 0
je set_interrupts_for_IDE_controllers.continue
 
mov ax, [IDE_Interrupt]
cmp al, 0xff
jne @f
 
mov [dma_hdd], 0
jmp set_interrupts_for_IDE_controllers.end_set_interrupts
@@:
;-----------------------------------------------------------------------------
; set interrupts for IDE Controller
;-----------------------------------------------------------------------------
mov esi, boot_set_int_IDE
call boot_log
set_interrupts_for_IDE_controllers:
mov ax, [IDEContrProgrammingInterface]
cmp ax, 0x0180
je .pata_ide
 
cmp ax, 0x018a
jne .sata_ide
;--------------------------------------
.pata_ide:
cmp [IDEContrRegsBaseAddr], 0
je .end_set_interrupts
 
stdcall attach_int_handler, 14, IDE_irq_14_handler, 0
DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax
stdcall attach_int_handler, 15, IDE_irq_15_handler, 0
DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax
jmp .enable_IDE_interrupt
;--------------------------------------
.sata_ide:
cmp ax, 0x0185
je .sata_ide_1
 
cmp ax, 0x018f
jne .end_set_interrupts
;--------------------------------------
.sata_ide_1:
cmp [IDEContrRegsBaseAddr], 0
je .end_set_interrupts
 
mov ax, [IDE_Interrupt]
movzx eax, al
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [IDE_Interrupt]:1, eax
;--------------------------------------
.enable_IDE_interrupt:
mov esi, boot_enabling_ide
call boot_log
; Enable interrupts in IDE controller for DMA
mov al, 0
mov dx, [IDE_BAR1_val] ;0x3F4
add dx, 2 ;0x3F6
out dx, al
mov dx, [IDE_BAR3_val] ;0x374
add dx, 2 ;0x376
out dx, al
;--------------------------------------
.end_set_interrupts:
;-----------------------------------------------------------------------------
cmp [dma_hdd], 0
je .print_pio
.print_dma:
1196,8 → 1315,8
jnz .yes
call stack_handler_has_work?
jnz .yes
call check_fdd_motor_status_has_work?
jnz .yes
; call check_fdd_motor_status_has_work?
; jnz .yes
call check_ATAPI_device_event_has_work?
jnz .yes
call check_lights_state_has_work?
1288,10 → 1407,10
loop .fl60
push eax
 
mov ax, [BOOT_VAR+BOOT_Y_RES]
mov ax, [BOOT_VARS+BOOT_Y_RES]
shr ax, 1
shl eax, 16
mov ax, [BOOT_VAR+BOOT_X_RES]
mov ax, [BOOT_VARS+BOOT_X_RES]
shr ax, 1
mov [MOUSE_X], eax
call wakeup_osloop
1675,76 → 1794,17
ret
nsyse5:
 
sub ebx, 2 ; HD BASE
sub ebx, 2 ; HD BASE - obsolete
jnz nsyse7
 
test ecx, ecx
jz nosethd
 
cmp ecx, 4
ja nosethd
mov [hd_base], cl
 
cmp ecx, 1
jnz noprmahd
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
and dword [hdid], 0x0
mov dword [hdpos], ecx
; call set_FAT32_variables
noprmahd:
 
cmp ecx, 2
jnz noprslhd
mov eax, [hd_address_table]
mov [hdbase], eax ;0x1f0
mov [hdid], 0x10
mov dword [hdpos], ecx
; call set_FAT32_variables
noprslhd:
 
cmp ecx, 3
jnz nosemahd
mov eax, [hd_address_table+16]
mov [hdbase], eax ;0x170
and dword [hdid], 0x0
mov dword [hdpos], ecx
; call set_FAT32_variables
nosemahd:
 
cmp ecx, 4
jnz noseslhd
mov eax,[hd_address_table+16]
mov [hdbase], eax ;0x170
mov [hdid], 0x10
mov dword [hdpos], ecx
; call set_FAT32_variables
noseslhd:
call reserve_hd1
call reserve_hd_channel
call free_hd_channel
and dword [hd1_status], 0 ; free
nosethd:
ret
 
iglobal
hd_base db 0
endg
 
nsyse7:
 
; cmp eax,8 ; HD PARTITION
; cmp eax,8 ; HD PARTITION - obsolete
dec ebx
jnz nsyse8
mov [fat32part], ecx
; call set_FAT32_variables
call reserve_hd1
call reserve_hd_channel
call free_hd_channel
; pusha
call choice_necessity_partition_1
; popa
and dword [hd1_status], 0 ; free
ret
 
nsyse8:
1845,7 → 1905,7
; cmp eax,7
sub ebx, 2
jnz ngsyse7
movzx eax, [hd_base]
xor eax, eax
mov [esp+32], eax
ret
ngsyse7:
2178,7 → 2238,7
jl exit_for_anyone
cmp ecx, 4
jg exit_for_anyone
mov [BOOT_VAR+0x9030], cl
mov [BOOT_VARS+0x9030], cl
 
mov eax, [TASK_COUNT]
mov [SYS_SHUTDOWN], al
4833,10 → 4893,12
end if
 
mov [msg_board_data+ecx], bl
if debug_direct_print
; // if debug_direct_print == 1
cmp byte [debug_direct_print], 1
jnz @f
pusha
iglobal
msg_board_pos dd 234*65536+10
msg_board_pos dd (42*6)*65536+10 ; for printing debug output on the screen
endg
lea edx, [msg_board_data+ecx]
mov ecx, 0x40FFFFFF
4848,7 → 4910,7
add word [msg_board_pos+2], 6
cmp bl, 10
jnz @f
mov word [msg_board_pos+2], 234
mov word [msg_board_pos+2], (42*6)
add word [msg_board_pos], 10
mov ax, word [Screen_Max_Y]
cmp word [msg_board_pos], ax
4855,7 → 4917,8
jbe @f
mov word [msg_board_pos], 10
@@:
end if
; // end if
 
if 0
pusha
mov al, bl
5632,7 → 5695,7
align 4
system_shutdown: ; shut down the system
 
cmp byte [BOOT_VAR+0x9030], 1
cmp byte [BOOT_VARS+0x9030], 1
jne @F
ret
@@:
5657,11 → 5720,11
rep movsb
end if
 
mov esi, BOOT_VAR ; restore 0x0 - 0xffff
mov edi, OS_BASE
mov ecx, 0x10000/4
cld
rep movsd
; mov esi, BOOT_VAR ; restore 0x0 - 0xffff
; mov edi, OS_BASE
; mov ecx, 0x10000/4
; cld
; rep movsd
 
call restorefatchain
 
/kernel/branches/Kolibri-acpi/network/ARP.inc
293,7 → 293,7
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n"
 
.exit:
call kernel_free
call NET_packet_free
add esp, 4 ; pop (balance stack)
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: exiting\n"
/kernel/branches/Kolibri-acpi/network/IPv4.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; IPv4.INC ;;
305,7 → 305,7
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
inc [IP_packets_dumped] ; FIXME: use correct interface
call kernel_free
call NET_packet_free
add esp, 4 ; pop (balance stack)
ret
 
485,7 → 485,7
push edx ; Push pointer to fragment onto stack
mov ebx, [edx + FRAGMENT_entry.Owner] ; we need to remeber the owner, in case this is the last packet
mov edx, [edx + FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
call kernel_free ; free the previous fragment buffer (this uses the value from stack)
call NET_packet_free ; free the previous fragment buffer (this uses the value from stack)
pop eax
cmp edx, -1 ; Check if it is last fragment in chain
jne .rebuild_packet_loop
845,7 → 845,7
add esp, 12 + 4 + 6
.err2:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: dumping\n"
call kernel_free
call NET_packet_free
add esp, 4
 
ret
/kernel/branches/Kolibri-acpi/network/PPPoE.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2012-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; PPPoE.INC ;;
103,7 → 103,7
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n'
call kernel_free
call NET_packet_free
add esp, 4
ret
 
229,7 → 229,7
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: dumping\n"
call kernel_free
call NET_packet_free
add esp, 4
ret
 
/kernel/branches/Kolibri-acpi/network/ethernet.inc
82,7 → 82,7
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE,"ETH_input: dumping\n"
call kernel_free
call NET_packet_free
add esp, 4
ret
 
/kernel/branches/Kolibri-acpi/network/icmp.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ICMP.INC ;;
304,7 → 304,7
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
 
call kernel_free
call NET_packet_free
add esp, 4 ; pop (balance stack)
 
ret
/kernel/branches/Kolibri-acpi/network/loopback.inc
97,7 → 97,7
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: dumping\n"
call kernel_free
call NET_packet_free
add esp, 4
ret
 
/kernel/branches/Kolibri-acpi/network/socket.inc
754,15 → 754,15
; Ok, we got a socket ptr
mov eax, [esi]
 
; Convert it to a socket number
call SOCKET_ptr_to_num
jz .invalid ; FIXME ?
 
; Change thread ID to that of the current thread
mov ebx, [TASK_BASE]
mov ebx, [ebx + TASKDATA.pid]
mov [eax + SOCKET.TID], ebx
 
; Convert it to a socket number
call SOCKET_ptr_to_num
jz .invalid ; FIXME ?
 
; and return it to caller
mov [esp+32], eax
ret
871,6 → 871,9
test edi, MSG_DONTWAIT
jnz .return_err
 
test [eax + SOCKET.state], SS_CANTRCVMORE
jnz .return_err
 
; test [eax + SOCKET.options], SO_NONBLOCK
; jnz .return_err
 
926,7 → 929,7
rep movsd
.nd:
 
call kernel_free ; free kernel buffer
call NET_packet_free
pop eax ; return number of bytes copied to application
xor ebx, ebx
ret
1565,7 → 1568,7
call mutex_unlock
popa
 
call kernel_free
call NET_packet_free
add esp, 8
 
ret
1891,8 → 1894,7
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Raised a network event!\n"
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax
jmp .done
 
.unblock:
2049,6 → 2051,7
; SOCKET_free
;
; Free socket data memory and remove socket from the list
; Caller should lock and unlock socket_mutex
;
; IN: eax = socket ptr
; OUT: /
2059,11 → 2062,6
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: %x\n", eax
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
call SOCKET_check
jz .error
 
2109,12 → 2107,6
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: success!\n"
 
.error:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
ret
 
;------------------------------------
2149,7 → 2141,8
pop eax
 
; Copy structure from current socket to new
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
; We start at PID to preserve the socket num, 2 pointers and mutex
; TID will be filled in later
lea esi, [ebx + SOCKET.PID]
lea edi, [eax + SOCKET.PID]
mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
2157,6 → 2150,12
 
and [eax + SOCKET.options], not SO_ACCEPTCON
 
; Notify owner of parent socket
push eax
mov eax, ebx
call SOCKET_notify
pop eax
 
ret
 
.fail2:
2322,9 → 2321,6
align 4
SOCKET_process_end:
 
pushf
cli ; FIXME
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx
 
pusha
2351,11 → 2347,6
mov ebx, [ebx + SOCKET.NextPtr]
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
pusha
cmp [eax + SOCKET.Domain], AF_INET4
jne .free
 
2370,12 → 2361,6
 
.closed:
popa
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
jmp .next_socket_test
 
.done:
2386,8 → 2371,6
call mutex_unlock
popa
 
popf
 
ret
 
 
/kernel/branches/Kolibri-acpi/network/stack.inc
316,7 → 316,12
ret
 
 
align 4
NET_packet_free:
and dword[esp+4], not 0xfff
jmp kernel_free
 
 
align 4
NET_link_changed:
 
613,7 → 618,7
align 4
sys_network:
 
cmp ebx, -1
cmp bl, 255
jne @f
 
mov eax, [NET_RUNNING]
/kernel/branches/Kolibri-acpi/network/tcp_input.inc
69,7 → 69,7
inc [TCP_segments_missed + edi]
 
add esp, sizeof.TCP_queue_entry - 8
call kernel_free
call NET_packet_free
add esp, 4
 
ret
1455,10 → 1455,9
jnz @f
 
test ecx, ecx
jnz .final_processing
jz .final_processing
@@:
 
 
; The segment is in order?
mov eax, [edx + TCP_header.SequenceNumber]
cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
1491,6 → 1490,8
 
.out_of_order:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP data is out of order\n"
 
; Uh-oh, some data is out of order, lets call TCP reassemble for help
 
call TCP_reassemble
1622,7 → 1623,7
.dumpit:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
 
call kernel_free
call NET_packet_free
add esp, 4
jmp .loop
 
1695,6 → 1696,6
.drop_no_socket:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n"
 
call kernel_free
call NET_packet_free
add esp, 4
jmp .loop
/kernel/branches/Kolibri-acpi/network/tcp_subr.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;;
190,7 → 190,7
;;; TODO: update slow start threshold
 
call SOCKET_is_disconnected
call SOCKET_free
;; call SOCKET_free
 
ret
 
338,7 → 338,7
; Create the IP packet
 
push cx edx
mov ebx, [edi + 4]
mov edx, [edi + 4]
mov eax, [edi]
mov ecx, sizeof.TCP_header
mov di, IP_PROTO_TCP shl 8 + 128
/kernel/branches/Kolibri-acpi/network/udp.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; UDP.INC ;;
116,7 → 116,6
;
;-----------------------------------------------------------------
align 4
diff16 "UDP packetgfgfgfgfs", 0, $
UDP_input:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: size=%u\n", ecx
231,7 → 230,7
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
 
.dump:
call kernel_free
call NET_packet_free
add esp, 4 ; pop (balance stack)
DEBUGF DEBUG_NETWORK_VERBOSE,"UDP_input: dumping\n"