Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 2267 → Rev 2268

/kernel/branches/Kolibri-acpi/vmodeint.inc
File deleted
Property changes:
Deleted: svn:keywords
-Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/vmodeld.inc
File deleted
Property changes:
Deleted: svn:keywords
-Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev/disk.inc
5,16 → 5,16
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2140 $
$Revision: 2257 $
 
; =============================================================================
; ================================= Constants =================================
; =============================================================================
; Error codes for callback functions.
DISK_STATUS_OK = 0 ; success
DISK_STATUS_OK = 0 ; success
DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable
DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters
DISK_STATUS_NO_MEDIA = 2 ; no media present
DISK_STATUS_NO_MEDIA = 2 ; no media present
DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data
; Driver flags. Represent bits in DISK.DriverFlags.
DISK_NO_INSERT_NOTIFICATION = 1
21,10 → 21,10
; Media flags. Represent bits in DISKMEDIAINFO.Flags.
DISK_MEDIA_READONLY = 1
 
; If we see too many partitions, probably there is some error on the disk.
; If too many partitions are detected,there is probably an error on the disk.
; 256 partitions should be enough for any reasonable use.
; Also, the same number is limiting the number of MBRs to process; if we see
; too many MBRs, probably there is a loop in the MBR structure.
; Also, the same number is limiting the number of MBRs to process; if
; too many MBRs are visible,there probably is a loop in the MBR structure.
MAX_NUM_PARTITIONS = 256
 
; =============================================================================
34,17 → 34,17
; device. They are implemented by a driver. Objects with this structure reside
; in a driver.
struct DISKFUNC
.strucsize dd ?
.strucsize dd ?
; Size of the structure. This field is intended for possible extensions of
; this structure. If a new function is added to this structure and a driver
; implements an old version, the caller can detect this by checking .strucsize,
; so the driver remains compatible.
.close dd ?
.close dd ?
; The pointer to the function which frees all driver-specific resources for
; the disk.
; Optional, may be NULL.
; void close(void* userdata);
.closemedia dd ?
.closemedia dd ?
; The pointer to the function which informs the driver that the kernel has
; finished all processing with the current media. If media is removed, the
; driver should decline all requests to that media with DISK_STATUS_NO_MEDIA,
53,17 → 53,17
; function is called.
; Optional, may be NULL (if media is not removable).
; void closemedia(void* userdata);
.querymedia dd ?
.querymedia dd ?
; The pointer to the function which determines capabilities of the media.
; int querymedia(void* userdata, DISKMEDIAINFO* info);
; Return value: one of DISK_STATUS_*
.read dd ?
.read dd ?
; The pointer to the function which reads data from the device.
; int read(void* userdata, void* buffer, __int64 startsector, int* numsectors);
; input: *numsectors = number of sectors to read
; output: *numsectors = number of sectors which were successfully read
; Return value: one of DISK_STATUS_*
.write dd ?
.write dd ?
; The pointer to the function which writes data to the device.
; Optional, may be NULL.
; int write(void* userdata, void* buffer, __int64 startsector, int* numsectors);
70,7 → 70,7
; input: *numsectors = number of sectors to write
; output: *numsectors = number of sectors which were successfully written
; Return value: one of DISK_STATUS_*
.flush dd ?
.flush dd ?
; The pointer to the function which flushes the internal device cache.
; Optional, may be NULL.
; int flush(void* userdata);
78,7 → 78,7
; Note that read/write are called by the cache manager, so a driver should not
; create a software cache. This function is implemented for flushing a hardware
; cache, if it exists.
.adjust_cache_size dd ?
.adjust_cache_size dd ?
; The pointer to the function which returns the cache size for this device.
; Optional, may be NULL.
; unsigned int adjust_cache_size(unsigned int suggested_size);
85,30 → 85,30
; Return value: 0 = disable cache, otherwise = used cache size in bytes.
ends
 
; This structure holds an information about a media.
; Objects with this structure are allocated by the kernel as a part of DISK
; structure and filled by a driver in the 'querymedia' callback.
; This structure holds information on a medium.
; Objects with this structure are allocated by the kernel as a part of the DISK
; structure and are filled by a driver in the 'querymedia' callback.
struct DISKMEDIAINFO
.Flags dd ?
.Flags dd ?
; Combination of DISK_MEDIA_* bits.
.SectorSize dd ?
.SectorSize dd ?
; Size of the sector.
.Capacity dq ?
.Capacity dq ?
; Size of the media in sectors.
ends
 
; This structure represents disk cache. To follow the old implementation,
; there are two distinct caches for a disk, one for "system" data, other
; This structure represents the disk cache. To follow the old implementation,
; there are two distinct caches for a disk, one for "system" data,and the other
; for "application" data.
struct DISKCACHE
.Lock MUTEX
.Lock MUTEX
; Lock to protect the cache.
; The following fields are inherited from data32.inc:cache_ideX.
.pointer rd 1
.data_size rd 1 ; not use
.data rd 1
.data rd 1
.sad_size rd 1
.search_start rd 1
.search_start rd 1
ends
 
; This structure represents a disk device and its media for the kernel.
116,23 → 116,23
; freed in the 'disk_dereference' function.
struct DISK
; Fields of disk object
.Next dd ?
.Prev dd ?
.Next dd ?
.Prev dd ?
; All disk devices are linked in one list with these two fields.
; Head of the list is the 'disk_list' variable.
.Functions dd ?
.Functions dd ?
; Pointer to the 'DISKFUNC' structure with driver functions.
.Name dd ?
.Name dd ?
; Pointer to the string used for accesses through the global filesystem.
.UserData dd ?
.UserData dd ?
; This field is passed to all callback functions so a driver can decide which
; physical device is addressed.
.DriverFlags dd ?
.DriverFlags dd ?
; Bitfield. Currently only DISK_NO_INSERT_NOTIFICATION bit is defined.
; If it is set, the driver will never issue 'disk_media_changed' notification
; with argument set to true, so the kernel must try to detect media during
; requests from the file system.
.RefCount dd ?
.RefCount dd ?
; Count of active references to this structure. One reference is kept during
; the lifetime of the structure between 'disk_add' and 'disk_del'.
; Another reference is taken during any filesystem operation for this disk.
140,37 → 140,37
; The structure is destroyed when the reference count decrements to zero:
; this usually occurs in 'disk_del', but can be delayed to the end of last
; filesystem operation, if one is active.
.MediaLock MUTEX
.MediaLock MUTEX
; Lock to protect the MEDIA structure. See the description after
; 'disk_list_mutex' for the locking strategy.
; Fields of media object
.MediaInserted db ?
.MediaInserted db ?
; 0 if media is not inserted, nonzero otherwise.
.MediaUsed db ?
.MediaUsed db ?
; 0 if media fields are not used, nonzero otherwise. If .MediaRefCount is
; nonzero, this field is nonzero too; however, when .MediaRefCount goes
; to zero, there is some time interval during which media object is still used.
align 4
align 4
; The following fields are not valid unless either .MediaInserted is nonzero
; or they are accessed from a code which has obtained the reference when
; .MediaInserted was nonzero.
.MediaRefCount dd ?
.MediaRefCount dd ?
; Count of active references to the media object. One reference is kept during
; the lifetime of the media between two calls to 'disk_media_changed'.
; Another reference is taken during any filesystem operation for this media.
; The callback 'closemedia' is called when the reference count decrements to
; zero: this usually occurs in 'disk_media_changed', but can be delayed to the
; end of last filesystem operation, if one is active.
.MediaInfo DISKMEDIAINFO
; This field keeps an information about the current media.
.NumPartitions dd ?
; end of the last filesystem operation, if one is active.
.MediaInfo DISKMEDIAINFO
; This field keeps information on the current media.
.NumPartitions dd ?
; Number of partitions on this media.
.Partitions dd ?
.Partitions dd ?
; Pointer to array of .NumPartitions pointers to PARTITION structures.
.cache_size dd ?
.cache_size dd ?
; inherited from cache_ideX_size
.SysCache DISKCACHE
.AppCache DISKCACHE
.SysCache DISKCACHE
.AppCache DISKCACHE
; Two caches for the disk.
ends
 
178,13 → 178,13
; template, the actual contents after common fields is determined by the
; file system code for this partition.
struct PARTITION
.FirstSector dq ?
.FirstSector dq ?
; First sector of the partition.
.Length dq ?
.Length dq ?
; Length of the partition in sectors.
.Disk dd ?
.Disk dd ?
; Pointer to parent DISK structure.
.FSUserFunctions dd ?
.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
; point to handlers of corresponding subfunctions.
194,23 → 194,23
 
; This is an external structure, it represents an entry in the partition table.
struct PARTITION_TABLE_ENTRY
.Bootable db ?
.Bootable db ?
; 80h = bootable partition, 0 = non-bootable partition, other values = invalid
.FirstHead db ?
.FirstSector db ?
.FirstTrack db ?
.FirstHead db ?
.FirstSector db ?
.FirstTrack db ?
; Coordinates of first sector in CHS.
.Type db ?
.Type db ?
; Partition type, one of predefined constants. 0 = empty, several types denote
; extended partition (see process_partition_table_entry), we are not interested
; in other values.
.LastHead db ?
.LastSector db ?
.LastTrack db ?
.LastHead db ?
.LastSector db ?
.LastTrack db ?
; Coordinates of last sector in CHS.
.FirstAbsSector dd ?
.FirstAbsSector dd ?
; Coordinate of first sector in LBA.
.Length dd ?
.Length dd ?
; Length of the partition in sectors.
ends
 
221,15 → 221,15
; The pseudo-item for the list of all DISK structures.
; Initialized to the empty list.
disk_list:
dd disk_list
dd disk_list
dd disk_list
dd disk_list
endg
uglobal
; This mutex guards all operations with the global list of DISK structures.
disk_list_mutex MUTEX
; * There are two dependent objects, a disk and a media. In the simplest case
; * There are two dependent objects, a disk and a media. In the simplest case,
; disk and media are both non-removable. However, in the general case both
; can be removed at any time, simultaneously or only media, this makes things
; can be removed at any time, simultaneously or only media,and this makes things
; complicated.
; * For efficiency, both disk and media objects are located in the one
; structure named DISK. However, logically they are different.
284,14 → 284,14
; decrements the value when the job is done. Otherwise, it immediately
; decrements the value and uses buffers from the heap, allocated in the
; beginning and freed in the end.
partition_buffer_users dd -1
partition_buffer_users dd -1
endg
uglobal
; The static buffers for MBR, bootsector and fs-temporary sector data.
align 16
mbr_buffer rb 512
bootsect_buffer rb 512
fs_tmp_buffer rb 512
mbr_buffer rb 512
bootsect_buffer rb 512
fs_tmp_buffer rb 512
endg
 
iglobal
300,13 → 300,13
; have the default implementations.
align 4
disk_default_callbacks:
dd disk_default_close
dd disk_default_closemedia
dd disk_default_querymedia
dd disk_default_read
dd disk_default_write
dd disk_default_flush
dd disk_default_adjust_cache_size
dd disk_default_close
dd disk_default_closemedia
dd disk_default_querymedia
dd disk_default_read
dd disk_default_write
dd disk_default_flush
dd disk_default_adjust_cache_size
endg
 
; =============================================================================
332,79 → 332,79
; in the operations with other Disk* functions.
; The handle is the pointer to the internal structure DISK.
disk_add:
push ebx esi ; save used registers to be stdcall
push ebx esi ; save used registers to be stdcall
; 1. Allocate the DISK structure.
; 1a. Call the heap manager.
push sizeof.DISK
pop eax
call malloc
push sizeof.DISK
pop eax
call malloc
; 1b. Check the result. If allocation failed, return (go to 9) with eax = 0.
test eax, eax
jz .nothing
; 2. Copy disk name to the DISK structure.
test eax, eax
jz .nothing
; 2. Copy the disk name to the DISK structure.
; 2a. Get length of the name, including the terminating zero.
mov ebx, [esp+8+8] ; ebx = pointer to name
push eax ; save allocated pointer to DISK
xor eax, eax ; the argument of malloc() is in eax
mov ebx, [esp+8+8] ; ebx = pointer to name
push eax ; save allocated pointer to DISK
xor eax, eax ; the argument of malloc() is in eax
@@:
inc eax
cmp byte [ebx+eax-1], 0
jnz @b
inc eax
cmp byte [ebx+eax-1], 0
jnz @b
; 2b. Call the heap manager.
call malloc
call malloc
; 2c. Check the result. If allocation failed, go to 7.
pop esi ; restore allocated pointer to DISK
test eax, eax
jz .free
pop esi ; restore allocated pointer to DISK
test eax, eax
jz .free
; 2d. Store the allocated pointer to the DISK structure.
mov [esi+DISK.Name], eax
mov [esi+DISK.Name], eax
; 2e. Copy the name.
@@:
mov dl, [ebx]
mov [eax], dl
inc ebx
inc eax
test dl, dl
jnz @b
mov dl, [ebx]
mov [eax], dl
inc ebx
inc eax
test dl, dl
jnz @b
; 3. Copy other arguments of the function to the DISK structure.
mov eax, [esp+4+8]
mov [esi+DISK.Functions], eax
mov eax, [esp+12+8]
mov [esi+DISK.UserData], eax
mov eax, [esp+16+8]
mov [esi+DISK.DriverFlags], eax
mov eax, [esp+4+8]
mov [esi+DISK.Functions], eax
mov eax, [esp+12+8]
mov [esi+DISK.UserData], eax
mov eax, [esp+16+8]
mov [esi+DISK.DriverFlags], eax
; 4. Initialize other fields of the DISK structure.
; Media is not inserted, reference counter is 1.
lea ecx, [esi+DISK.MediaLock]
call mutex_init
xor eax, eax
mov dword [esi+DISK.MediaInserted], eax
inc eax
mov [esi+DISK.RefCount], eax
lea ecx, [esi+DISK.MediaLock]
call mutex_init
xor eax, eax
mov dword [esi+DISK.MediaInserted], eax
inc eax
mov [esi+DISK.RefCount], eax
; The DISK structure is initialized.
; 5. Insert the new structure to the global list.
; 5a. Acquire the mutex.
mov ecx, disk_list_mutex
call mutex_lock
mov ecx, disk_list_mutex
call mutex_lock
; 5b. Insert item to the tail of double-linked list.
mov edx, disk_list
list_add_tail esi, edx ;esi= new edx= list head
mov edx, disk_list
list_add_tail esi, edx ;esi= new edx= list head
; 5c. Release the mutex.
call mutex_unlock
call mutex_unlock
; 6. Return with eax = pointer to DISK.
xchg eax, esi
jmp .nothing
xchg eax, esi
jmp .nothing
.free:
; Memory allocation for DISK structure succeeded, but for disk name failed.
; 7. Free the DISK structure.
xchg eax, esi
call free
xchg eax, esi
call free
; 8. Return with eax = 0.
xor eax, eax
xor eax, eax
.nothing:
; 9. Return.
pop esi ebx ; restore used registers to be stdcall
ret 16 ; purge 4 dword arguments to be stdcall
pop esi ebx ; restore used registers to be stdcall
ret 16 ; purge 4 dword arguments to be stdcall
 
; This function deletes a disk device from the global filesystem.
; This includes:
415,29 → 415,29
; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure.
; Return value: none.
disk_del:
push esi ; save used registers to be stdcall
push esi ; save used registers to be stdcall
; 1. Force media to be removed. If the media is already removed, the
; call does nothing.
mov esi, [esp+4+8] ; esi = handle of the disk
stdcall disk_media_changed, esi, 0
mov esi, [esp+4+8] ; esi = handle of the disk
stdcall disk_media_changed, esi, 0
; 2. Delete the structure from the global list.
; 2a. Acquire the mutex.
mov ecx, disk_list_mutex
call mutex_lock
mov ecx, disk_list_mutex
call mutex_lock
; 2b. Delete item from double-linked list.
mov eax, [esi+DISK.Next]
mov edx, [esi+DISK.Prev]
mov [eax+DISK.Prev], edx
mov [edx+DISK.Next], eax
mov eax, [esi+DISK.Next]
mov edx, [esi+DISK.Prev]
mov [eax+DISK.Prev], edx
mov [edx+DISK.Next], eax
; 2c. Release the mutex.
call mutex_unlock
call mutex_unlock
; 3. The structure still has one reference created in disk_add. Remove this
; reference. If there are no other references, disk_dereference will free the
; structure.
call disk_dereference
call disk_dereference
; 4. Return.
pop esi ; restore used registers to be stdcall
ret 4 ; purge 1 dword argument to be stdcall
pop esi ; restore used registers to be stdcall
ret 4 ; purge 1 dword argument to be stdcall
 
; This is an internal function which removes a previously obtained reference
; to the disk. If this is the last reference, this function lets the driver
446,21 → 446,21
disk_dereference:
; 1. Decrement reference counter. Use atomic operation to correctly handle
; possible simultaneous calls.
lock dec [esi+DISK.RefCount]
lock dec [esi+DISK.RefCount]
; 2. If the result is nonzero, there are other references, so nothing to do.
; In this case, return (go to 4).
jnz .nothing
jnz .nothing
; 3. If we are here, we just removed the last reference and must destroy the
; disk object.
; 3a. Call the driver.
mov al, DISKFUNC.close
stdcall disk_call_driver
mov al, DISKFUNC.close
stdcall disk_call_driver
; 3b. Free the structure.
xchg eax, esi
call free
xchg eax, esi
call free
; 4. Return.
.nothing:
ret
ret
 
; This is an internal function which removes a previously obtained reference
; to the media. If this is the last reference, this function calls 'closemedia'
470,10 → 470,10
disk_media_dereference:
; 1. Decrement reference counter. Use atomic operation to correctly handle
; possible simultaneous calls.
lock dec [esi+DISK.MediaRefCount]
lock dec [esi+DISK.MediaRefCount]
; 2. If the result is nonzero, there are other references, so nothing to do.
; In this case, return (go to 4).
jnz .nothing
jnz .nothing
; 3. If we are here, we just removed the last reference and must destroy the
; media object.
; Note that the same place inside the DISK structure is reused for all media
492,27 → 492,27
; does not matter when this flag is cleared. In the second case this flag must
; be cleared after all other actions, including call to 'closemedia'.
; 3a. Free all partitions.
push esi edi
mov edi, [esi+DISK.NumPartitions]
mov esi, [esi+DISK.Partitions]
test edi, edi
jz .nofree
push esi edi
mov edi, [esi+DISK.NumPartitions]
mov esi, [esi+DISK.Partitions]
test edi, edi
jz .nofree
.freeloop:
lodsd
call free
dec edi
jnz .freeloop
lodsd
call free
dec edi
jnz .freeloop
.nofree:
pop edi esi
pop edi esi
; 3b. Free the cache.
call disk_free_cache
call disk_free_cache
; 3c. Call the driver.
mov al, DISKFUNC.closemedia
stdcall disk_call_driver
mov al, DISKFUNC.closemedia
stdcall disk_call_driver
; 3d. Clear the flag.
mov [esi+DISK.MediaUsed], 0
mov [esi+DISK.MediaUsed], 0
.nothing:
ret
ret
 
; This function is called by the driver and informs the kernel that the media
; has changed. If the media is non-removable, it is called exactly once
521,28 → 521,28
; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure.
; [esp+8] = new status of the media: zero = no media, nonzero = media inserted.
disk_media_changed:
push ebx esi edi ; save used registers to be stdcall
push ebx esi edi ; save used registers to be stdcall
; 1. Remove the existing media, if it is present.
mov esi, [esp+4+12] ; esi = pointer to DISK
mov esi, [esp+4+12] ; esi = pointer to DISK
; 1a. Check whether it is present. Since DISK.MediaInserted is changed only
; in this function and calls to this function are synchronized, no lock is
; required for checking.
cmp [esi+DISK.MediaInserted], 0
jz .noremove
cmp [esi+DISK.MediaInserted], 0
jz .noremove
; We really need to remove the media.
; 1b. Acquire mutex.
lea ecx, [esi+DISK.MediaLock]
call mutex_lock
lea ecx, [esi+DISK.MediaLock]
call mutex_lock
; 1c. Clear the flag.
mov [esi+DISK.MediaInserted], 0
mov [esi+DISK.MediaInserted], 0
; 1d. Release mutex.
call mutex_unlock
call mutex_unlock
; 1e. Remove the "lifetime" reference and possibly destroy the structure.
call disk_media_dereference
call disk_media_dereference
.noremove:
; 2. Test whether there is new media.
cmp dword [esp+8+12], 0
jz .noinsert
cmp dword [esp+8+12], 0
jz .noinsert
; Yep, there is.
; 3. Process the new media. We assume that all media fields are available to
; use, see comments in 'disk_media_dereference' (this covers using by previous
550,28 → 550,28
; (this covers using by new media referencers).
; 3a. Call the 'querymedia' callback.
; .Flags are set to zero for possible future extensions.
lea edx, [esi+DISK.MediaInfo]
and [edx+DISKMEDIAINFO.Flags], 0
mov al, DISKFUNC.querymedia
stdcall disk_call_driver, edx
lea edx, [esi+DISK.MediaInfo]
and [edx+DISKMEDIAINFO.Flags], 0
mov al, DISKFUNC.querymedia
stdcall disk_call_driver, edx
; 3b. Check the result of the callback. Abort if it failed.
test eax, eax
jnz .noinsert
test eax, eax
jnz .noinsert
; 3c. Allocate the cache unless disabled by the driver. Abort if failed.
call disk_init_cache
test al, al
jz .noinsert
call disk_init_cache
test al, al
jz .noinsert
; 3d. Acquire the lifetime reference for the media object.
inc [esi+DISK.MediaRefCount]
inc [esi+DISK.MediaRefCount]
; 3e. Scan for partitions. Ignore result; the list of partitions is valid even
; on errors.
call disk_scan_partitions
call disk_scan_partitions
; 3f. Media is inserted and available for use.
inc [esi+DISK.MediaInserted]
inc [esi+DISK.MediaInserted]
.noinsert:
; 4. Return.
pop edi esi ebx ; restore used registers to be stdcall
ret 8 ; purge 2 dword arguments to be stdcall
pop edi esi ebx ; restore used registers to be stdcall
ret 8 ; purge 2 dword arguments to be stdcall
 
; This function is a thunk for all functions of a disk driver.
; It checks whether the referenced function is implemented in the driver.
582,37 → 582,37
; stack is the same as for the corresponding function except that the
; first parameter (void* userdata) is prepended automatically.
disk_call_driver:
movzx eax, al ; eax = offset of function in the DISKFUNC structure
movzx eax, al ; eax = offset of function in the DISKFUNC structure
; 1. Prepend the first argument to the stack.
pop ecx ; ecx = return address
push [esi+DISK.UserData] ; add argument
push ecx ; save return address
pop ecx ; ecx = return address
push [esi+DISK.UserData] ; add argument
push ecx ; save return address
; 2. Check that the required function is inside the table. If not, go to 5.
mov ecx, [esi+DISK.Functions]
cmp eax, [ecx+DISKFUNC.strucsize]
jae .default
mov ecx, [esi+DISK.Functions]
cmp eax, [ecx+DISKFUNC.strucsize]
jae .default
; 3. Check that the required function is implemented. If not, go to 5.
mov ecx, [ecx+eax]
test ecx, ecx
jz .default
mov ecx, [ecx+eax]
test ecx, ecx
jz .default
; 4. Jump to the required function.
jmp ecx
jmp ecx
.default:
; 5. Driver does not implement the required function; use default implementation.
jmp dword [disk_default_callbacks+eax-4]
jmp dword [disk_default_callbacks+eax-4]
 
; The default implementation of DISKFUNC.querymedia.
disk_default_querymedia:
push DISK_STATUS_INVALID_CALL
pop eax
ret 8
push DISK_STATUS_INVALID_CALL
pop eax
ret 8
 
; The default implementation of DISKFUNC.read and DISKFUNC.write.
disk_default_read:
disk_default_write:
push DISK_STATUS_INVALID_CALL
pop eax
ret 20
push DISK_STATUS_INVALID_CALL
pop eax
ret 20
 
; The default implementation of DISKFUNC.close, DISKFUNC.closemedia and
; DISKFUNC.flush.
619,15 → 619,15
disk_default_close:
disk_default_closemedia:
disk_default_flush:
xor eax, eax
ret 4
xor eax, eax
ret 4
 
; The default implementation of DISKFUNC.adjust_cache_size.
disk_default_adjust_cache_size:
mov eax, [esp+4]
ret 4
mov eax, [esp+4]
ret 4
 
; This is an internal function called from 'disk_media_changed' when new media
; This is an internal function called from 'disk_media_changed' when a new media
; is detected. It creates the list of partitions for the media.
; If media is not partitioned, then the list consists of one partition which
; covers all the media.
634,26 → 634,26
; esi = pointer to the DISK structure.
disk_scan_partitions:
; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list.
and [esi+DISK.NumPartitions], 0
and [esi+DISK.Partitions], 0
and [esi+DISK.NumPartitions], 0
and [esi+DISK.Partitions], 0
; 2. Currently we can work only with 512-bytes sectors. Check this restriction.
; The only exception is 2048-bytes CD/DVD, but they are not supported yet by
; this code.
cmp [esi+DISK.MediaInfo.SectorSize], 512
jz .doscan
DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize]
ret
cmp [esi+DISK.MediaInfo.SectorSize], 512
jz .doscan
DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize]
ret
.doscan:
; 3. Acquire the buffer for MBR and bootsector tests. See the comment before
; the 'partition_buffer_users' variable.
mov ebx, mbr_buffer ; assume the global buffer is free
lock inc [partition_buffer_users]
jz .buffer_acquired ; yes, it is free
lock dec [partition_buffer_users] ; no, we must allocate
stdcall kernel_alloc, 512*3
test eax, eax
jz .nothing
xchg eax, ebx
mov ebx, mbr_buffer ; assume the global buffer is free
lock inc [partition_buffer_users]
jz .buffer_acquired ; yes, it is free
lock dec [partition_buffer_users] ; no, we must allocate
stdcall kernel_alloc, 512*3
test eax, eax
jz .nothing
xchg eax, ebx
.buffer_acquired:
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no
; more than MAX_NUM_PARTITION times.
662,36 → 662,36
; [esp] will hold the sector number for current extended partition, if there
; is one.
; [esp+4] will hold the counter that prevents long loops.
push ebp ; save ebp
push MAX_NUM_PARTITIONS ; the counter of max MBRs to process
xor ebp, ebp ; start from sector zero
push ebp ; no extended partition yet
push ebp ; save ebp
push MAX_NUM_PARTITIONS ; the counter of max MBRs to process
xor ebp, ebp ; start from sector zero
push ebp ; no extended partition yet
.new_mbr:
; 5. Read the current sector.
; Note that 'read' callback operates with 64-bit sector numbers, so we must
; push additional zero as a high dword of sector number.
mov al, DISKFUNC.read
push 1
stdcall disk_call_driver, ebx, ebp, 0, esp
pop ecx
mov al, DISKFUNC.read
push 1
stdcall disk_call_driver, ebx, ebp, 0, esp
pop ecx
; 6. If the read has failed, abort the loop.
dec ecx
jnz .mbr_failed
dec ecx
jnz .mbr_failed
; 7. Check the MBR/EBR signature. If it is wrong, abort the loop.
; Soon we will access the partition table which starts at ebx+0x1BE,
; so we can fill its address right now. If we do it now, then the addressing
; [ecx+0x40] is shorter than [ebx+0x1fe]: one-byte offset vs 4-bytes offset.
lea ecx, [ebx+0x1be] ; ecx -> partition table
cmp word [ecx+0x40], 0xaa55
jnz .mbr_failed
lea ecx, [ebx+0x1be] ; ecx -> partition table
cmp word [ecx+0x40], 0xaa55
jnz .mbr_failed
; 8. The MBR is treated differently from EBRs. For MBR we additionally need to
; execute step 9 and possibly step 10.
test ebp, ebp
jnz .mbr
; Partition table can be present or not present. In the first case, we just
; read the MBR. In the second case, we just read the bootsector for some
test ebp, ebp
jnz .mbr
; The partition table can be present or not present. In the first case, we just
; read the MBR. In the second case, we just read the bootsector for a
; filesystem.
; We use the following algorithm to distinguish between these cases.
; The following algorithm is used to distinguish between these cases.
; A. If at least one entry of the partition table is invalid, this is
; a bootsector. See the description of 'is_partition_table_entry' for
; definition of validity.
698,53 → 698,53
; B. If all entries are empty (filesystem type field is zero) and the first
; byte is jmp opcode (0EBh or 0E9h), this is a bootsector which happens to
; have zeros in the place of partition table.
; C. Otherwise, this is a MBR.
; C. Otherwise, this is an MBR.
; 9. Test for MBR vs bootsector.
; 9a. Check entries. If any is invalid, go to 10 (rule A).
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
; 9b. Check types of the entries. If at least one is nonzero, go to 11 (rule C).
mov al, [ecx-30h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx-20h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx-10h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx+PARTITION_TABLE_ENTRY.Type]
jnz .mbr
mov al, [ecx-30h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx-20h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx-10h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx+PARTITION_TABLE_ENTRY.Type]
jnz .mbr
; 9c. Empty partition table or bootsector with many zeroes? (rule B)
cmp byte [ebx], 0EBh
jz .notmbr
cmp byte [ebx], 0E9h
jnz .mbr
cmp byte [ebx], 0EBh
jz .notmbr
cmp byte [ebx], 0E9h
jnz .mbr
.notmbr:
; 10. This is not MBR. The media is not partitioned. Create one partition
; 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]
jmp .done
stdcall disk_add_partition, 0, 0, \
dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4]
jmp .done
.mbr:
; 11. Process all entries of the new MBR/EBR
lea ecx, [ebx+0x1be] ; ecx -> partition table
push 0 ; assume no extended partition
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
pop ebp
lea ecx, [ebx+0x1be] ; ecx -> partition table
push 0 ; assume no extended partition
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
pop ebp
; 12. Test whether we found a new EBR and should continue the loop.
; 12a. If there was no next EBR, return.
test ebp, ebp
jz .done
test ebp, ebp
jz .done
; Ok, we have EBR.
; 12b. EBRs addresses are relative to the start of extended partition.
; For simplicity, just abort if an 32-bit overflow occurs; large disks
751,38 → 751,38
; are most likely partitioned with GPT, not MBR scheme, since the precise
; calculation here would increase limit just twice at the price of big
; compatibility problems.
pop eax ; load extended partition
add ebp, eax
jc .mbr_failed
pop eax ; load extended partition
add ebp, eax
jc .mbr_failed
; 12c. If extended partition has not yet started, start it.
test eax, eax
jnz @f
mov eax, ebp
test eax, eax
jnz @f
mov eax, ebp
@@:
; 12c. If the limit is not exceeded, continue the loop.
dec dword [esp]
push eax ; store extended partition
jnz .new_mbr
dec dword [esp]
push eax ; store extended partition
jnz .new_mbr
.mbr_failed:
.done:
; 13. Cleanup after the loop.
pop eax ; not important anymore
pop eax ; not important anymore
pop ebp ; restore ebp
pop eax ; not important anymore
pop eax ; not important anymore
pop ebp ; restore ebp
; 14. Release the buffer.
; 14a. Test whether it is the global buffer or we have allocated it.
cmp ebx, mbr_buffer
jz .release_partition_buffer
cmp ebx, mbr_buffer
jz .release_partition_buffer
; 14b. If we have allocated it, free it.
xchg eax, ebx
call free
jmp .nothing
xchg eax, ebx
call free
jmp .nothing
; 14c. Otherwise, release reference.
.release_partition_buffer:
lock dec [partition_buffer_users]
lock dec [partition_buffer_users]
.nothing:
; 15. Return.
ret
ret
 
; This is an internal function called from disk_scan_partitions. It checks
; whether the entry pointed to by ecx is a valid entry of partition table.
792,33 → 792,33
; greater than the real size.
is_partition_table_entry:
; 1. Check .Bootable field.
mov al, [ecx+PARTITION_TABLE_ENTRY.Bootable]
and al, 7Fh
jnz .invalid
mov al, [ecx+PARTITION_TABLE_ENTRY.Bootable]
and al, 7Fh
jnz .invalid
; 3. Calculate first sector + length. Note that .FirstAbsSector is relative
; to the MBR/EBR, so the real sum is ebp + .FirstAbsSector + .Length.
mov eax, ebp
xor edx, edx
add eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
adc edx, 0
add eax, [ecx+PARTITION_TABLE_ENTRY.Length]
adc edx, 0
mov eax, ebp
xor edx, edx
add eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
adc edx, 0
add eax, [ecx+PARTITION_TABLE_ENTRY.Length]
adc edx, 0
; 4. Divide by two.
shr edx, 1
rcr eax, 1
shr edx, 1
rcr eax, 1
; 5. Compare with capacity. If the subtraction (edx:eax) - .Capacity does not
; overflow, this is bad.
sub eax, dword [esi+DISK.MediaInfo.Capacity]
sbb edx, dword [esi+DISK.MediaInfo.Capacity+4]
jnc .invalid
sub eax, dword [esi+DISK.MediaInfo.Capacity]
sbb edx, dword [esi+DISK.MediaInfo.Capacity+4]
jnc .invalid
.valid:
; 5. Return success: CF is cleared.
clc
ret
clc
ret
.invalid:
; 6. Return fail: CF is set.
stc
ret
stc
ret
 
; This is an internal function called from disk_scan_partitions. It processes
; the entry pointed to by ecx.
831,40 → 831,40
; fs-specific checks do this more reliably.
process_partition_table_entry:
; 1. Check for valid entry. If invalid, return (go to 5).
call is_partition_table_entry
jc .nothing
call is_partition_table_entry
jc .nothing
; 2. Check for empty entry. If invalid, return (go to 5).
mov al, [ecx+PARTITION_TABLE_ENTRY.Type]
test al, al
jz .nothing
mov al, [ecx+PARTITION_TABLE_ENTRY.Type]
test al, al
jz .nothing
; 3. Check for extended partition. If extended, go to 6.
irp type,\
0x05,\ ; DOS: extended partition
0x0f,\ ; WIN95: extended partition, LBA-mapped
0xc5,\ ; DRDOS/secured: extended partition
0xd5 ; Old Multiuser DOS secured: extended partition
0x05,\ ; DOS: extended partition
0x0f,\ ; WIN95: extended partition, LBA-mapped
0xc5,\ ; DRDOS/secured: extended partition
0xd5 ; Old Multiuser DOS secured: extended partition
{
cmp al, type
jz .extended
cmp al, type
jz .extended
}
; 4. If we are here, that is a normal partition. Add it to the list.
; Note that the first sector is relative to MBR/EBR.
mov eax, ebp
xor edx, edx
add eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
adc edx, 0
push ecx
stdcall disk_add_partition, eax, edx, \
[ecx+PARTITION_TABLE_ENTRY.Length], 0
pop ecx
mov eax, ebp
xor edx, edx
add eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
adc edx, 0
push ecx
stdcall disk_add_partition, eax, edx, \
[ecx+PARTITION_TABLE_ENTRY.Length], 0
pop ecx
.nothing:
; 5. Return.
ret
ret
.extended:
; 6. If we are here, that is an extended partition. Store the address.
mov eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
mov [esp+4], eax
ret
mov eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
mov [esp+4], eax
ret
 
; This is an internal function called from disk_scan_partitions and
; process_partition_table_entry. It adds one partition to the list of
871,8 → 871,8
; partitions for the media.
proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword
; 1. Check that this partition will not exceed the limit on total number.
cmp [esi+DISK.NumPartitions], MAX_NUM_PARTITIONS
jae .nothing
cmp [esi+DISK.NumPartitions], MAX_NUM_PARTITIONS
jae .nothing
; 2. Check that this partition does not overlap with any already registered
; partition. Since any file system assumes that the disk data will not change
; outside of its control, such overlap could be destructive.
880,31 → 880,31
; to be large, the simple linear search is sufficient.
; 2a. Prepare the loop: edi will point to the current item of .Partitions
; array, ecx will be the current item, ebx will hold number of items left.
mov edi, [esi+DISK.Partitions]
mov ebx, [esi+DISK.NumPartitions]
test ebx, ebx
jz .partitionok
mov edi, [esi+DISK.Partitions]
mov ebx, [esi+DISK.NumPartitions]
test ebx, ebx
jz .partitionok
.scan_existing:
; 2b. Get the next partition.
mov ecx, [edi]
add edi, 4
mov ecx, [edi]
add edi, 4
; The range [.FirstSector, .FirstSector+.Length) must be either entirely to
; the left of [start, start+length) or entirely to the right.
; 2c. Subtract .FirstSector - start. The possible overflow distinguish between
; cases "to the left" (2e) and "to the right" (2d).
mov eax, dword [ecx+PARTITION.FirstSector]
mov edx, dword [ecx+PARTITION.FirstSector+4]
sub eax, dword [start]
sbb edx, dword [start+4]
jb .less
mov eax, dword [ecx+PARTITION.FirstSector]
mov edx, dword [ecx+PARTITION.FirstSector+4]
sub eax, dword [start]
sbb edx, dword [start+4]
jb .less
; 2d. .FirstSector is greater than or equal to start. Check that .FirstSector
; is greater than or equal to start+length; the subtraction
; (.FirstSector-start) - length must not cause overflow. Go to 2g if life is
; good or to 2f in the other case.
sub eax, dword [length]
sbb edx, dword [length+4]
jb .overlap
jmp .next_existing
sub eax, dword [length]
sbb edx, dword [length+4]
jb .overlap
jmp .next_existing
.less:
; 2e. .FirstSector is less than start. Check that .FirstSector+.Length is less
; than or equal to start. If the addition (.FirstSector-start) + .Length does
911,57 → 911,57
; not cause overflow, then .FirstSector + .Length is strictly less than start;
; since the equality is also valid, use decrement preliminarily. Go to 2g or
; 2f depending on the overflow.
sub eax, 1
sbb edx, 0
add eax, dword [ecx+PARTITION.Length]
adc edx, dword [ecx+PARTITION.Length+4]
jnc .next_existing
sub eax, 1
sbb edx, 0
add eax, dword [ecx+PARTITION.Length]
adc edx, dword [ecx+PARTITION.Length+4]
jnc .next_existing
.overlap:
; 2f. The partition overlaps with previously registered partition. Say warning
; and return with nothing done.
dbgstr 'two partitions overlap, ignoring the last one'
jmp .nothing
dbgstr 'two partitions overlap, ignoring the last one'
jmp .nothing
.next_existing:
; 2g. The partition does not overlap with the current partition. Continue the
; loop.
dec ebx
jnz .scan_existing
dec ebx
jnz .scan_existing
.partitionok:
; 3. The partition has passed tests. Reallocate the partitions array for a new
; entry.
; 3a. Call the allocator.
mov eax, [esi+DISK.NumPartitions]
inc eax ; one more entry
shl eax, 2 ; each entry is dword
call malloc
mov eax, [esi+DISK.NumPartitions]
inc eax ; one more entry
shl eax, 2 ; each entry is dword
call malloc
; 3b. Test the result. If failed, return with nothing done.
test eax, eax
jz .nothing
test eax, eax
jz .nothing
; 3c. Copy the old array to the new array.
mov edi, eax
push esi
mov ecx, [esi+DISK.NumPartitions]
mov esi, [esi+DISK.Partitions]
rep movsd
pop esi
mov edi, eax
push esi
mov ecx, [esi+DISK.NumPartitions]
mov esi, [esi+DISK.Partitions]
rep movsd
pop esi
; 3d. Set the field in the DISK structure to the new array.
xchg [esi+DISK.Partitions], eax
xchg [esi+DISK.Partitions], eax
; 3e. Free the old array.
call free
call free
; 4. Recognize the file system.
; 4a. Call the filesystem recognizer. It will allocate the PARTITION structure
; with possible filesystem-specific fields.
call disk_detect_partition
call disk_detect_partition
; 4b. Check return value. If zero, return with list not changed; so far only
; the array was reallocated, this is ok for other code.
test eax, eax
jz .nothing
test eax, eax
jz .nothing
; 5. Insert the new partition to the list.
stosd
inc [esi+DISK.NumPartitions]
stosd
inc [esi+DISK.NumPartitions]
; 6. Return.
.nothing:
ret
ret
endp
 
; This is an internal function called from disk_add_partition.
972,29 → 972,29
; with ebp-based frame arguments start from ebp+8, since [ebp]=saved ebp
; and [ebp+4]=return address.
virtual at ebp+8
.start dq ?
.length dq ?
.start dq ?
.length dq ?
end virtual
; Currently no file systems are supported, so just allocate the PARTITION
; structure without extra fields.
; 1. Allocate and check result.
push sizeof.PARTITION
pop eax
call malloc
test eax, eax
jz .nothing
push sizeof.PARTITION
pop eax
call malloc
test eax, eax
jz .nothing
; 2. Fill the common fields: copy .start and .length.
mov edx, dword [.start]
mov dword [eax+PARTITION.FirstSector], edx
mov edx, dword [.start+4]
mov dword [eax+PARTITION.FirstSector+4], edx
mov edx, dword [.length]
mov dword [eax+PARTITION.Length], edx
mov edx, dword [.length+4]
mov dword [eax+PARTITION.Length+4], edx
mov edx, dword [.start]
mov dword [eax+PARTITION.FirstSector], edx
mov edx, dword [.start+4]
mov dword [eax+PARTITION.FirstSector+4], edx
mov edx, dword [.length]
mov dword [eax+PARTITION.Length], edx
mov edx, dword [.length+4]
mov dword [eax+PARTITION.Length+4], edx
.nothing:
; 3. Return with eax = pointer to PARTITION or NULL.
ret
ret
 
; This function is called from file_system_lfn.
; This handler gets the control each time when fn 70 is called
1005,127 → 1005,127
; but instead pop return address and return directly to the caller
; otherwise simply return
dyndisk_handler:
push ebx edi ; save registers used in file_system_lfn
push ebx edi ; save registers used in file_system_lfn
; 1. Acquire the mutex.
mov ecx, disk_list_mutex
call mutex_lock
mov ecx, disk_list_mutex
call mutex_lock
; 2. Loop over the list of DISK structures.
; 2a. Initialize.
mov ebx, disk_list
mov ebx, disk_list
.scan:
; 2b. Get the next item.
mov ebx, [ebx+DISK.Next]
mov ebx, [ebx+DISK.Next]
; 2c. Check whether the list is done. If so, go to 3.
cmp ebx, disk_list
jz .notfound
cmp ebx, disk_list
jz .notfound
; 2d. Compare names. If names match, go to 5.
mov edi, [ebx+DISK.Name]
push esi
mov edi, [ebx+DISK.Name]
push esi
@@:
; esi points to the name from fs operation; it is terminated by zero or slash.
lodsb
test al, al
jz .eoin_dec
cmp al, '/'
jz .eoin
lodsb
test al, al
jz .eoin_dec
cmp al, '/'
jz .eoin
; edi points to the disk name.
inc edi
inc edi
; edi points to lowercase name, this is a requirement for the driver.
; Characters at esi can have any register. Lowercase the current character.
; This lowercasing works for latin letters and digits; since the disk name
; should not contain other symbols, this is ok.
or al, 20h
cmp al, [edi-1]
jz @b
or al, 20h
cmp al, [edi-1]
jz @b
.wrongname:
; 2f. Names don't match. Continue the loop.
pop esi
jmp .scan
pop esi
jmp .scan
.notfound:
; The loop is done and no name matches.
; 3. Release the mutex.
call mutex_unlock
call mutex_unlock
; 4. Return normally.
pop edi ebx ; restore registers used in file_system_lfn
ret
pop edi ebx ; restore registers used in file_system_lfn
ret
; part of 2d: the name matches partially, but we must check that this is full
; equality.
.eoin_dec:
dec esi
dec esi
.eoin:
cmp byte [edi], 0
jnz .wrongname
cmp byte [edi], 0
jnz .wrongname
; We found the addressed DISK structure.
; 5. Reference the disk.
lock inc [ebx+DISK.RefCount]
lock inc [ebx+DISK.RefCount]
; 6. Now we are sure that the DISK structure is not going to die at least
; while we are working with it, so release the global mutex.
call mutex_unlock
call mutex_unlock
; 7. Acquire the mutex for media object.
pop edi ; restore edi
lea ecx, [ebx+DISK.MediaLock]
call mutex_lock
pop edi ; restore edi
lea ecx, [ebx+DISK.MediaLock]
call mutex_lock
; 8. Get the media object. If it is not NULL, reference it.
xor edx, edx
cmp [ebx+DISK.MediaInserted], dl
jz @f
mov edx, ebx
inc [ebx+DISK.MediaRefCount]
xor edx, edx
cmp [ebx+DISK.MediaInserted], dl
jz @f
mov edx, ebx
inc [ebx+DISK.MediaRefCount]
@@:
; 9. Now we are sure that the media object, if it exists, is not going to die
; at least while we are working with it, so release the mutex for media object.
call mutex_unlock
mov ecx, ebx
pop ebx eax ; restore ebx, pop return address
call mutex_unlock
mov ecx, ebx
pop ebx eax ; restore ebx, pop return address
; 10. Check whether the fs operation wants to enumerate partitions (go to 11)
; or work with some concrete partition (go to 12).
cmp byte [esi], 0
jnz .haspartition
cmp byte [esi], 0
jnz .haspartition
; 11. The fs operation wants to enumerate partitions.
; 11a. Only "list directory" operation is applicable to /<diskname> path. Check
; the operation code. If wrong, go to 13.
cmp dword [ebx], 1
jnz .access_denied
cmp dword [ebx], 1
jnz .access_denied
; 11b. If the media is inserted, use 'fs_dyndisk_next' as an enumeration
; procedure. Otherwise, use 'fs_dyndisk_next_nomedia'.
mov esi, fs_dyndisk_next_nomedia
test edx, edx
jz @f
mov esi, fs_dyndisk_next
mov esi, fs_dyndisk_next_nomedia
test edx, edx
jz @f
mov esi, fs_dyndisk_next
@@:
; 11c. Let the procedure from fs_lfn.inc do the job.
jmp file_system_lfn.maindir_noesi
jmp file_system_lfn.maindir_noesi
.haspartition:
; 12. The fs operation has specified some partition.
; 12a. Store parameters for callback functions.
push edx
push ecx
push edx
push ecx
; 12b. Store callback functions.
push dyndisk_cleanup
push fs_dyndisk
mov edi, esp
push dyndisk_cleanup
push fs_dyndisk
mov edi, esp
; 12c. Let the procedure from fs_lfn.inc do the job.
jmp file_system_lfn.found2
jmp file_system_lfn.found2
.access_denied:
; 13. Fail the operation with the appropriate code.
mov dword [esp+32], ERROR_ACCESS_DENIED
mov dword [esp+32], ERROR_ACCESS_DENIED
.cleanup:
; 14. Cleanup.
mov esi, ecx ; disk*dereference assume that esi points to DISK
mov esi, ecx ; disk*dereference assume that esi points to DISK
.cleanup_esi:
test edx, edx ; if there are no media, we didn't reference it
jz @f
call disk_media_dereference
test edx, edx ; if there are no media, we didn't reference it
jz @f
call disk_media_dereference
@@:
call disk_dereference
call disk_dereference
; 15. Return.
ret
ret
 
; This is a callback for cleaning up things called from file_system_lfn.found2.
dyndisk_cleanup:
mov esi, [edi+8]
mov edx, [edi+12]
jmp dyndisk_handler.cleanup_esi
mov esi, [edi+8]
mov edx, [edi+12]
jmp dyndisk_handler.cleanup_esi
 
; This is a callback for enumerating partitions called from
; file_system_lfn.maindir in the case of inserted media.
1132,36 → 1132,36
; It just increments eax until DISK.NumPartitions reached and then
; cleans up.
fs_dyndisk_next:
cmp eax, [ecx+DISK.NumPartitions]
jae .nomore
inc eax
clc
ret
cmp eax, [ecx+DISK.NumPartitions]
jae .nomore
inc eax
clc
ret
.nomore:
pusha
mov esi, ecx
call disk_media_dereference
call disk_dereference
popa
stc
ret
pusha
mov esi, ecx
call disk_media_dereference
call disk_dereference
popa
stc
ret
 
; This is a callback for enumerating partitions called from
; file_system_lfn.maindir in the case of missing media.
; In this case we create one pseudo-partition.
fs_dyndisk_next_nomedia:
cmp eax, 1
jae .nomore
inc eax
clc
ret
cmp eax, 1
jae .nomore
inc eax
clc
ret
.nomore:
pusha
mov esi, ecx
call disk_dereference
popa
stc
ret
pusha
mov esi, ecx
call disk_dereference
popa
stc
ret
 
; This is a callback for doing real work with selected partition.
; Currently this is just placeholder, since no file systems are supported.
1168,54 → 1168,54
; edi = esp -> {dd fs_dyndisk, dd dyndisk_cleanup, dd pointer to DISK, dd media object}
; ecx = partition number, esi+ebp = ASCIIZ name
fs_dyndisk:
dec ecx ; convert to zero-based partition index
pop edx edx edx eax ; edx = pointer to DISK, eax = NULL or edx
test eax, eax
jz .nomedia
dec ecx ; convert to zero-based partition index
pop edx edx edx eax ; edx = pointer to DISK, eax = NULL or edx
test eax, eax
jz .nomedia
.main:
cmp ecx, [edx+DISK.NumPartitions]
jae .notfound
mov dword [esp+32], ERROR_UNKNOWN_FS
cmp ecx, [edx+DISK.NumPartitions]
jae .notfound
mov dword [esp+32], ERROR_UNKNOWN_FS
.cleanup:
mov esi, edx
call disk_media_dereference
call disk_dereference
ret
mov esi, edx
call disk_media_dereference
call disk_dereference
ret
.notfound:
mov dword [esp+32], ERROR_FILE_NOT_FOUND
jmp .cleanup
mov dword [esp+32], ERROR_FILE_NOT_FOUND
jmp .cleanup
.nomedia:
test ecx, ecx
jnz .notfound
test byte [edx+DISK.DriverFlags], DISK_NO_INSERT_NOTIFICATION
jz .deverror
test ecx, ecx
jnz .notfound
test byte [edx+DISK.DriverFlags], DISK_NO_INSERT_NOTIFICATION
jz .deverror
; if the driver does not support insert notifications and we are the only fs
; operation with this disk, issue the fake insert notification; if media is
; still not inserted, 'disk_media_changed' will detect this and do nothing
;;; push ebx
lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaRefCount], 1
jnz .noluck
call mutex_unlock
push edx
stdcall disk_media_changed, edx, 1
pop edx
lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaInserted], 0
jz .noluck
lock inc [edx+DISK.MediaRefCount]
call mutex_unlock
xor ecx, ecx
jmp .main
lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaRefCount], 1
jnz .noluck
call mutex_unlock
push edx
stdcall disk_media_changed, edx, 1
pop edx
lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaInserted], 0
jz .noluck
lock inc [edx+DISK.MediaRefCount]
call mutex_unlock
xor ecx, ecx
jmp .main
.noluck:
call mutex_unlock
call mutex_unlock
.deverror:
mov dword [esp+32], ERROR_DEVICE
mov esi, edx
call disk_dereference
ret
mov dword [esp+32], ERROR_DEVICE
mov esi, edx
call disk_dereference
ret
 
; This function is called from file_system_lfn.
; This handler is called when virtual root is enumerated
1225,34 → 1225,34
; out: eax = 0 => no more items
; eax != 0 => buffer pointed to by edi contains name of item
dyndisk_enum_root:
push edx ; save register used in file_system_lfn
mov ecx, disk_list_mutex ; it will be useful
push edx ; save register used in file_system_lfn
mov ecx, disk_list_mutex ; it will be useful
; 1. If this is the first call, acquire the mutex and initialize.
test eax, eax
jnz .notfirst
call mutex_lock
mov eax, disk_list
test eax, eax
jnz .notfirst
call mutex_lock
mov eax, disk_list
.notfirst:
; 2. Get next item.
mov eax, [eax+DISK.Next]
mov eax, [eax+DISK.Next]
; 3. If there are no more items, go to 6.
cmp eax, disk_list
jz .last
cmp eax, disk_list
jz .last
; 4. Copy name from the DISK structure to edi.
push eax esi
mov esi, [eax+DISK.Name]
push eax esi
mov esi, [eax+DISK.Name]
@@:
lodsb
stosb
test al, al
jnz @b
pop esi eax
lodsb
stosb
test al, al
jnz @b
pop esi eax
; 5. Return with eax = item.
pop edx ; restore register used in file_system_lfn
ret
pop edx ; restore register used in file_system_lfn
ret
.last:
; 6. Release the mutex and return with eax = 0.
call mutex_unlock
xor eax, eax
pop edx ; restore register used in file_system_lfn
ret
call mutex_unlock
xor eax, eax
pop edx ; restore register used in file_system_lfn
ret
/kernel/branches/Kolibri-acpi/boot/bootcode.inc
552,11 → 552,11
adc byte [di+preboot_dma-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
cmp byte [di+preboot_vrrm-preboot_device], 0
jnz @f
mov byte [di+preboot_vrrm-preboot_device], 2
@@:
;; default value for VRR is OFF
; cmp byte [di+preboot_vrrm-preboot_device], 0
; jnz @f
; mov byte [di+preboot_vrrm-preboot_device], 2
;@@:
; notify user
_setcursor 5,2
 
584,9 → 584,9
mov si, usebd_msg
cmp [preboot_biosdisk], 1
call .say_on_off
mov si, vrrm_msg
cmp [preboot_vrrm], 1
call .say_on_off
; mov si, vrrm_msg
; cmp [preboot_vrrm], 1
; call .say_on_off
mov si, preboot_device_msg
call print
mov al, [preboot_device]
674,9 → 674,9
jz .change_a
cmp al, 'b'
jz .change_b
cmp al, 'c'
jz .change_c
cmp al, 'd'
; cmp al, 'c'
; jz .change_c
cmp al, 'c' ; 'd'
jnz .show_remarks
_setcursor 15,0
mov si, bdev
784,15 → 784,15
mov [preboot_biosdisk], al
_setcursor 11,0
jmp .d
.change_c:
_setcursor 15,0
mov si, vrrmprint
call print
mov bx, '12'
call getkey
mov [preboot_vrrm], al
_setcursor 12,0
jmp .d
;.change_c:
; _setcursor 15,0
; mov si, vrrmprint
; call print
; mov bx, '12'
; call getkey
; mov [preboot_vrrm], al
; _setcursor 12,0
; jmp .d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.say_on_off:
pushf
947,10 → 947,10
mov al, [preboot_dma]
mov [es:0x901F], al
 
; VRR_M USE
 
mov al,[preboot_vrrm]
mov [es:0x9030], al
;; VRR_M USE
;
; mov al,[preboot_vrrm]
; mov [es:0x9030], al
mov [es:0x901E], byte 1
 
; BOOT DEVICE
/kernel/branches/Kolibri-acpi/boot/booteng.inc
23,43 → 23,27
d80x25_bottom_num = 3
 
msg_apm db " APM x.x ", 0
vervesa db "Version of Vesa: Vesa x.x",13,10,0
novesa db "Display: EGA/CGA",13,10,0
s_vesa db "Version of VESA: "
.ver db "?.?",13,10,0
 
gr_mode db "Select a videomode: ",13,10,0
;s_bpp db 13,10,186," ƒ«ã¡¨­  梥â : "
; .bpp dw "??"
; db 13,10,0
 
vrrmprint db "Apply VRR? (picture frequency greater than 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0
 
 
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
 
if defined extended_primary_loader
bdev db "Load ramdisk from [1-floppy; 2-kolibri.img]: ",0
else
bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-use preloaded ram-image from kernel restart;"
db 13,10,186," "
db "4-create blank image]: ",0
else
bdev db "Load ramdisk from [1-floppy; 2-kolibri.img]: ",0
end if
probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, "
db "2-probe bios (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
 
prnotfnd db "Fatal - Videomode not found.",0
;modena db "Fatal - VBE 0x112+ required.",0
 
not386 db "Fatal - CPU 386+ required.",0
btns db "Fatal - Can't determine color depth.",0
fatalsel db "Fatal - Graphics mode not supported by hardware.",0
pres_key db "Press any key to choose a new videomode.",0
badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0
77,21 → 61,15
current_cfg_msg db "Current settings:",13,10,0
curvideo_msg db " [a] Videomode: ",0
 
;modes_msg dw mode4,mode1,mode2,mode3
;modevesa20 db " with LFB",0
;modevesa12 db ", VESA 1.2 Bnk",0
mode0 db "320x200, EGA/CGA 256 colors",13,10,0
mode9 db "640x480, VGA 16 colors",13,10,0
 
;probeno_msg db " (standard mode)",0
;probeok_msg db " (check nonstandard modes)",0
;dma_msg db " [b] Use DMA for HDD access:",0
usebd_msg db " [b] Add disks visible by BIOS:",0
on_msg db " on",13,10,0
off_msg db " off",13,10,0
;readonly_msg db " only for reading",13,10,0
vrrm_msg db " [c] Use VRR:",0
preboot_device_msg db " [d] Floppy image: ",0
 
preboot_device_msg db " [c] Floppy image: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 db "real floppy",13,10,0
103,7 → 81,9
pdm3 db "use already loaded image",13,10,0
pdm4 db "create blank image",13,10,0
end if
 
loading_msg db "Loading KolibriOS...",0
 
if ~ defined extended_primary_loader
save_quest db "Remember current settings? [y/n]: ",0
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0
116,7 → 96,6
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
remark2 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/bootet.inc
13,43 → 13,24
 
$Revision$
 
 
d80x25_bottom:
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
db 'NO WARRANTY ',186
db 186,' See file COPYING for details '
db 186,' KolibriOS pohineb MenuetOS ja kaasas IGASUGUSE GARANTI'
db 'ITA ',186
db 186,' Naha faili COPYING detailid '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
msg_apm db " APM x.x ", 0
novesa db "Ekraan: EGA/CGA",13,10,0
vervesa db "Vesa versioon: Vesa x.x",13,10,0
vervesa_off=20
msg_apm db " APM x.x ", 0
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 värvi: [9] 320x200, "
db "VGA 16 värvi: [0] 640x480",13,10
db 186," Vali reziim: ",0
bt24 db "Bitti pikseli kohta: 24",13,10,0
bt32 db "Bitti pikseli kohta: 32",13,10,0
vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz"
db " ainult:",13,10
db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0
;askmouse db " Hiir:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Vali port [1-3]: ",0
;no_com1 db 13,10,186, " No COM1 mouse",0
;no_com2 db 13,10,186, " No COM2 mouse",0
;ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-no]: ",0
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
;gr_direct db 186," Use direct LFB writing? "
; db "[1-yes/2-no] ? ",0
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
s_vesa db "Vesa versioon: "
.ver db "?.?",13,10,0
 
gr_mode db "Vali videomode: ",13,10,0
 
ask_bd db "Lisa kettad nahtavaks BIOS reziim V86? [1-jah, 2-no]: ",0
 
if defined extended_primary_loader
bdev db "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0
else
59,18 → 40,12
db 13,10,186," "
db "4-loo tühi pilt]: ",0
end if
probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, "
db "2-leia biosist (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
 
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0
;modena db "Fataalne - VBE 0x112+ on vajalik.",0
 
not386 db "Fataalne - CPU 386+ on vajalik.",0
btns db "Fataalne - Ei suuda värvisügavust määratleda.",0
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0
pres_key db "Vajutage suvalist klahvi, et valida uus videomode.",0
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
okt db " ... OK"
85,24 → 60,16
db " automaatseks jätkamiseks",13,10,0
current_cfg_msg db "Praegused seaded:",13,10,0
curvideo_msg db " [a] Videoreziim: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4,mode1,mode2,mode3
modevesa20 db " koos LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 värvi",0
mode10 db "640x480, VGA 16 värvi",0
probeno_msg db " (standard reziim)",0
probeok_msg db " (kontrolli ebastandardseid reziime)",0
;dma_msg db " [b] Kasuta DMA'd HDD juurdepääsuks:",0
usebd_msg db " [b] Add disks visible by BIOS:",0
 
mode0 db "320x200, EGA/CGA 256 värvi",0
mode9 db "640x480, VGA 16 värvi",0
 
usebd_msg db " [b] Lisa kettad nahtavaks BIOS:",0
on_msg db " sees",13,10,0
off_msg db " väljas",13,10,0
;readonly_msg db " ainult lugemiseks",13,10,0
vrrm_msg db " [c] Kasuta VRR:",0
preboot_device_msg db " [d] Disketi kujutis: ",0
 
preboot_device_msg db " [c] Disketi kujutis: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 db "reaalne diskett",13,10,0
114,14 → 81,21
pdm3 db "kasuta juba laaditud kujutist",13,10,0
pdm4 db "loo tühi pilt",13,10,0
end if
 
loading_msg db "Laadin KolibriOS...",0
 
if ~ defined extended_primary_loader
save_quest db "Jäta meelde praegused seaded? [y/n]: ",0
loader_block_error db "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0
end if
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0
 
remark1 db "Vaikimisi maaratud vaartused on valitud mugavuse enamikes, kuid mitte koik.",0
remark2 db "Kui susteem ei kaivitu, proovige lulitada kirje [b].",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/bootge.inc
15,11 → 15,6
 
 
d80x25_bottom:
; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
; db 'NO WARRANTY ',186
; db 186,' See file COPYING for details '
; db ' ',186
 
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche '
db ' Garantie vertrieben ',186
db 186,' Details stehen in der Datei COPYING '
27,34 → 22,15
line_full_bottom
d80x25_bottom_num = 3
 
msg_apm db " APM x.x ", 0
novesa db "Anzeige: EGA/CGA ",13,10,0
vervesa db "Vesa-Version: Vesa ",13,10,0
vervesa_off=22
msg_apm db " APM x.x ", 0
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 Farben: [9] 320x200, "
db "VGA 16 Farben: [0] 640x480",13,10
db 186," Waehle Modus: ",0
bt24 db "Bits Per Pixel: 24",13,10,0
bt32 db "Bits Per Pixel: 32",13,10,0
vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0
;askmouse db " Maus angeschlossen an:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Waehle Port [1-3]: ",0
;no_com1 db 13,10,186, " Keine COM1 Maus",0
;no_com2 db 13,10,186, " Keine COM2 Maus",0
;ask_dma db "Nutze DMA zum HDD Zugriff? [1-ja, 2-allein fur Lesen, 3-nein]: ",0
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
;gr_direct db 186," Benutze direct LFB? "
; db "[1-ja/2-nein] ? ",0
;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
s_vesa db "Vesa-Version: "
.ver db "?.?",13,10,0
 
gr_mode db "Wahlen Sie einen videomode: ",13,10,0
 
ask_bd db "Add-Festplatten sichtbar BIOS in V86-Modus emuliert? [1-ja, 2 nein]: ",0
 
if defined extended_primary_loader
bdev db "Lade die Ramdisk von [1-Diskette; 2-kolibri.img]: ",0
else
64,18 → 40,12
db 13,10,186," "
db "4-create blank image]: ",0
end if
probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, "
db "2-BIOS Test (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
 
prnotfnd db "Fatal - Videomodus nicht gefunden.",0
;modena db "Fatal - VBE 0x112+ required.",0
 
not386 db "Fatal - CPU 386+ benoetigt.",0
btns db "Fatal - konnte Farbtiefe nicht erkennen.",0
fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0
pres_key db "Drucken Sie eine beliebige Taste, um eine neue videomode wahlen.",0
badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0
memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0
okt db " ... OK"
84,30 → 54,22
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 [abcd], 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
current_cfg_msg db "Aktuelle Einstellungen:",13,10,0
curvideo_msg db " [a] Videomodus: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4,mode1,mode2,mode3
modevesa20 db " mit LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 colors",0
mode10 db "640x480, VGA 16 colors",0
probeno_msg db " (Standard Modus)",0
probeok_msg db " (teste nicht-standard Modi)",0
;dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0
usebd_msg db " [b] Add disks visible by BIOS:",0
 
mode0 db "320x200, EGA/CGA 256 colors",13,10,0
mode9 db "640x480, VGA 16 colors",13,10,0
 
usebd_msg db " [b] Add-Festplatten sichtbar durch das BIOS:",0
on_msg db " an",13,10,0
off_msg db " aus",13,10,0
;readonly_msg db " fur Lesen",13,10,0
vrrm_msg db " [c] Nutze VRR:",0
preboot_device_msg db " [d] Diskettenimage: ",0
 
preboot_device_msg db " [c] Diskettenimage: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 db "Echte Diskette",13,10,0
119,14 → 81,21
pdm3 db "Nutze bereits geladenes Image",13,10,0
pdm4 db "create blank image",13,10,0
end if
 
loading_msg db "Lade KolibriOS...",0
 
if ~ defined extended_primary_loader
save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0
end if
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0
 
remark1 db "Die Standardwerte sind fur die meisten gewahlt, aber nicht fur jedermann.",0
remark2 db "Wenn das System nicht bootet, versuchen, das Element [b] deaktivieren.",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/bootru.inc
15,8 → 15,8
 
 
d80x25_bottom:
db 186,' Kolibri OS ®á­®¢ ­  ­  Menuet OS ¨ ­¥ ¯à¥¤®áâ ¢«ï¥â '
db '­¨ª ª¨å £ àa­â¨©. ',186
db 186,' KolibriOS ®á­®¢ ­  ­  MenuetOS ¨ … …„Ž‘’€‚‹Ÿ…’ ˆ'
db 'Š€Šˆ• ƒ€A’ˆ‰. ',186
db 186,' ®¤à®¡­¥¥ ᬮâà¨â¥ ¢ ä ©«¥ COPYING.TXT '
db ' ',186
line_full_bottom
28,11 → 28,9
.ver db "?.?",13,10,0
 
gr_mode db "‚ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",13,10,0
vrrmprint db "ˆá¯®«ì§®¢ âì VRR? (ç áâ®â  ª ¤à®¢ ¢ëè¥ 60 ƒæ"
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-­¥â]: ",0
;ask_dma db "ˆá¯®«ì§®¢ âì DMA ¤«ï ¤®áâ㯠 ª HDD? [1-¤ , 2-⮫쪮 ç⥭¨¥, 3-­¥â]: ",0
 
ask_bd db "„®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS ¢ ०¨¬¥ V86? [1-¤ , 2-­¥â]: ",0
 
if defined extended_primary_loader
bdev db "‡ £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-kolibri.img ¨§ ¯ ¯ª¨ § £à㧪¨]: ",0
else
42,7 → 40,9
db 13,10,186," "
db "4-ᮧ¤ âì ç¨áâë© ®¡à §]: ",0
end if
 
prnotfnd db "Žè¨¡ª  - ‚¨¤¥®à¥¦¨¬ ­¥ ­ ©¤¥­.",0
 
not386 db "Žè¨¡ª  - ’ॡã¥âáï ¯à®æ¥áá®à 386+.",0
fatalsel db "Žè¨¡ª  - ‚ë¡à ­­ë© ¢¨¤¥®à¥¦¨¬ ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0
pres_key db " ¦¨¬¨â¥ «î¡ãî ª« ¢¨èã, ¤«ï ¯¥à¥å®¤  ¢ ¢ë¡®à ०¨¬®¢.",0
61,7 → 61,6
current_cfg_msg db "’¥ªã騥 ­ áâனª¨:",13,10,0
curvideo_msg db " [a] ‚¨¤¥®à¥¦¨¬: ",0
 
 
mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0
mode9 db "640x480, VGA 16 梥⮢",13,10,0
 
68,9 → 67,9
usebd_msg db " [b] „®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS:",0
on_msg db " ¢ª«",13,10,0
off_msg db " ¢ëª«",13,10,0
readonly_msg db " ⮫쪮 ç⥭¨¥",13,10,0
vrrm_msg db " [c] ˆá¯®«ì§®¢ ­¨¥ VRR:",0
preboot_device_msg db " [d] Ž¡à § ¤¨áª¥âë: ",0
 
preboot_device_msg db " [c] Ž¡à § ¤¨áª¥âë: ",0
 
if defined extended_primary_loader
preboot_device_msgs dw 0,pdm1,pdm2,0
pdm1 db "­ áâ®ïé ï ¤¨áª¥â ",13,10,0
82,13 → 81,14
pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §",13,10,0
pdm4 db "ᮧ¤ âì ç¨áâë© ®¡à §",13,10,0
end if
 
loading_msg db "ˆ¤ñâ § £à㧪  KolibriOS...",0
 
if ~ defined extended_primary_loader ; saving not supported in this case
save_quest db "‡ ¯®¬­¨âì ⥪ã騥 ­ áâனª¨? [y/n]: ",0
loader_block_error db "Žè¨¡ª  ¢ ¤ ­­ëå ­ ç «ì­®£® § £àã§ç¨ª , ¯à®¤®«¦¥­¨¥ ­¥¢®§¬®¦­®.",0
end if
 
 
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ',13,10,0
_r1 db 186,' ³ 320x200 EGA/CGA 256 梥⮢ ³ ³ ',13,10,0
_r2 db 186,' ³ 640x480 VGA 16 梥⮢ ³ ³ ',13,10,0
95,9 → 95,7
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³ ',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ',13,10,0
 
 
remark1 db "‡­ ç¥­¨ï ¯® 㬮«ç ­¨î ¢ë¡à ­ë ¤«ï 㤮¡á⢠ ¡®«ì設á⢠, ­® ­¥ ¢á¥å.",0
remark2 db "…᫨ 㠂 á ‹’-¬®­¨â®à, ¢ª«îç¨â¥ VRR ¢ ¯ã­ªâ¥ [c].",0
remark3 db "…᫨ 㠂 á ­¥ £à㧨âáï á¨á⥬ , ¯®¯à®¡ã©â¥ ®âª«îç¨âì ¯ã­ªâ [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
remark2 db "…᫨ 㠂 á ­¥ £à㧨âáï á¨á⥬ , ¯®¯à®¡ã©â¥ ®âª«îç¨âì ¯ã­ªâ [b].",0
remarks dw remark1, remark2
num_remarks = 2
/kernel/branches/Kolibri-acpi/boot/parsers.inc
5,7 → 5,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 1962 $
$Revision: 2261 $
 
; All parsers are called with ds:si -> value of the variable,
; possibly with spaces before, and dx = limit of config file.
57,16 → 57,16
.nothing:
ret
 
parse_vrr:
; vrr is a boolean setting
call parse_bool
jc .nothing
; convert 0 to 2, 1 to 1
inc ax
xor al, 3
mov [es:preboot_vrrm], al
.nothing:
ret
;parse_vrr:
;; vrr is a boolean setting
; call parse_bool
; jc .nothing
;; convert 0 to 2, 1 to 1
; inc ax
; xor al, 3
; mov [es:preboot_vrrm], al
;.nothing:
; ret
 
parse_biosdisks:
; using biosdisks is a boolean setting
/kernel/branches/Kolibri-acpi/boot/preboot.inc
23,7 → 23,7
number_vm dw 0 ;
;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_vrrm db 0 ; use VRR_M (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/build.bat
1,7 → 1,7
@echo off
cls
set languages=en ru ge et
set drivers=com_mouse emu10k1x ensoniq fm801 infinity sis sound viasound vt823x
set drivers=com_mouse emu10k1x fm801 infinity sis sound viasound vt823x
set targets=all kernel drivers skins clean
 
call :Check_Target %1
73,9 → 73,7
if not %errorlevel%==0 goto :Error_FasmFailed
)
cd ..
move bin\drivers\vmode.obj bin\drivers\vmode.mdr
 
 
kpack >nul 2>&1
 
if %errorlevel%==9009 goto :Error_KpackFailed
/kernel/branches/Kolibri-acpi/const.inc
298,23 → 298,22
 
BUTTON_INFO equ (OS_BASE+0x02C0000)
RESERVED_PORTS equ (OS_BASE+0x02D0000)
IRQ_SAVE equ (OS_BASE+0x02E0000)
BOOT_VAR equ (OS_BASE+0x02f0000)
BOOT_VAR equ (OS_BASE+0x02E0000)
 
stack_data_start equ (OS_BASE+0x0300000)
eth_data_start equ (OS_BASE+0x0300000)
stack_data equ (OS_BASE+0x0304000)
stack_data_end equ (OS_BASE+0x031ffff)
resendQ equ (OS_BASE+0x0320000)
stack_data_start equ (OS_BASE+0x02F0000)
eth_data_start equ (OS_BASE+0x02F0000)
stack_data equ (OS_BASE+0x02F4000)
stack_data_end equ (OS_BASE+0x030ffff)
resendQ equ (OS_BASE+0x0310000)
 
skin_data equ (OS_BASE+0x0328000)
draw_data equ (OS_BASE+0x0330000)
skin_data equ (OS_BASE+0x0318000)
draw_data equ (OS_BASE+0x0320000)
 
BgrDrawMode equ (OS_BASE+0x0333FF4)
BgrDataWidth equ (OS_BASE+0x0333FF8)
BgrDataHeight equ (OS_BASE+0x0333FFC)
BgrDrawMode equ (OS_BASE+0x0323FF4)
BgrDataWidth equ (OS_BASE+0x0323FF8)
BgrDataHeight equ (OS_BASE+0x0323FFC)
 
sys_pgmap equ (OS_BASE+0x0334000)
sys_pgmap equ (OS_BASE+0x0324000)
 
UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000)
 
/kernel/branches/Kolibri-acpi/data16.inc
78,7 → 78,7
config_variable 'timeout', parse_timeout
config_variable 'resolution', parse_resolution
config_variable 'vbemode', parse_vbemode
config_variable 'vrr', parse_vrr
; config_variable 'vrr', parse_vrr
config_variable 'biosdisks', parse_biosdisks
config_variable 'imgfrom', parse_imgfrom
dw 0
/kernel/branches/Kolibri-acpi/data32.inc
141,7 → 141,7
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db '/sys/drivers/VMODE.MDR',0
vrr_m db 'VRR_M',0
;vrr_m db 'VRR_M',0
kernel_file db 'KERNEL MNT'
 
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt
635,6 → 635,15
¢ ä®à¬ â¥ ¯®¤ä㭪樨 2 ä㭪樨 37 ¢ ¬®¬¥­â ­ ç «  ­ ¦ â¨ï
­  ª­®¯ªã, §  ¨áª«î祭¨¥¬ ¬« ¤è¥£® ¡¨â  (ᮮ⢥âáâ¢ãî饣® «¥¢®©
ª­®¯ª¥ ¬ëè¨), ª®â®àë© á¡à á뢠¥âáï.
======================================================================
= ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 1 - ᤥ« âì á ¬ë¬ ­¨¦­¨¬ ®ª­® ¯®â®ª . =======
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à á«®â  ¯®â®ª 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
======================================================================
==== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 2 - § ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® á«®âã. ====
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
627,6 → 627,17
of button press, excluding lower bit, which is cleared.
 
======================================================================
===================== Function 18, subfunction 1 =====================
============= Make deactive the window of the given thread. ==========
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 1 - subfunction number
* ecx = number of the thread slot
Returned value:
* function does not return value
======================================================================
= Function 18, subfunction 2 - terminate process/thread by the slot. =
======================================================================
Parameters:
/kernel/branches/Kolibri-acpi/drivers/vt823(x).asm
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/vmode.asm
File deleted
/kernel/branches/Kolibri-acpi/drivers/viasound.asm
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:eol-style
-native
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui/window.inc
1163,7 → 1163,7
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, ebx
call window._.draw_negative_box
call window._.end_moving__box
 
mov edi, esi
shl edi, 5
1306,18 → 1306,7
mov ecx, 4
repz cmpsd
pop edi
jnz @f
mov edi,eax
mov eax, [edi + BOX.left - 2]
mov ax, word[edi + BOX.left]
add ax, word[edi + BOX.width]
mov ebx, [edi + BOX.top - 2]
mov bx, word[edi + BOX.top]
add bx, word[edi + BOX.height]
xor esi,esi
call draw_rectangle.forced
jmp .exit
jz .exit
@@:
 
add esp, -BOX.sizeof
1823,6 → 1812,9
 
; if type of current active window is 3 or 4, it must be redrawn
mov ebx, [TASK_COUNT]
; DEBUGF 1, "K : TASK_COUNT (0x%x)\n", ebx
movzx ebx, word[WIN_POS + ebx * 2]
shl ebx, 5
add eax, window_data
1849,6 → 1841,13
cmp eax, [TASK_COUNT]
jae .move_self_up
inc eax
; push ebx
; xor ebx,ebx
; mov bx,[WIN_STACK + eax * 2]
; DEBUGF 1, "K : DEC WIN_STACK (0x%x)\n",ebx
; pop ebx
cmp [WIN_STACK + eax * 2], bx
jbe .next_stack_window
dec word[WIN_STACK + eax * 2]
1881,6 → 1880,53
pop ebx eax
ret
 
;------------------------------------------------------------------------------
window._.window_deactivate: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Deactivate window
;------------------------------------------------------------------------------
;> esi = pointer to WIN_POS+ window data
;------------------------------------------------------------------------------
push eax ebx
;------------------------------------------------------------------------------
.move_others_up:
; ax <- process no
movzx ebx, word[esi]
; ax <- position in window stack
movzx ebx, word[WIN_STACK + ebx * 2]
; up others
xor eax, eax
.next_stack_window:
cmp eax, [TASK_COUNT]
jae .move_self_down
inc eax
cmp [WIN_STACK + eax * 2], bx
jae .next_stack_window
inc word[WIN_STACK + eax * 2]
jmp .next_stack_window
;----------------------------------------------
.move_self_down:
movzx ebx, word[esi]
; this is the last (and the low)
mov [WIN_STACK + ebx * 2], word 1
; update on screen - window stack
xor eax, eax
.next_window_pos:
cmp eax, [TASK_COUNT]
jae .reset_vars
inc eax
movzx ebx, word[WIN_STACK + eax * 2]
mov [WIN_POS + ebx * 2], ax
jmp .next_window_pos
;-----------------------------------------------
.reset_vars:
mov byte[KEY_COUNT], 0
mov byte[BTN_COUNT], 0
mov word[MOUSE_SCROLL_H], 0
mov word[MOUSE_SCROLL_V], 0
pop ebx eax
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
window._.check_window_draw: ;//////////////////////////////////////////////////
2084,6 → 2130,8
;> edi = pointer to BOX struct
;------------------------------------------------------------------------------
push eax ebx esi
mov esi, 0x01000000
.1:
mov eax, [edi + BOX.left - 2]
mov ax, word[edi + BOX.left]
add ax, word[edi + BOX.width]
2090,7 → 2138,16
mov ebx, [edi + BOX.top - 2]
mov bx, word[edi + BOX.top]
add bx, word[edi + BOX.height]
mov esi, 0x01000000
call draw_rectangle.forced
pop esi ebx eax
ret
;------------------------------------------------------------------------------
window._.end_moving__box: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Draw positive box
;------------------------------------------------------------------------------
;> edi = pointer to BOX struct
;------------------------------------------------------------------------------
push eax ebx esi
xor esi,esi
jmp window._.draw_negative_box.1
/kernel/branches/Kolibri-acpi/kernel.asm
867,18 → 867,18
; LOAD FIRST APPLICATION
cli
 
cmp byte [BOOT_VAR+0x9030],1
jne no_load_vrr_m
; cmp byte [BOOT_VAR+0x9030],1
; jne no_load_vrr_m
 
mov ebp, vrr_m
call fs_execute_from_sysdir
; 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:
 
; 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
 
1935,7 → 1935,7
iglobal
align 4
sys_system_table:
dd exit_for_anyone ; 1 = obsolete
dd sysfn_deactivate ; 1 = deactivate window
dd sysfn_terminate ; 2 = terminate thread
dd sysfn_activate ; 3 = activate window
dd sysfn_getidletime ; 4 = get idle time
1960,7 → 1960,7
dd sysfn_min_rest_window ; 22 = minimize and restore any window
sysfn_num = ($ - sys_system_table)/4
endg
 
;------------------------------------------------------------------------------
sys_system:
dec ebx
cmp ebx, sysfn_num
1968,8 → 1968,7
jmp dword [sys_system_table + ebx*4]
@@:
ret
 
 
;------------------------------------------------------------------------------
sysfn_shutdown: ; 18.9 = system shutdown
cmp ecx,1
jl exit_for_anyone
1986,7 → 1985,7
uglobal
shutdown_processes: dd 0x0
endg
 
;------------------------------------------------------------------------------
sysfn_terminate: ; 18.2 = TERMINATE
cmp ecx,2
jb noprocessterminate
2010,7 → 2009,7
noatsc:
noprocessterminate:
ret
 
;------------------------------------------------------------------------------
sysfn_terminate2:
;lock application_table_status mutex
.table_status:
2037,7 → 2036,34
mov [application_table_status],0
or dword [esp+32],-1
ret
;------------------------------------------------------------------------------
sysfn_deactivate: ; 18.1 = DEACTIVATE WINDOW
cmp ecx,2
jb .nowindowdeactivate
cmp ecx,[TASK_COUNT]
ja .nowindowdeactivate
movzx esi, word [WIN_STACK + ecx*2]
cmp esi, 1
je .nowindowdeactivate ; already deactive
 
mov edi, ecx
shl edi, 5
add edi, window_data
movzx esi, word [WIN_STACK + ecx * 2]
lea esi, [WIN_POS + esi * 2]
call window._.window_deactivate
 
xor eax, eax
mov byte[MOUSE_BACKGROUND], al
mov byte[DONT_DRAW_MOUSE], al
mov byte[MOUSE_DOWN], 0
 
call syscall_display_settings._.calculate_whole_screen
call syscall_display_settings._.redraw_whole_screen
.nowindowdeactivate:
ret
;------------------------------------------------------------------------------
sysfn_activate: ; 18.3 = ACTIVATE WINDOW
cmp ecx,2
jb .nowindowactivate
2058,21 → 2084,22
call waredraw
.nowindowactivate:
ret
 
;------------------------------------------------------------------------------
sysfn_getidletime: ; 18.4 = GET IDLETIME
mov eax,[idleusesec]
mov [esp+32], eax
ret
 
;------------------------------------------------------------------------------
sysfn_getcpuclock: ; 18.5 = GET TSC/SEC
mov eax,[CPU_FREQ]
mov [esp+32], eax
ret
 
;------------------------------------------------------------------------------
; SAVE ramdisk to /hd/1/menuet.img
;!!!!!!!!!!!!!!!!!!!!!!!!
include 'blkdev/rdsave.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!
;------------------------------------------------------------------------------
align 4
sysfn_getactive: ; 18.7 = get active window
mov eax, [TASK_COUNT]
2079,7 → 2106,7
movzx eax, word [WIN_POS + eax*2]
mov [esp+32],eax
ret
 
;------------------------------------------------------------------------------
sysfn_sound_flag: ; 18.8 = get/set sound_flag
; cmp ecx,1
dec ecx
2094,10 → 2121,11
xor byte [sound_flag], 1
nosoundflag:
ret
 
;------------------------------------------------------------------------------
sysfn_minimize: ; 18.10 = minimize window
mov [window_minimize],1
ret
;------------------------------------------------------------------------------
align 4
sysfn_getdiskinfo: ; 18.11 = get disk info table
; cmp ecx,1
2122,11 → 2150,11
cld
rep movsd
ret
 
;------------------------------------------------------------------------------
sysfn_lastkey: ; 18.12 = return 0 (backward compatibility)
and dword [esp+32], 0
ret
 
;------------------------------------------------------------------------------
sysfn_getversion: ; 18.13 = get kernel ID and version
mov edi,ecx
mov esi,version_inf
2133,7 → 2161,7
mov ecx,version_end-version_inf
rep movsb
ret
 
;------------------------------------------------------------------------------
sysfn_waitretrace: ; 18.14 = sys wait retrace
;wait retrace functions
sys_wait_retrace:
2144,7 → 2172,7
jz WaitRetrace_loop
and [esp+32],dword 0
ret
 
;------------------------------------------------------------------------------
align 4
sysfn_centermouse: ; 18.15 = mouse centered
; removed here by <Lrz>
2163,8 → 2191,8
xor eax,eax
and [esp+32],eax
; pop eax
 
ret
;------------------------------------------------------------------------------
align 4
sysfn_mouse_acceleration: ; 18.19 = set/get mouse features
test ecx,ecx ; get mouse speed factor
2211,7 → 2239,7
mov [mouse_active],1
.end:
ret
 
;------------------------------------------------------------------------------
sysfn_getfreemem:
mov eax, [pg_data.pages_free]
shl eax, 2