forked from KolibriOS/kolibrios
Rustem Gimadutdinov (rgimad)
73864ff1d7
git-svn-id: svn://kolibrios.org@9019 a494cfbc-eb01-0410-851d-a64ba20cac60
281 lines
8.8 KiB
PHP
281 lines
8.8 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
$Revision$
|
|
|
|
search_partitions:
|
|
push ecx
|
|
; 1. Fill missing parameters in HD_DATA structures.
|
|
xor eax, eax
|
|
mov edx, IDE_controller_1
|
|
mov ax, [edx + IDE_DATA.BAR0_val]
|
|
mov [hd0_data.hdbase], ax
|
|
mov [hd1_data.hdbase], ax
|
|
mov ax, [edx + IDE_DATA.BAR2_val]
|
|
mov [hd2_data.hdbase], ax
|
|
mov [hd3_data.hdbase], ax
|
|
|
|
mov edx, IDE_controller_2
|
|
mov ax, [edx + IDE_DATA.BAR0_val]
|
|
mov [hd4_data.hdbase], ax
|
|
mov [hd5_data.hdbase], ax
|
|
mov ax, [edx + IDE_DATA.BAR2_val]
|
|
mov [hd6_data.hdbase], ax
|
|
mov [hd7_data.hdbase], ax
|
|
|
|
mov edx, IDE_controller_3
|
|
mov ax, [edx + IDE_DATA.BAR0_val]
|
|
mov [hd8_data.hdbase], ax
|
|
mov [hd9_data.hdbase], ax
|
|
mov ax, [edx + IDE_DATA.BAR2_val]
|
|
mov [hd10_data.hdbase], ax
|
|
mov [hd11_data.hdbase], ax
|
|
; 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 @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
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 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 @f
|
|
|
|
push 'hd1'
|
|
mov eax, esp
|
|
mov edx, hd1_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+3], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 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
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 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
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 2e. /hd4: exists if mask 0x40 in [DRIVE_DATA+6] is set,
|
|
; data: hd4_data,
|
|
; number of partitions: [DRIVE_DATA+7]
|
|
test [DRIVE_DATA+6], byte 0x40
|
|
jz @f
|
|
|
|
push 'hd4'
|
|
mov eax, esp ; name
|
|
mov edx, hd4_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+7], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 2f. /hd5: exists if mask 0x10 in [DRIVE_DATA+6] is set,
|
|
; data: hd5_data,
|
|
; number of partitions: [DRIVE_DATA+8]
|
|
test [DRIVE_DATA+6], byte 0x10
|
|
jz @f
|
|
|
|
push 'hd5'
|
|
mov eax, esp
|
|
mov edx, hd5_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+8], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 2g. /hd6: exists if mask 4 in [DRIVE_DATA+6] is set,
|
|
; data: hd6_data,
|
|
; number of partitions: [DRIVE_DATA+9]
|
|
test [DRIVE_DATA+6], byte 4
|
|
jz @f
|
|
|
|
push 'hd6'
|
|
mov eax, esp
|
|
mov edx, hd6_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+9], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 2h. /hd7: exists if mask 1 in [DRIVE_DATA+6] is set,
|
|
; data: hd7_data,
|
|
; number of partitions: [DRIVE_DATA+10]
|
|
test [DRIVE_DATA+6], byte 1
|
|
jz @f
|
|
|
|
push 'hd7'
|
|
mov eax, esp
|
|
mov edx, hd7_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+10], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 2i. /hd8: exists if mask 0x40 in [DRIVE_DATA+11] is set,
|
|
; data: hd8_data,
|
|
; number of partitions: [DRIVE_DATA+12]
|
|
test [DRIVE_DATA+11], byte 0x40
|
|
jz @f
|
|
|
|
push 'hd8'
|
|
mov eax, esp ; name
|
|
mov edx, hd8_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+12], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 2j. /hd9: exists if mask 0x10 in [DRIVE_DATA+11] is set,
|
|
; data: hd9_data,
|
|
; number of partitions: [DRIVE_DATA+13]
|
|
test [DRIVE_DATA+11], byte 0x10
|
|
jz @f
|
|
|
|
push 'hd9'
|
|
mov eax, esp
|
|
mov edx, hd9_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+13], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 2k. /hd10: exists if mask 4 in [DRIVE_DATA+11] is set,
|
|
; data: hd10_data,
|
|
; number of partitions: [DRIVE_DATA+14]
|
|
test [DRIVE_DATA+14], byte 4
|
|
jz @f
|
|
|
|
push 'hd10'
|
|
mov eax, esp
|
|
mov edx, hd10_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+9], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 2l. /hd11: exists if mask 1 in [DRIVE_DATA+11] is set,
|
|
; data: hd11_data,
|
|
; number of partitions: [DRIVE_DATA+15]
|
|
test [DRIVE_DATA+11], byte 1
|
|
jz @f
|
|
|
|
push 'hd11'
|
|
mov eax, esp
|
|
mov edx, hd11_data
|
|
call ide_disk_add
|
|
mov [DRIVE_DATA+15], al
|
|
pop ecx
|
|
;-----------------------------------------------------------------------------
|
|
@@:
|
|
; 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.
|
|
lea eax, [esi*4]
|
|
movzx eax, [BiosDisksData+eax*4+BiosDiskData.DriveNumber]
|
|
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'
|
|
@@:
|
|
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
|
|
;-----------------------------------------------------------------------------
|
|
; 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
|
|
endp
|
|
;-----------------------------------------------------------------------------
|
|
end_search_partitions:
|
|
pop ecx
|