Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3907 → Rev 3908

/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc
768,6 → 768,8
cmp [cd_status], 0
jne .end
mov [IDE_Channel_2], 1
mov ecx, ide_channel2_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 1
791,6 → 793,8
cmp [cd_status], 0
jne .end
mov [IDE_Channel_2], 1
mov ecx, ide_channel2_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 0
814,6 → 818,8
cmp [cd_status], 0
jne .end
mov [IDE_Channel_1], 1
mov ecx, ide_channel1_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 1
837,6 → 843,8
cmp [cd_status], 0
jne .end
mov [IDE_Channel_1], 1
mov ecx, ide_channel1_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 0
/kernel/branches/Kolibri-acpi/blkdev/disk.inc
5,7 → 5,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 3460 $
$Revision: 3742 $
 
; =============================================================================
; ================================= Constants =================================
186,9 → 186,9
; Pointer to parent DISK structure.
FSUserFunctions dd ?
; Handlers for the sysfunction 70h. This field is a pointer to the following
; array. The first dword is a number of supported subfunctions, other dwords
; array. The first dword is pointer to disconnect handler.
; The first dword is a number of supported subfunctions, other dwords
; point to handlers of corresponding subfunctions.
; This field is 0 if file system is not recognized.
; ...fs-specific data may follow...
ends
 
501,7 → 501,8
jz .nofree
.freeloop:
lodsd
call free
mov ecx, [eax+PARTITION.FSUserFunctions]
call dword [ecx]
dec edi
jnz .freeloop
.nofree:
727,7 → 728,7
; 10. This is not an MBR. The media is not partitioned. Create one partition
; which covers all the media and abort the loop.
stdcall disk_add_partition, 0, 0, \
dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4]
dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4], esi
jmp .done
.mbr:
; 11. Process all entries of the new MBR/EBR
855,7 → 856,7
adc edx, 0
push ecx
stdcall disk_add_partition, eax, edx, \
[ecx+PARTITION_TABLE_ENTRY.Length], 0
[ecx+PARTITION_TABLE_ENTRY.Length], 0, esi
pop ecx
.nothing:
; 5. Return.
869,7 → 870,10
; This is an internal function called from disk_scan_partitions and
; process_partition_table_entry. It adds one partition to the list of
; partitions for the media.
proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword
; Important note: start, length, disk MUST be present and
; MUST be in the same order as in PARTITION structure.
; esi duplicates [disk].
proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword, disk:dword
; 1. Check that this partition will not exceed the limit on total number.
cmp [esi+DISK.NumPartitions], MAX_NUM_PARTITIONS
jae .nothing
974,27 → 978,34
virtual at ebp+8
.start dq ?
.length dq ?
.disk dd ?
end virtual
; 1. Read the bootsector to the buffer.
; When disk_add_partition is called, ebx contains a pointer to
; a two-sectors-sized buffer. This function saves ebx in the stack
; a three-sectors-sized buffer. This function saves ebx in the stack
; immediately before ebp.
virtual at ebp-4
.buffer dd ?
end virtual
; 1. Read the bootsector to the buffer.
mov al, DISKFUNC.read
mov ebx, [.buffer]
add ebx, 512
push 1
stdcall disk_call_driver, ebx, dword [.start], dword [.start+4], esp
mov ebx, [ebp-4] ; get buffer
add ebx, 512 ; advance over MBR data to bootsector data
add ebp, 8 ; ebp points to part of PARTITION structure
xor eax, eax ; first sector of the partition
call fs_read32_sys
push eax
; 2. Run tests for all supported filesystems. If at least one test succeeded,
; go to 4.
; For tests: qword [ebp+8] = partition start, qword [ebp+10h] = partition
; length, [esp] = 0 if reading bootsector failed or 1 if succeeded,
; ebx points to the buffer for bootsector.
; For tests:
; ebp -> first three fields of PARTITION structure, .start, .length, .disk;
; [esp] = error code after bootsector read: 0 = ok, otherwise = failed,
; ebx points to the buffer for bootsector,
; ebx+512 points to 512-bytes buffer that can be used for anything.
call fat_create_partition
test eax, eax
jnz .success
call ntfs_create_partition
test eax, eax
jnz .success
call ext2_create_partition
test eax, eax
jnz .success
; 3. No file system has recognized the volume, so just allocate the PARTITION
; structure without extra fields.
movi eax, sizeof.PARTITION
1001,22 → 1012,30
call malloc
test eax, eax
jz .nothing
mov edx, dword [.start]
mov edx, dword [ebp+PARTITION.FirstSector]
mov dword [eax+PARTITION.FirstSector], edx
mov edx, dword [.start+4]
mov edx, dword [ebp+PARTITION.FirstSector+4]
mov dword [eax+PARTITION.FirstSector+4], edx
mov edx, dword [.length]
mov edx, dword [ebp+PARTITION.Length]
mov dword [eax+PARTITION.Length], edx
mov edx, dword [.length+4]
mov edx, dword [ebp+PARTITION.Length+4]
mov dword [eax+PARTITION.Length+4], edx
mov [eax+PARTITION.Disk], esi
and [eax+PARTITION.FSUserFunctions], 0
mov [eax+PARTITION.FSUserFunctions], default_fs_functions
.success:
.nothing:
sub ebp, 8 ; restore ebp
; 4. Return with eax = pointer to PARTITION or NULL.
pop ecx
ret
 
iglobal
align 4
default_fs_functions:
dd free
dd 0 ; no user functions
endg
 
; This function is called from file_system_lfn.
; This handler gets the control each time when fn 70 is called
; with unknown item of root subdirectory.
1200,15 → 1219,13
mov eax, [edx+DISK.Partitions]
mov eax, [eax+ecx*4]
mov edi, [eax+PARTITION.FSUserFunctions]
test edi, edi
jz .nofs
mov ecx, [ebx]
cmp [edi], ecx
cmp [edi+4], ecx
jbe .unsupported
push edx
push ebp
mov ebp, eax
call dword [edi+4+ecx*4]
call dword [edi+8+ecx*4]
pop ebp
pop edx
mov dword [esp+32], eax
1225,6 → 1242,8
mov dword [esp+32], ERROR_FILE_NOT_FOUND
jmp .cleanup
.unsupported:
cmp edi, default_fs_functions
jz .nofs
mov dword [esp+32], ERROR_UNSUPPORTED_FS
jmp .cleanup
.nomedia:
/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc
5,7 → 5,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 3284 $
$Revision: 3742 $
 
; This function is intended to replace the old 'hd_read' function when
; [hdd_appl_data] = 0, so its input/output parameters are the same, except
14,19 → 14,7
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_read32_sys:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 0
call hd_read
mov [hdd_appl_data], 1 ; restore to default state
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; do its work.
; Save ecx, set ecx to SysCache and let the common part do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.SysCache
39,18 → 27,7
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_read32_app:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 1
call hd_read
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
; Save ecx, set ecx to AppCache and let the common part do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.AppCache
185,19 → 162,7
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_write32_sys:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 0
call hd_write
mov [hdd_appl_data], 1 ; restore to default state
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; do its work.
; Save ecx, set ecx to SysCache and let the common part do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.SysCache
210,18 → 175,7
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_write32_app:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
add eax, dword [ebp+PARTITION.FirstSector]
mov [hdd_appl_data], 1
call hd_write
mov eax, [hd_error]
ret
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
; Save ecx, set ecx to AppCache and let the common part do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.AppCache
622,17 → 576,6
; This function flushes all modified data from both caches for the given DISK.
; esi = pointer to DISK
disk_sync:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by write_cache.
cmp esi, 'old'
jnz @f
mov [hdd_appl_data], 0
call write_cache
mov [hdd_appl_data], 1
call write_cache
mov eax, [hd_error]
ret
@@:
; The algorithm is straightforward.
push esi
push esi ; for second write_cache64
/kernel/branches/Kolibri-acpi/blkdev/fdc.inc
8,11 → 8,6
$Revision$
 
 
iglobal
;function pointers.
fdc_irq_func dd fdc_null
endg
 
uglobal
dmasize db 0x0
dmamode db 0x0
25,11 → 20,6
rep stosb
ret
 
fdc_irq:
call [fdc_irq_func]
fdc_null:
ret
 
save_image:
call reserve_flp
call restorefatchain
64,7 → 54,6
cmp [FDD_Track], 80
jne save_image_1
unnecessary_save_image:
mov [fdc_irq_func], fdc_null
popa
mov [flp_status], 0
ret
/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc
185,19 → 185,11
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
;*********************************************
FDCInterrupt:
; Установить флаг прерывани
; Установить флаг прерывания
mov [FDD_IntFlag], 1
mov al, 1
ret
 
 
;******************************************
;* УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЙ *
;* НГМД *
;******************************************
SetUserInterrupts:
mov [fdc_irq_func], FDCInterrupt
ret
 
;*******************************************
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
;*******************************************
212,9 → 204,9
mov [TickCounter], eax
; Ожидать установки флага прерывания НГМД
@@TestRS_2:
call change_task
cmp [FDD_IntFlag], 0
jnz @@End_7 ;прерывание произошло
call change_task
mov eax, [timer_ticks]
sub eax, [TickCounter]
cmp eax, 50 ;25 ;5 ;ожидать 5 тиков
/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13,39 → 13,96
; Access through BIOS by diamond
; LBA48 support by Mario79
;-----------------------------------------------------------------------------
struct HD_DATA
hdbase dd ?
hdid dd ?
hdpos dd ?
ends
 
iglobal
align 4
hd_read:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
and [hd_error], 0
push ecx esi edi ; scan cache
ide_callbacks:
dd ide_callbacks.end - ide_callbacks ; strucsize
dd 0 ; no close function
dd 0 ; no closemedia function
dd ide_querymedia
dd ide_read
dd ide_write
dd 0 ; no flush function
dd 0 ; use default cache size
.end:
 
call calculate_cache
add esi, 8
bd_callbacks:
dd bd_callbacks.end - bd_callbacks ; strucsize
dd 0 ; no close function
dd 0 ; no closemedia function
dd bd_querymedia
dd bd_read_interface
dd bd_write_interface
dd 0 ; no flush function
dd 0 ; use default cache size
.end:
 
mov edi, 1
hd0_data HD_DATA ?, 0, 1
hd1_data HD_DATA ?, 0x10, 2
hd2_data HD_DATA ?, 0, 3
hd3_data HD_DATA ?, 0x10, 4
endg
 
hdreadcache:
cmp dword [esi+4], 0 ; empty
je nohdcache
uglobal
ide_mutex MUTEX
ide_channel1_mutex MUTEX
ide_channel2_mutex MUTEX
endg
 
cmp [esi], eax ; correct sector
je yeshdcache
 
nohdcache:
add esi, 8
inc edi
dec ecx
jnz hdreadcache
 
call find_empty_slot ; ret in edi
cmp [hd_error], 0
jne return_01
; Read through BIOS?
cmp [hdpos], 0x80
jae .bios
proc ide_read stdcall uses edi, \
hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data
; buffer = pointer to buffer for data
; startsector = 64-bit start sector
; numsectors = pointer to number of sectors on input,
; must be filled with number of sectors really read
locals
sectors_todo dd ?
channel_lock dd ?
endl
; 1. Initialize number of sectors: get number of requested sectors
; and say that no sectors were read yet.
mov ecx, [numsectors]
mov eax, [ecx]
mov dword [ecx], 0
mov [sectors_todo], eax
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
mov ecx, ide_channel2_mutex
mov eax, [hd_data]
push ecx
mov ecx, [hd_address_table]
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0
pop ecx
jne .IDE_Channel_2
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov [channel_lock], ecx
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
; Underlying procedures do not know about 64-bit sectors.
; Worker procedures use global variables and edi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase]
mov [hdbase], eax
mov eax, [ecx+HD_DATA.hdid]
mov [hdid], eax
mov eax, [ecx+HD_DATA.hdpos]
mov [hdpos], eax
mov eax, dword [startsector]
mov edi, [buffer]
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
.sectors_loop:
; DMA read is permitted if [allow_dma_access]=1 or 2
cmp [allow_dma_access], 2
ja .nodma
55,38 → 112,276
jmp @f
.nodma:
call hd_read_pio
jmp @f
.bios:
call bd_read
@@:
cmp [hd_error], 0
jne return_01
jnz .fail
mov ecx, [numsectors]
inc dword [ecx] ; one more sector is read
dec [sectors_todo]
jz .done
inc eax
jnz .sectors_loop
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
.done:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
call calculate_cache_1
lea esi, [edi*8+esi]
proc ide_write stdcall uses esi edi, \
hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data
; buffer = pointer to buffer with data
; startsector = 64-bit start sector
; numsectors = pointer to number of sectors on input,
; must be filled with number of sectors really written
locals
sectors_todo dd ?
channel_lock dd ?
endl
; 1. Initialize number of sectors: get number of requested sectors
; and say that no sectors were read yet.
mov ecx, [numsectors]
mov eax, [ecx]
mov dword [ecx], 0
mov [sectors_todo], eax
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
mov ecx, ide_channel2_mutex
mov eax, [hd_data]
push ecx
mov ecx, [hd_address_table]
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0
pop ecx
jne .IDE_Channel_2
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov [channel_lock], ecx
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
; Underlying procedures do not know about 64-bit sectors.
; Worker procedures use global variables and esi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase]
mov [hdbase], eax
mov eax, [ecx+HD_DATA.hdid]
mov [hdid], eax
mov eax, [ecx+HD_DATA.hdpos]
mov [hdpos], eax
mov esi, [buffer]
lea edi, [startsector]
mov [cache_chain_ptr], edi
; 4. Worker procedures take max 16 sectors per time,
; loop until all sectors will be processed.
.sectors_loop:
mov ecx, 16
cmp ecx, [sectors_todo]
jbe @f
mov ecx, [sectors_todo]
@@:
mov [cache_chain_size], cl
; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2
jae .nodma
cmp [dma_hdd], 1
jnz .nodma
call cache_write_dma
jmp .common
.nodma:
mov [cache_chain_size], 1
call cache_write_pio
.common:
cmp [hd_error], 0
jnz .fail
movzx ecx, [cache_chain_size]
mov eax, [numsectors]
add [eax], ecx
sub [sectors_todo], ecx
jz .done
add [edi], ecx
jc .fail
shl ecx, 9
add esi, ecx
jmp .sectors_loop
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
.done:
mov ecx, [channel_lock]
call mutex_unlock
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
mov [esi], eax ; sector number
mov dword [esi+4], 1 ; hd read - mark as same as in hd
; This is a stub.
proc ide_querymedia stdcall, hd_data, mediainfo
mov eax, [mediainfo]
mov [eax+DISKMEDIAINFO.Flags], 0
mov [eax+DISKMEDIAINFO.SectorSize], 512
or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
xor eax, eax
ret
endp
 
yeshdcache:
mov esi, edi
shl esi, 9
proc bd_read_interface stdcall uses edi, \
userdata, buffer, startsector:qword, numsectors
; userdata = old [hdpos] = 80h + index in NumBiosDisks
; buffer = pointer to buffer for data
; startsector = 64-bit start sector
; numsectors = pointer to number of sectors on input,
; must be filled with number of sectors really read
locals
sectors_todo dd ?
endl
; 1. Initialize number of sectors: get number of requested sectors
; and say that no sectors were read yet.
mov ecx, [numsectors]
mov eax, [ecx]
mov dword [ecx], 0
mov [sectors_todo], eax
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
; Underlying procedures do not know about 64-bit sectors.
; Worker procedures use global variables and edi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov eax, [userdata]
mov [hdpos], eax
mov eax, dword [startsector]
mov edi, [buffer]
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
.sectors_loop:
call bd_read
cmp [hd_error], 0
jnz .fail
mov ecx, [numsectors]
inc dword [ecx] ; one more sector is read
dec [sectors_todo]
jz .done
inc eax
jnz .sectors_loop
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
.done:
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
push eax
call calculate_cache_2
add esi, eax
pop eax
proc bd_write_interface stdcall uses esi edi, \
userdata, buffer, startsector:qword, numsectors
; userdata = old [hdpos] = 80h + index in NumBiosDisks
; buffer = pointer to buffer with data
; startsector = 64-bit start sector
; numsectors = pointer to number of sectors on input,
; must be filled with number of sectors really written
locals
sectors_todo dd ?
endl
; 1. Initialize number of sectors: get number of requested sectors
; and say that no sectors were read yet.
mov ecx, [numsectors]
mov eax, [ecx]
mov dword [ecx], 0
mov [sectors_todo], eax
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
; Underlying procedures do not know about 64-bit sectors.
; Worker procedures use global variables and esi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
and [hd_error], 0
mov eax, [userdata]
mov [hdpos], eax
mov esi, [buffer]
lea edi, [startsector]
mov [cache_chain_ptr], edi
; 4. Worker procedures take max 16 sectors per time,
; loop until all sectors will be processed.
.sectors_loop:
mov ecx, 16
cmp ecx, [sectors_todo]
jbe @f
mov ecx, [sectors_todo]
@@:
mov [cache_chain_size], cl
call bd_write_cache_chain
cmp [hd_error], 0
jnz .fail
movzx ecx, [cache_chain_size]
mov eax, [numsectors]
add [eax], ecx
sub [sectors_todo], ecx
jz .done
add [edi], ecx
jc .fail
shl ecx, 9
add esi, ecx
jmp .sectors_loop
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, ide_mutex
call mutex_unlock
or eax, -1
ret
.done:
mov ecx, ide_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
mov edi, ebx
mov ecx, 512/4
cld
rep movsd ; move data
; This is a stub.
proc bd_querymedia stdcall, hd_data, mediainfo
mov eax, [mediainfo]
mov [eax+DISKMEDIAINFO.Flags], 0
mov [eax+DISKMEDIAINFO.SectorSize], 512
or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
xor eax, eax
ret
endp
 
return_01:
pop edi esi ecx
ret
;-----------------------------------------------------------------------------
align 4
; input: eax = sector, edi -> buffer
; output: edi = edi + 512
hd_read_pio:
push eax edx
 
184,19 → 479,11
 
pushfd
cli
push edi
shl edi, 9
 
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx, 256
mov edx, [hdbase]
cld
rep insw
pop edi
popfd
 
pop edx eax
203,61 → 490,7
ret
;-----------------------------------------------------------------------------
align 4
hd_write:
;-----------------------------------------------------------
; input : eax = block
; ebx = pointer to memory
;-----------------------------------------------------------
push ecx esi edi
 
; check if the cache already has the sector and overwrite it
call calculate_cache
add esi, 8
mov edi, 1
 
hdwritecache:
cmp dword [esi+4], 0 ; if cache slot is empty
je not_in_cache_write
 
cmp [esi], eax ; if the slot has the sector
je yes_in_cache_write
 
not_in_cache_write:
add esi, 8
inc edi
dec ecx
jnz hdwritecache
 
; sector not found in cache
; write the block to a new location
call find_empty_slot ; ret in edi
cmp [hd_error], 0
jne hd_write_access_denied
 
call calculate_cache_1
lea esi, [edi*8+esi]
mov [esi], eax ; sector number
 
yes_in_cache_write:
mov dword [esi+4], 2 ; write - differs from hd
 
shl edi, 9
 
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov esi, ebx
mov ecx, 512/4
cld
rep movsd ; move data
 
hd_write_access_denied:
pop edi esi ecx
ret
;-----------------------------------------------------------------------------
align 4
; edi -> sector, esi -> data
cache_write_pio:
; Select the desired drive
mov edx, [hdbase]
271,7 → 504,7
jne hd_write_error
 
; ATA with 28 or 48 bit for sector number?
mov eax, [esi]
mov eax, [edi]
cmp eax, 0x10000000
jae .lba48
;--------------------------------------
286,7 → 519,7
inc eax
out dx, al ; ATA Sector Counter счётчик секторов
inc edx
mov eax, [esi] ; eax = sector to write
mov eax, [edi] ; eax = sector to write
out dx, al ; LBA Low LBA (7:0)
shr eax, 8
inc edx
303,7 → 536,6
inc edx
mov al, 30h ; WRITE SECTOR(S)
out dx, al ; ATACommand регистр команд
popfd
jmp .continue
;--------------------------------------
.lba48:
319,7 → 551,7
inc eax
out dx, al ; Sector Count Current Sector count (7:0)
inc edx
mov eax, [esi]
mov eax, [edi]
rol eax, 8
out dx, al ; LBA Low Previous LBA (31:24)
xor eax, eax ; because only 32 bit cache
328,7 → 560,7
inc edx
out dx, al ; LBA High Previous LBA (47:40)
sub edx, 2
mov eax, [esi]
mov eax, [edi]
out dx, al ; LBA Low Current LBA (7:0)
shr eax, 8
inc edx
343,9 → 575,9
inc edx
mov al, 34h ; WRITE SECTOR(S) EXT
out dx, al ; ATACommand регистр команд
popfd
;--------------------------------------
.continue:
popfd
call wait_for_sector_buffer
 
cmp [hd_error], 0
355,14 → 587,6
 
pushfd
cli
mov esi, edi
shl esi, 9
 
push eax
call calculate_cache_2
add esi, eax
pop eax
 
mov ecx, 256
mov edx, [hdbase]
cld
485,6 → 709,9
pop edx eax
ret
;-----------------------------------------------------------------------------
irq14_num equ byte 14
irq15_num equ byte 15
;-----------------------------------------------------------------------------
align 4
wait_for_sector_dma_ide0:
push eax
494,15 → 721,22
align 4
.wait:
call change_task
cmp [irq14_func], hdd_irq14
jnz .done
cmp [IDE_common_irq_param], 0
jz .done
 
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
mov [irq14_func], hdd_irq_null
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
popfd
;--------------------------------------
align 4
.done:
pop edx
pop eax
517,16 → 751,23
align 4
.wait:
call change_task
cmp [irq15_func], hdd_irq15
jnz .done
cmp [IDE_common_irq_param], 0
jz .done
 
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
mov [irq15_func], hdd_irq_null
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
popfd
;--------------------------------------
align 4
.done:
pop edx
pop eax
542,8 → 783,7
 
dma_cur_sector dd not 40h
dma_hdpos dd 0
irq14_func dd hdd_irq_null
irq15_func dd hdd_irq_null
IDE_common_irq_param db 0
endg
;-----------------------------------------------------------------------------
uglobal
560,35 → 800,97
endg
;-----------------------------------------------------------------------------
align 4
hdd_irq14:
IDE_irq_14_handler:
cmp [IDE_common_irq_param], irq14_num
jne .exit
 
pushfd
cli
pushad
mov [irq14_func], hdd_irq_null
; clear Bus Master IDE Command register
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
; clear Bus Master IDE Status register
; clear Interrupt bit
add edx, 2
mov al, 4 ; 100b
out dx, al
 
popad
popfd
;--------------------------------------
align 4
hdd_irq_null:
.exit:
mov al, 1
ret
;-----------------------------------------------------------------------------
align 4
hdd_irq15:
IDE_irq_15_handler:
cmp [IDE_common_irq_param], irq15_num
jne .exit
 
pushfd
cli
pushad
mov [irq15_func], hdd_irq_null
; clear Bus Master IDE Command register
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
; clear Bus Master IDE Status register
; clear Interrupt bit
add edx, 2
mov al, 4 ; 100b
out dx, al
 
popad
popfd
;--------------------------------------
align 4
.exit:
mov al, 1
ret
;-----------------------------------------------------------------------------
align 4
IDE_common_irq_handler:
cmp [IDE_common_irq_param], 0
je .exit
 
pushfd
cli
pushad
; clear Bus Master IDE Command register
xor ebx, ebx
mov dx, [IDEContrRegsBaseAddr]
mov eax, IDE_common_irq_param
cmp [eax], irq14_num
mov [eax], bl
xor eax, eax
je @f
 
add dx, 8
;--------------------------------------
align 4
@@:
out dx, al
; clear Bus Master IDE Status register
; clear Interrupt bit
add edx, 2
mov al, 4 ; 100b
out dx, al
 
popad
popfd
;--------------------------------------
align 4
.exit:
mov al, 1
ret
;-----------------------------------------------------------------------------
align 4
hd_read_dma:
push eax
push edx
605,42 → 907,45
sub eax, [dma_cur_sector]
shl eax, 9
add eax, (OS_BASE+IDE_DMA)
push ecx esi edi
push ecx esi
mov esi, eax
shl edi, 9
 
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx, 512/4
cld
rep movsd
pop edi esi ecx
pop esi ecx
pop edx
pop eax
ret
.notread:
; set data for PRD Table
mov eax, IDE_descriptor_table
mov dword [eax], IDE_DMA
mov word [eax+4], 0x2000
sub eax, OS_BASE
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jz @f
add edx, 8
@@:
push edx
; Bus Master IDE PRD Table Address
add edx, 4
; save IDE_descriptor_table
out dx, eax
pop edx
; clear Bus Master IDE Command register
mov al, 0
out dx, al
; clear Bus Master IDE Status register
; clear Error bit and Interrupt bit
add edx, 2
mov al, 6
mov al, 6 ; 110b
out dx, al
 
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ; адрес регистра головок
728,6 → 1033,7
out dx, al ; ATACommand регистр команд
;--------------------------------------
.continue:
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
734,21 → 1040,27
jz @f
add dx, 8
@@:
; set write to memory and Start Bus Master
mov al, 9
out dx, al
 
mov eax, [CURRENT_TASK]
mov [dma_process], eax
 
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
 
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
 
mov [IDE_common_irq_param], irq14_num
jmp @f
.ide1:
mov [irq15_func], hdd_irq15
mov [IDE_common_irq_param], irq15_num
@@:
popfd
; wait for interrupt
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .wait_ide1
766,24 → 1078,13
mov [dma_cur_sector], eax
jmp hd_read_dma
;-----------------------------------------------------------------------------
align 4
write_cache_sector:
mov [cache_chain_size], 1
mov [cache_chain_pos], edi
;--------------------------------------
align 4
write_cache_chain:
cmp [hdpos], 0x80
jae bd_write_cache_chain
mov eax, [cache_chain_ptr]
cache_write_dma:
mov eax, [cache_chain_ptr] ; for what?
push esi
; set data for PRD Table
mov eax, IDE_descriptor_table
mov edx, eax
pusha
mov esi, [cache_chain_pos]
shl esi, 9
call calculate_cache_2
add esi, eax
mov edi, (OS_BASE+IDE_DMA)
mov dword [edx], IDE_DMA
movzx ecx, [cache_chain_size]
794,21 → 1095,29
rep movsd
popa
sub eax, OS_BASE
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jz @f
add edx, 8
@@:
push edx
; Bus Master IDE PRD Table Address
add edx, 4
; save IDE_descriptor_table
out dx, eax
pop edx
; clear Bus Master IDE Command register
mov al, 0
out dx, al
; clear Bus Master IDE Status register
; clear Error bit and Interrupt bit
add edx, 2
mov al, 6
out dx, al
 
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ; адрес регистра головок
897,6 → 1206,7
out dx, al ; ATACommand регистр команд
;--------------------------------------
.continue:
; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr]
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
903,6 → 1213,7
jz @f
add dx, 8
@@:
; set write to device and Start Bus Master
mov al, 1
out dx, al
mov eax, [CURRENT_TASK]
912,12 → 1223,14
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
 
mov [IDE_common_irq_param], irq14_num
jmp @f
.ide1:
mov [irq15_func], hdd_irq15
mov [IDE_common_irq_param], irq15_num
@@:
popfd
; wait for interrupt
mov [dma_cur_sector], not 0x40
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
933,6 → 1246,8
ret
;-----------------------------------------------------------------------------
uglobal
align 4
IDE_Interrupt dw ?
IDEContrRegsBaseAddr dw ?
IDEContrProgrammingInterface dw ?
IDE_BAR0_val dw ?
965,19 → 1280,12
sub eax, [bios_cur_sector]
shl eax, 9
add eax, (OS_BASE+0x9A000)
push ecx esi edi
push ecx esi
mov esi, eax
shl edi, 9
 
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx, 512/4
cld
rep movsd
pop edi esi ecx
pop esi ecx
pop edx
pop eax
ret
1006,10 → 1314,6
align 4
bd_write_cache_chain:
pusha
mov esi, [cache_chain_pos]
shl esi, 9
call calculate_cache_2
add esi, eax
mov edi, OS_BASE + 0x9A000
movzx ecx, [cache_chain_size]
push ecx
1041,7 → 1345,7
int13_call:
; Because this code uses fixed addresses,
; it can not be run simultaniously by many threads.
; In current implementation it is protected by common mutex 'hd1_status'
; In current implementation it is protected by common mutex 'ide_status'
mov word [OS_BASE + 510h], 10h ; packet length
mov word [OS_BASE + 512h], cx ; number of sectors
mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000
1088,82 → 1392,3
@@:
ret
; \end{diamond}
;-----------------------------------------------------------------------------
align 4
reserve_hd1:
cli
cmp [hd1_status], 0
je reserve_ok1
 
sti
call change_task
jmp reserve_hd1
 
reserve_ok1:
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
mov [hd1_status], eax
pop eax
sti
ret
;-----------------------------------------------------------------------------
uglobal
hd_in_cache db ?
endg
;-----------------------------------------------------------------------------
align 4
reserve_hd_channel:
; BIOS disk accesses are protected with common mutex hd1_status
; This must be modified when hd1_status will not be valid!
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1], 0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2], 0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_2
.reserve_ok_1:
mov [IDE_Channel_1], 1
push eax
mov al, 1
jmp @f
.reserve_ok_2:
mov [IDE_Channel_2], 1
push eax
mov al, 3
@@:
cmp [hdid], 1
sbb al, -1
mov [hd_in_cache], al
pop eax
sti
.ret:
ret
;-----------------------------------------------------------------------------
free_hd_channel:
; see comment at reserve_hd_channel
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
.ret:
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
ret
;-----------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc
23,546 → 23,7
 
$Revision$
 
 
align 4
write_cache:
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
push eax ecx edx esi edi
 
; write difference ( 2 ) from cache to hd
call calculate_cache
add esi, 8
mov edi, 1
write_cache_more:
cmp dword [esi+4], 2; if cache slot is not different
jne .write_chain
mov dword [esi+4], 1; same as in hd
mov eax, [esi] ; eax = sector to write
cmp eax, [PARTITION_START]
jb danger
cmp eax, [PARTITION_END]
ja danger
cmp [hdpos], 0x80
jae @f
; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2
jae .nodma
cmp [dma_hdd], 1
jnz .nodma
@@:
; Объединяем запись цепочки последовательных секторов в одно обращение к диску
cmp ecx, 1
jz .nonext
cmp dword [esi+8+4], 2
jnz .nonext
push eax
inc eax
cmp eax, [esi+8]
pop eax
jnz .nonext
cmp [cache_chain_started], 1
jz @f
mov [cache_chain_started], 1
mov [cache_chain_size], 0
mov [cache_chain_pos], edi
mov [cache_chain_ptr], esi
@@:
inc [cache_chain_size]
cmp [cache_chain_size], 16
jnz .continue
jmp .write_chain
.nonext:
call flush_cache_chain
mov [cache_chain_size], 1
mov [cache_chain_ptr], esi
call write_cache_sector
jmp .continue
.nodma:
call cache_write_pio
.write_chain:
call flush_cache_chain
.continue:
danger:
add esi, 8
inc edi
dec ecx
jnz write_cache_more
call flush_cache_chain
return_02:
pop edi esi edx ecx eax
ret
 
flush_cache_chain:
cmp [cache_chain_started], 0
jz @f
call write_cache_chain
mov [cache_chain_started], 0
@@:
ret
;--------------------------------------------------------------------
align 4
find_empty_slot:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
; output : edi = cache slot
;-----------------------------------------------------------
; push ecx esi
 
search_again:
call calculate_cache_3
shr ecx, 3
search_for_empty:
inc edi
call calculate_cache_4
jbe inside_cache
mov edi, 1
inside_cache:
push esi
call calculate_cache_1
cmp dword [edi*8+esi+4], 2
pop esi
jb found_slot ; it's empty or read
dec ecx
jnz search_for_empty
call write_cache ; no empty slots found, write all
cmp [hd_error], 0
jne found_slot_access_denied
jmp search_again ; and start again
found_slot:
call calculate_cache_5
found_slot_access_denied:
ret
;--------------------------------------------------------------------
align 4
calculate_cache:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov esi, [cache_ide0_pointer]
ret
.ide0_appl_data:
mov ecx, [cache_ide0_appl_sad_size]
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx, [cache_ide1_appl_sad_size]
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx, [cache_ide2_appl_sad_size]
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx, [cache_ide3_appl_sad_size]
mov esi, [cache_ide3_data_pointer]
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov ecx, [cache_ide0_system_sad_size-cache_ide0+eax]
mov esi, [cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov ecx, [cache_ide0_appl_sad_size-cache_ide0+eax]
mov esi, [cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
;--------------------------------------------------------------------
align 4
calculate_cache_1:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov esi, [cache_ide0_pointer]
ret
.ide0_appl_data:
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi, [cache_ide3_data_pointer]
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov esi, [cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov esi, [cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
 
;--------------------------------------------------------------------
align 4
calculate_cache_2:
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov eax, [cache_ide0_system_data]
ret
.ide0_appl_data:
mov eax, [cache_ide0_appl_data]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov eax, [cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax, [cache_ide1_appl_data]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov eax, [cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax, [cache_ide2_appl_data]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov eax, [cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax, [cache_ide3_appl_data]
ret
.noide:
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov eax, [cache_ide0_system_data-cache_ide0+eax]
ret
.bd_appl_data:
mov eax, [cache_ide0_appl_data-cache_ide0+eax]
ret
;--------------------------------------------------------------------
align 4
calculate_cache_3:
; mov ecx,cache_max*10/100
; mov edi,[cache_search_start]
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov edi, [cache_ide0_search_start]
ret
.ide0_appl_data:
mov ecx, [cache_ide0_appl_sad_size]
mov edi, [cache_ide0_appl_search_start]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov edi, [cache_ide1_search_start]
ret
.ide1_appl_data:
mov ecx, [cache_ide1_appl_sad_size]
mov edi, [cache_ide1_appl_search_start]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov edi, [cache_ide2_search_start]
ret
.ide2_appl_data:
mov ecx, [cache_ide2_appl_sad_size]
mov edi, [cache_ide2_appl_search_start]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov edi, [cache_ide3_search_start]
ret
.ide3_appl_data:
mov ecx, [cache_ide3_appl_sad_size]
mov edi, [cache_ide3_appl_search_start]
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov ecx, [cache_ide0_system_sad_size-cache_ide0+eax]
mov edi, [cache_ide0_search_start-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov ecx, [cache_ide0_appl_sad_size-cache_ide0+eax]
mov edi, [cache_ide0_appl_search_start-cache_ide0+eax]
pop eax
ret
;--------------------------------------------------------------------
align 4
calculate_cache_4:
; cmp edi,cache_max
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
cmp edi, [cache_ide0_system_sad_size]
ret
.ide0_appl_data:
cmp edi, [cache_ide0_appl_sad_size]
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
cmp edi, [cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi, [cache_ide1_appl_sad_size]
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
cmp edi, [cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi, [cache_ide2_appl_sad_size]
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
cmp edi, [cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi, [cache_ide3_appl_sad_size]
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
cmp edi, [cache_ide0_system_sad_size-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
cmp edi, [cache_ide0_appl_sad_size-cache_ide0+eax]
pop eax
ret
 
;--------------------------------------------------------------------
align 4
calculate_cache_5:
; mov [cache_search_start],edi
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov [cache_ide0_search_start], edi
ret
.ide0_appl_data:
mov [cache_ide0_appl_search_start], edi
ret
.ide1:
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov [cache_ide1_search_start], edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start], edi
ret
.ide2:
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov [cache_ide2_search_start], edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start], edi
ret
.ide3:
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov [cache_ide3_search_start], edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start], edi
ret
.noide:
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov [cache_ide0_search_start-cache_ide0+eax], edi
pop eax
ret
.bd_appl_data:
mov [cache_ide0_appl_search_start-cache_ide0+eax], edi
pop eax
ret
 
;--------------------------------------------------------------------
align 4
find_empty_slot_CD_cache:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write