/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" |