/kernel/branches/net/blkdev/cd_drv.inc |
---|
170,13 → 170,15 |
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä |
uglobal |
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû |
PacketCommand: rb 12 ;DB 12 DUP (?) |
PacketCommand: |
rb 12 ;DB 12 DUP (?) |
; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà |
;CDDataBuf DB 4096 DUP (0) |
; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ |
;CDBlockSize DW ? |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ |
CDSectorAddress: DD ? |
CDSectorAddress: |
DD ? |
; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì |
TickCounter_1 DD 0 |
; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà |
/kernel/branches/net/blkdev/disk.inc |
---|
0,0 → 1,1258 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 2381 $ |
; ============================================================================= |
; ================================= Constants ================================= |
; ============================================================================= |
; Error codes for callback functions. |
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_END_OF_MEDIA = 3 ; end of media while reading/writing data |
; Driver flags. Represent bits in DISK.DriverFlags. |
DISK_NO_INSERT_NOTIFICATION = 1 |
; Media flags. Represent bits in DISKMEDIAINFO.Flags. |
DISK_MEDIA_READONLY = 1 |
; 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 |
; too many MBRs are visible,there probably is a loop in the MBR structure. |
MAX_NUM_PARTITIONS = 256 |
; ============================================================================= |
; ================================ Structures ================================= |
; ============================================================================= |
; This structure defines all callback functions for working with the physical |
; device. They are implemented by a driver. Objects with this structure reside |
; in a driver. |
struct DISKFUNC |
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 ? |
; The pointer to the function which frees all driver-specific resources for |
; the disk. |
; Optional, may be NULL. |
; void close(void* userdata); |
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, |
; even if new media is inserted, until this function is called. If media is |
; removed, a new call to 'disk_media_changed' is not allowed until this |
; function is called. |
; Optional, may be NULL (if media is not removable). |
; void closemedia(void* userdata); |
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 ? |
; 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 ? |
; 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); |
; input: *numsectors = number of sectors to write |
; output: *numsectors = number of sectors which were successfully written |
; Return value: one of DISK_STATUS_* |
flush dd ? |
; The pointer to the function which flushes the internal device cache. |
; Optional, may be NULL. |
; int flush(void* userdata); |
; Return value: one of DISK_STATUS_* |
; 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 ? |
; 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); |
; Return value: 0 = disable cache, otherwise = used cache size in bytes. |
ends |
; 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 ? |
; Combination of DISK_MEDIA_* bits. |
SectorSize dd ? |
; Size of the sector. |
Capacity dq ? |
; Size of the media in sectors. |
ends |
; 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 |
mutex MUTEX |
; Lock to protect the cache. |
; The following fields are inherited from data32.inc:cache_ideX. |
pointer dd ? |
data_size dd ? ; unused |
data dd ? |
sad_size dd ? |
search_start dd ? |
ends |
; This structure represents a disk device and its media for the kernel. |
; This structure is allocated by the kernel in the 'disk_add' function, |
; freed in the 'disk_dereference' function. |
struct DISK |
; Fields of disk object |
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 ? |
; Pointer to the 'DISKFUNC' structure with driver functions. |
Name dd ? |
; Pointer to the string used for accesses through the global filesystem. |
UserData dd ? |
; This field is passed to all callback functions so a driver can decide which |
; physical device is addressed. |
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 ? |
; 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. |
; One reference is added if media is inserted. |
; 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 |
; Lock to protect the MEDIA structure. See the description after |
; 'disk_list_mutex' for the locking strategy. |
; Fields of media object |
MediaInserted db ? |
; 0 if media is not inserted, nonzero otherwise. |
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 |
; 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 ? |
; 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 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 ? |
; Pointer to array of .NumPartitions pointers to PARTITION structures. |
cache_size dd ? |
; inherited from cache_ideX_size |
SysCache DISKCACHE |
AppCache DISKCACHE |
; Two caches for the disk. |
ends |
; This structure represents one partition for the kernel. This is a base |
; template, the actual contents after common fields is determined by the |
; file system code for this partition. |
struct PARTITION |
FirstSector dq ? |
; First sector of the partition. |
Length dq ? |
; Length of the partition in sectors. |
Disk dd ? |
; 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 |
; point to handlers of corresponding subfunctions. |
; This field is 0 if file system is not recognized. |
; ...fs-specific data may follow... |
ends |
; This is an external structure, it represents an entry in the partition table. |
struct PARTITION_TABLE_ENTRY |
Bootable db ? |
; 80h = bootable partition, 0 = non-bootable partition, other values = invalid |
FirstHead db ? |
FirstSector db ? |
FirstTrack db ? |
; Coordinates of first sector in CHS. |
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 ? |
; Coordinates of last sector in CHS. |
FirstAbsSector dd ? |
; Coordinate of first sector in LBA. |
Length dd ? |
; Length of the partition in sectors. |
ends |
; ============================================================================= |
; ================================ Global data ================================ |
; ============================================================================= |
iglobal |
; The pseudo-item for the list of all DISK structures. |
; Initialized to the empty list. |
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, |
; disk and media are both non-removable. However, in the general case both |
; 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. |
; * The following operations use data of disk object: adding (disk_add); |
; deleting (disk_del); filesystem (fs_lfn which eventually calls |
; dyndisk_handler or dyndisk_enum_root). |
; * The following operations use data of media object: adding/removing |
; (disk_media_changed); filesystem (fs_lfn which eventually calls |
; dyndisk_handler; dyndisk_enum_root doesn't work with media). |
; * Notifications disk_add, disk_media_changed, disk_del are synchronized |
; between themselves, this is a requirement for the driver. However, file |
; system operations are asynchronous, can be issued at any time by any |
; thread. |
; * We must prevent a situation when a filesystem operation thinks that the |
; object is still valid but in fact the notification has destroyed the |
; object. So we keep a reference counter for both disk and media and destroy |
; the object when this counter goes to zero. |
; * The driver must know when it is safe to free driver-allocated resources. |
; The object can be alive even after death notification has completed. |
; We use special callbacks to satisfy both assertions: 'close' for the disk |
; and 'closemedia' for the media. The destruction of the object includes |
; calling the corresponding callback. |
; * Each filesystem operation keeps one reference for the disk and one |
; reference for the media. Notification disk_del forces notification on the |
; media death, so the reference counter for the disk is always not less than |
; the reference counter for the media. |
; * Two operations "get the object" and "increment the reference counter" can |
; not be done simultaneously. We use a mutex to guard the consistency here. |
; It must be a part of the container for the object, so that this mutex can |
; be acquired as a part of getting the object from the container. The |
; container for disk object is the global list, and this list is guarded by |
; 'disk_list_mutex'. The container for media object is the disk object, and |
; the corresponding mutex is DISK.MediaLock. |
; * Notifications do not change the data of objects, they can only remove |
; objects. Thus we don't need another synchronization at this level. If two |
; filesystem operations are referencing the same filesystem data, this is |
; better resolved at the level of the filesystem. |
endg |
iglobal |
; The function 'disk_scan_partitions' needs three 512-byte buffers for |
; MBR, bootsector and fs-temporary sector data. It can not use the static |
; buffers always, since it can be called for two or more disks in parallel. |
; However, this case is not typical. We reserve three static 512-byte buffers |
; and a flag that these buffers are currently used. If 'disk_scan_partitions' |
; detects that the buffers are currently used, it allocates buffers from the |
; heap. |
; The flag is implemented as a global dword variable. When the static buffers |
; are not used, the value is -1. When the static buffers are used, the value |
; is normally 0 and temporarily can become greater. The function increments |
; this value. If the resulting value is zero, it uses the buffers and |
; 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 |
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 |
endg |
iglobal |
; This is the array of default implementations of driver callbacks. |
; Same as DRIVERFUNC structure except for the first field; all functions must |
; 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 |
endg |
; ============================================================================= |
; ================================= Functions ================================= |
; ============================================================================= |
; This function registers a disk device. |
; This includes: |
; - allocating an internal structure describing this device; |
; - registering this structure in the global filesystem. |
; The function initializes the disk as if there is no media. If a media is |
; present, the function 'disk_media_changed' should be called after this |
; function succeeds. |
; Parameters: |
; [esp+4] = pointer to DISKFUNC structure with the callbacks |
; [esp+8] = pointer to name (ASCIIZ string) |
; [esp+12] = userdata to be passed to the callbacks as is. |
; [esp+16] = flags, bitfield. Currently only DISK_NO_INSERT_NOTIFICATION bit |
; is defined. |
; Return value: |
; NULL = operation has failed |
; non-NULL = handle of the disk. This handle can be used |
; 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 |
; 1. Allocate the DISK structure. |
; 1a. Call the heap manager. |
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 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 |
@@: |
inc eax |
cmp byte [ebx+eax-1], 0 |
jnz @b |
; 2b. Call the heap manager. |
call malloc |
; 2c. Check the result. If allocation failed, go to 7. |
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 |
; 2e. Copy the name. |
@@: |
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 |
; 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 |
; 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 |
; 5b. Insert item to the tail of double-linked list. |
mov edx, disk_list |
list_add_tail esi, edx ;esi= new edx= list head |
; 5c. Release the mutex. |
call mutex_unlock |
; 6. Return with eax = pointer to DISK. |
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 |
; 8. Return with eax = 0. |
xor eax, eax |
.nothing: |
; 9. Return. |
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: |
; - removing a media including all partitions; |
; - deleting this structure from the global filesystem; |
; - dereferencing the DISK structure and possibly destroying it. |
; Parameters: |
; [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 |
; 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 |
; 2. Delete the structure from the global list. |
; 2a. Acquire the mutex. |
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 |
; 2c. Release the mutex. |
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 |
; 4. Return. |
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 |
; finalize all associated data, and afterwards frees the DISK structure. |
; esi = pointer to DISK structure |
disk_dereference: |
; 1. Decrement reference counter. Use atomic operation to correctly handle |
; possible simultaneous calls. |
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 |
; 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 |
; 3b. Free the structure. |
xchg eax, esi |
call free |
; 4. Return. |
.nothing: |
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' |
; callback to signal the driver that the processing has finished and it is safe |
; to inform about a new media. |
; esi = pointer to DISK structure |
disk_media_dereference: |
; 1. Decrement reference counter. Use atomic operation to correctly handle |
; possible simultaneous calls. |
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 |
; 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 |
; objects, so we must guarantee that reusing does not happen while freeing. |
; Reusing is only possible when someone processes a new media. There are two |
; mutually exclusive variants: |
; * driver issues media insert notifications (DISK_NO_INSERT_NOTIFICATION bit |
; in DISK.DriverFlags is not set). In this case, we require from the driver |
; that such notification (except for the first one) can occur only after a |
; call to 'closemedia' callback. |
; * driver does not issue media insert notifications. In this case, the kernel |
; itself must sometimes check whether media is inserted. We have the flag |
; DISK.MediaUsed, visible to the kernel. This flag signals to the other parts |
; of kernel that the way is free. |
; In the first case other parts of the kernel do not use DISK.MediaUsed, so it |
; 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 |
.freeloop: |
lodsd |
call free |
dec edi |
jnz .freeloop |
.nofree: |
pop edi esi |
; 3b. Free the cache. |
call disk_free_cache |
; 3c. Call the driver. |
mov al, DISKFUNC.closemedia |
stdcall disk_call_driver |
; 3d. Clear the flag. |
mov [esi+DISK.MediaUsed], 0 |
.nothing: |
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 |
; immediately after 'disk_add' and once from 'disk_del'. |
; Parameters: |
; [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 |
; 1. Remove the existing media, if it is present. |
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 |
; We really need to remove the media. |
; 1b. Acquire mutex. |
lea ecx, [esi+DISK.MediaLock] |
call mutex_lock |
; 1c. Clear the flag. |
mov [esi+DISK.MediaInserted], 0 |
; 1d. Release mutex. |
call mutex_unlock |
; 1e. Remove the "lifetime" reference and possibly destroy the structure. |
call disk_media_dereference |
.noremove: |
; 2. Test whether there is new media. |
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 |
; media referencers) and note that calls to this function are synchronized |
; (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 |
; 3b. Check the result of the callback. Abort if it failed. |
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 |
; 3d. Acquire the lifetime reference for the media object. |
inc [esi+DISK.MediaRefCount] |
; 3e. Scan for partitions. Ignore result; the list of partitions is valid even |
; on errors. |
call disk_scan_partitions |
; 3f. Media is inserted and available for use. |
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 |
; This function is a thunk for all functions of a disk driver. |
; It checks whether the referenced function is implemented in the driver. |
; If so, this function jumps to the function in the driver. |
; Otherwise, it jumps to the default implementation. |
; al = offset of function in the DISKFUNC structure; |
; esi = pointer to the DISK structure; |
; 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 |
; 1. Prepend the first argument to the stack. |
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 |
; 3. Check that the required function is implemented. If not, go to 5. |
mov ecx, [ecx+eax] |
test ecx, ecx |
jz .default |
; 4. Jump to the required function. |
jmp ecx |
.default: |
; 5. Driver does not implement the required function; use default implementation. |
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 |
; The default implementation of DISKFUNC.read and DISKFUNC.write. |
disk_default_read: |
disk_default_write: |
push DISK_STATUS_INVALID_CALL |
pop eax |
ret 20 |
; The default implementation of DISKFUNC.close, DISKFUNC.closemedia and |
; DISKFUNC.flush. |
disk_default_close: |
disk_default_closemedia: |
disk_default_flush: |
xor eax, eax |
ret 4 |
; The default implementation of DISKFUNC.adjust_cache_size. |
disk_default_adjust_cache_size: |
mov eax, [esp+4] |
ret 4 |
; 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. |
; 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 |
; 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 |
.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 |
.buffer_acquired: |
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no |
; more than MAX_NUM_PARTITION times. |
; 4. Prepare things for the loop. |
; ebp will hold the sector number for current MBR/EBR. |
; [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 |
.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 |
; 6. If the read has failed, abort the loop. |
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 |
; 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 |
; 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. |
; 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. |
; 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 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 |
; 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 |
; 9c. Empty partition table or bootsector with many zeroes? (rule B) |
cmp byte [ebx], 0EBh |
jz .notmbr |
cmp byte [ebx], 0E9h |
jnz .mbr |
.notmbr: |
; 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 |
.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 |
; 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 |
; 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 |
; 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 |
; 12c. If extended partition has not yet started, start it. |
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 |
.mbr_failed: |
.done: |
; 13. Cleanup after the loop. |
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 |
; 14b. If we have allocated it, free it. |
xchg eax, ebx |
call free |
jmp .nothing |
; 14c. Otherwise, release reference. |
.release_partition_buffer: |
lock dec [partition_buffer_users] |
.nothing: |
; 15. Return. |
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. |
; The entry is valid if the first byte is 0 or 80h, the first sector plus the |
; length is less than twice the size of media. Multiplication by two is |
; required since the size mentioned in the partition table can be slightly |
; 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 |
; 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 |
; 4. Divide by two. |
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 |
.valid: |
; 5. Return success: CF is cleared. |
clc |
ret |
.invalid: |
; 6. Return fail: CF is set. |
stc |
ret |
; This is an internal function called from disk_scan_partitions. It processes |
; the entry pointed to by ecx. |
; * If the entry is invalid, just ignore this entry. |
; * If the type is zero, just ignore this entry. |
; * If the type is one of types for extended partition, store the address |
; of this partition as the new MBR in [esp+4]. |
; * Otherwise, add the partition to the list of partitions for this disk. |
; We don't use the type from the entry to identify the file system; |
; 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 |
; 2. Check for empty entry. If invalid, return (go to 5). |
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 |
{ |
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 |
.nothing: |
; 5. Return. |
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 |
; 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 |
; 1. Check that this partition will not exceed the limit on total number. |
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. |
; Since the number of partitions is usually very small and is guaranteed not |
; 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 |
.scan_existing: |
; 2b. Get the next partition. |
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 |
; 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 |
.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 |
; 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 |
.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 |
.next_existing: |
; 2g. The partition does not overlap with the current partition. Continue the |
; loop. |
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 |
; 3b. Test the result. If failed, return with nothing done. |
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 |
; 3d. Set the field in the DISK structure to the new array. |
xchg [esi+DISK.Partitions], eax |
; 3e. Free the old array. |
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 |
; 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 |
; 5. Insert the new partition to the list. |
stosd |
inc [esi+DISK.NumPartitions] |
; 6. Return. |
.nothing: |
ret |
endp |
; This is an internal function called from disk_add_partition. |
; It tries to recognize the file system on the partition and allocates the |
; corresponding PARTITION structure with filesystem-specific fields. |
disk_detect_partition: |
; This function inherits the stack frame from disk_add_partition. In stdcall |
; 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 ? |
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 |
; 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 |
.nothing: |
; 3. Return with eax = pointer to PARTITION or NULL. |
ret |
; 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. |
; in: esi -> name |
; ebp = 0 or rest of name relative to esi |
; out: if the handler processes path, it must not return in file_system_lfn, |
; 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 |
; 1. Acquire the mutex. |
mov ecx, disk_list_mutex |
call mutex_lock |
; 2. Loop over the list of DISK structures. |
; 2a. Initialize. |
mov ebx, disk_list |
.scan: |
; 2b. Get the next item. |
mov ebx, [ebx+DISK.Next] |
; 2c. Check whether the list is done. If so, go to 3. |
cmp ebx, disk_list |
jz .notfound |
; 2d. Compare names. If names match, go to 5. |
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 |
; edi points to the disk name. |
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 |
.wrongname: |
; 2f. Names don't match. Continue the loop. |
pop esi |
jmp .scan |
.notfound: |
; The loop is done and no name matches. |
; 3. Release the mutex. |
call mutex_unlock |
; 4. Return normally. |
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 |
.eoin: |
cmp byte [edi], 0 |
jnz .wrongname |
; We found the addressed DISK structure. |
; 5. Reference the disk. |
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 |
; 7. Acquire the mutex for media object. |
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] |
@@: |
; 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 |
; 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 |
; 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 |
; 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 |
@@: |
; 11c. Let the procedure from fs_lfn.inc do the job. |
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 |
; 12b. Store callback functions. |
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 |
.access_denied: |
; 13. Fail the operation with the appropriate code. |
mov dword [esp+32], ERROR_ACCESS_DENIED |
.cleanup: |
; 14. Cleanup. |
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 |
@@: |
call disk_dereference |
; 15. Return. |
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 |
; This is a callback for enumerating partitions called from |
; file_system_lfn.maindir in the case of inserted media. |
; 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 |
.nomore: |
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 |
.nomore: |
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. |
; 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 |
.main: |
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 |
.notfound: |
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 |
; 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 |
.noluck: |
call mutex_unlock |
.deverror: |
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 |
; and must return all items which can be handled by this. |
; It is called several times, first time with eax=0 |
; in: eax = 0 for first call, previously returned value for subsequent calls |
; out: eax = 0 => no more items |
; eax != 0 => buffer pointed to by edi contains name of item |
dyndisk_enum_root: |
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 |
.notfirst: |
; 2. Get next item. |
mov eax, [eax+DISK.Next] |
; 3. If there are no more items, go to 6. |
cmp eax, disk_list |
jz .last |
; 4. Copy name from the DISK structure to edi. |
push eax esi |
mov esi, [eax+DISK.Name] |
@@: |
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 |
.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 |
/kernel/branches/net/blkdev/disk_cache.inc |
---|
0,0 → 1,592 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 2381 $ |
; 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 |
; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. |
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure |
; 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 |
mov [hdd_appl_data], 0 |
call hd_read |
mov [hdd_appl_data], 1 ; restore to default state |
ret |
@@: |
; In the normal case, 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 |
jmp fs_read32_common |
; This function is intended to replace the old 'hd_read' function when |
; [hdd_appl_data] = 1, so its input/output parameters are the same, except |
; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. |
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure |
; 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 |
mov [hdd_appl_data], 1 |
jmp hd_read |
@@: |
; In the normal case, 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 |
; This label is the common part of fs_read32_sys and fs_read32_app. |
fs_read32_common: |
; 1. Check that the required sector is inside the partition. If no, return |
; DISK_STATUS_END_OF_MEDIA. |
cmp dword [ebp+PARTITION.Length+4], 0 |
jnz @f |
cmp dword [ebp+PARTITION.Length], eax |
ja @f |
mov eax, DISK_STATUS_END_OF_MEDIA |
pop ecx |
ret |
@@: |
; 2. Get the absolute sector on the disk. |
push edx |
xor edx, edx |
add eax, dword [ebp+PARTITION.FirstSector] |
adc edx, dword [ebp+PARTITION.FirstSector+4] |
; 3. If there is no cache for this disk, just pass the request to the driver. |
cmp [ecx+DISKCACHE.pointer], 0 |
jnz .scancache |
push 1 |
push esp ; numsectors |
push edx ; startsector |
push eax ; startsector |
push ebx ; buffer |
mov al, DISKFUNC.read |
call disk_call_driver |
pop ecx |
pop edx |
pop ecx |
ret |
.scancache: |
; 4. Scan the cache. |
push esi edi ecx ; scan cache |
push edx eax |
virtual at esp |
.sector_lo dd ? |
.sector_hi dd ? |
.cache dd ? |
end virtual |
; The following code is inherited from hd_read. The differences are: |
; all code is protected by the cache lock; instead of static calls |
; to hd_read_dma/hd_read_pio/bd_read the dynamic call to DISKFUNC.read is used; |
; sector is 64-bit, not 32-bit. |
call mutex_lock |
mov eax, [.sector_lo] |
mov edx, [.sector_hi] |
mov esi, [ecx+DISKCACHE.pointer] |
mov ecx, [ecx+DISKCACHE.sad_size] |
add esi, 12 |
mov edi, 1 |
.hdreadcache: |
cmp dword [esi+8], 0 ; empty |
je .nohdcache |
cmp [esi], eax ; correct sector |
jne .nohdcache |
cmp [esi+4], edx ; correct sector |
je .yeshdcache |
.nohdcache: |
add esi, 12 |
inc edi |
dec ecx |
jnz .hdreadcache |
mov esi, [.cache] |
call find_empty_slot64 ; ret in edi |
test eax, eax |
jnz .read_done |
push 1 |
push esp |
push edx |
push [.sector_lo+12] |
mov ecx, [.cache] |
mov eax, edi |
shl eax, 9 |
add eax, [ecx+DISKCACHE.data] |
push eax |
mov esi, [ebp+PARTITION.Disk] |
mov al, DISKFUNC.read |
call disk_call_driver |
pop ecx |
dec ecx |
jnz .read_done |
mov ecx, [.cache] |
lea eax, [edi*3] |
mov esi, [ecx+DISKCACHE.pointer] |
lea esi, [eax*4+esi] |
mov eax, [.sector_lo] |
mov edx, [.sector_hi] |
mov [esi], eax ; sector number |
mov [esi+4], edx ; sector number |
mov dword [esi+8], 1; hd read - mark as same as in hd |
.yeshdcache: |
mov esi, edi |
mov ecx, [.cache] |
shl esi, 9 |
add esi, [ecx+DISKCACHE.data] |
mov edi, ebx |
mov ecx, 512/4 |
rep movsd ; move data |
xor eax, eax ; successful read |
.read_done: |
mov ecx, [.cache] |
push eax |
call mutex_unlock |
pop eax |
add esp, 12 |
pop edi esi edx ecx |
ret |
; This function is intended to replace the old 'hd_write' function when |
; [hdd_appl_data] = 0, so its input/output parameters are the same, except |
; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. |
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure |
; 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 |
mov [hdd_appl_data], 0 |
call hd_write |
mov [hdd_appl_data], 1 ; restore to default state |
ret |
@@: |
; In the normal case, 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 |
jmp fs_write32_common |
; This function is intended to replace the old 'hd_write' function when |
; [hdd_appl_data] = 1, so its input/output parameters are the same, except |
; that it can't use the global variables 'hd_error' and 'hdd_appl_data'. |
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure |
; 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 |
mov [hdd_appl_data], 1 |
jmp hd_write |
@@: |
; In the normal case, 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 |
; This label is the common part of fs_read32_sys and fs_read32_app. |
fs_write32_common: |
; 1. Check that the required sector is inside the partition. If no, return |
; DISK_STATUS_END_OF_MEDIA. |
cmp dword [ebp+PARTITION.Length+4], 0 |
jnz @f |
cmp dword [ebp+PARTITION.Length], eax |
ja @f |
mov eax, DISK_STATUS_END_OF_MEDIA |
pop ecx |
ret |
@@: |
push edx |
; 2. Get the absolute sector on the disk. |
xor edx, edx |
add eax, dword [ebp+PARTITION.FirstSector] |
adc edx, dword [ebp+PARTITION.FirstSector+4] |
; 3. If there is no cache for this disk, just pass request to the driver. |
cmp [ecx+DISKCACHE.pointer], 0 |
jnz .scancache |
push 1 |
push esp ; numsectors |
push edx ; startsector |
push eax ; startsector |
push ebx ; buffer |
mov al, DISKFUNC.write |
call disk_call_driver |
pop ecx |
pop edx |
pop ecx |
ret |
.scancache: |
; 4. Scan the cache. |
push esi edi ecx ; scan cache |
push edx eax |
virtual at esp |
.sector_lo dd ? |
.sector_hi dd ? |
.cache dd ? |
end virtual |
; The following code is inherited from hd_write. The differences are: |
; all code is protected by the cache lock; |
; sector is 64-bit, not 32-bit. |
call mutex_lock |
; check if the cache already has the sector and overwrite it |
mov eax, [.sector_lo] |
mov edx, [.sector_hi] |
mov esi, [ecx+DISKCACHE.pointer] |
mov ecx, [ecx+DISKCACHE.sad_size] |
add esi, 12 |
mov edi, 1 |
.hdwritecache: |
cmp dword [esi+8], 0 ; if cache slot is empty |
je .not_in_cache_write |
cmp [esi], eax ; if the slot has the sector |
jne .not_in_cache_write |
cmp [esi+4], edx ; if the slot has the sector |
je .yes_in_cache_write |
.not_in_cache_write: |
add esi, 12 |
inc edi |
dec ecx |
jnz .hdwritecache |
; sector not found in cache |
; write the block to a new location |
mov esi, [.cache] |
call find_empty_slot64 ; ret in edi |
test eax, eax |
jne .hd_write_access_denied |
mov ecx, [.cache] |
lea eax, [edi*3] |
mov esi, [ecx+DISKCACHE.pointer] |
lea esi, [eax*4+esi] |
mov eax, [.sector_lo] |
mov edx, [.sector_hi] |
mov [esi], eax ; sector number |
mov [esi+4], edx ; sector number |
.yes_in_cache_write: |
mov dword [esi+4], 2 ; write - differs from hd |
shl edi, 9 |
mov ecx, [.cache] |
add edi, [ecx+DISKCACHE.data] |
mov esi, ebx |
mov ecx, 512/4 |
rep movsd ; move data |
xor eax, eax ; success |
.hd_write_access_denied: |
mov ecx, [.cache] |
push eax |
call mutex_unlock |
pop eax |
add esp, 12 |
pop edi esi edx ecx |
ret |
; This internal function is called from fs_read32_* and fs_write32_*. It is the |
; analogue of find_empty_slot for 64-bit sectors. |
find_empty_slot64: |
;----------------------------------------------------------- |
; find empty or read slot, flush cache if next 12.5% is used by write |
; output : edi = cache slot |
;----------------------------------------------------------- |
.search_again: |
mov ecx, [esi+DISKCACHE.sad_size] |
mov edi, [esi+DISKCACHE.search_start] |
shr ecx, 3 |
.search_for_empty: |
inc edi |
cmp edi, [esi+DISKCACHE.sad_size] |
jbe .inside_cache |
mov edi, 1 |
.inside_cache: |
lea eax, [edi*3] |
shl eax, 2 |
add eax, [esi+DISKCACHE.pointer] |
cmp dword [eax+8], 2 |
jb .found_slot ; it's empty or read |
dec ecx |
jnz .search_for_empty |
call write_cache64 ; no empty slots found, write all |
test eax, eax |
jne .found_slot_access_denied |
jmp .search_again ; and start again |
.found_slot: |
mov [esi+DISKCACHE.search_start], edi |
xor eax, eax ; success |
.found_slot_access_denied: |
ret |
; This function is intended to replace the old 'write_cache' function. |
proc write_cache64 uses ecx edx esi edi |
locals |
cache_chain_started dd ? |
cache_chain_size dd ? |
cache_chain_pos dd ? |
cache_chain_ptr dd ? |
endl |
; If there is no cache for this disk, nothing to do. |
cmp [esi+DISKCACHE.pointer], 0 |
jz .flush |
;----------------------------------------------------------- |
; write all changed sectors to disk |
;----------------------------------------------------------- |
; write difference ( 2 ) from cache to DISK |
mov ecx, [esi+DISKCACHE.sad_size] |
mov esi, [esi+DISKCACHE.pointer] |
add esi, 12 |
mov edi, 1 |
.write_cache_more: |
cmp dword [esi+8], 2 ; if cache slot is not different |
jne .write_chain |
mov dword [esi+8], 1 ; same as in hd |
mov eax, [esi] |
mov edx, [esi+4] ; edx:eax = sector to write |
; Îáúåäèíÿåì çàïèñü öåïî÷êè ïîñëåäîâàòåëüíûõ ñåêòîðîâ â îäíî îáðàùåíèå ê äèñêó |
cmp ecx, 1 |
jz .nonext |
cmp dword [esi+12+8], 2 |
jnz .nonext |
push eax edx |
add eax, 1 |
adc edx, 0 |
cmp eax, [esi+12] |
jnz @f |
cmp edx, [esi+12+4] |
@@: |
pop edx 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 |
test eax, eax |
jnz .nothing |
mov [cache_chain_size], 1 |
mov [cache_chain_ptr], esi |
call .write_cache_sector |
test eax, eax |
jnz .nothing |
jmp .continue |
.write_chain: |
call .flush_cache_chain |
test eax, eax |
jnz .nothing |
.continue: |
add esi, 12 |
inc edi |
dec ecx |
jnz .write_cache_more |
call .flush_cache_chain |
test eax, eax |
jnz .nothing |
.flush: |
mov esi, [ebp] |
mov esi, [esi+PARTITION.Disk] |
mov al, DISKFUNC.flush |
call disk_call_driver |
.nothing: |
ret |
.flush_cache_chain: |
xor eax, eax |
cmp [cache_chain_started], eax |
jz @f |
call .write_cache_chain |
mov [cache_chain_started], 0 |
@@: |
retn |
.write_cache_sector: |
mov [cache_chain_size], 1 |
mov [cache_chain_pos], edi |
.write_cache_chain: |
pusha |
mov edi, [cache_chain_pos] |
mov ecx, [ebp-12] |
shl edi, 9 |
add edi, [ecx+DISKCACHE.data] |
mov ecx, [cache_chain_size] |
push ecx |
push esp ; numsectors |
mov eax, [cache_chain_ptr] |
pushd [eax+4] |
pushd [eax] ; startsector |
push edi ; buffer |
mov esi, [ebp] |
mov esi, [esi+PARTITION.Disk] |
mov al, DISKFUNC.write |
call disk_call_driver |
pop ecx |
mov [esp+28], eax |
popa |
retn |
endp |
; This internal function is called from disk_add to initialize the caching for |
; a new DISK. |
; The algorithm is inherited from getcache.inc: take 1/32 part of the available |
; physical memory, round down to 8 pages, limit by 128K from below and by 1M |
; from above. Reserve 1/8 part of the cache for system data and 7/8 for app |
; data. |
; After the size is calculated, but before the cache is allocated, the device |
; driver can adjust the size. In particular, setting size to zero disables |
; caching: there is no sense in a cache for a ramdisk. In fact, such action |
; is most useful example of a non-trivial adjustment. |
; esi = pointer to DISK structure |
disk_init_cache: |
; 1. Calculate the suggested cache size. |
; 1a. Get the size of free physical memory in pages. |
mov eax, [pg_data.pages_free] |
; 1b. Use the value to calculate the size. |
shl eax, 12 - 5 ; 1/32 of it in bytes |
and eax, -8*4096 ; round down to the multiple of 8 pages |
; 1c. Force lower and upper limits. |
cmp eax, 1024*1024 |
jb @f |
mov eax, 1024*1024 |
@@: |
cmp eax, 128*1024 |
ja @f |
mov eax, 128*1024 |
@@: |
; 1d. Give a chance to the driver to adjust the size. |
push eax |
mov al, DISKFUNC.adjust_cache_size |
call disk_call_driver |
; Cache size calculated. |
mov [esi+DISK.cache_size], eax |
test eax, eax |
jz .nocache |
; 2. Allocate memory for the cache. |
; 2a. Call the allocator. |
stdcall kernel_alloc, eax |
test eax, eax |
jnz @f |
; 2b. If it failed, say a message and return with eax = 0. |
dbgstr 'no memory for disk cache' |
jmp .nothing |
@@: |
; 3. Fill two DISKCACHE structures. |
mov [esi+DISK.SysCache.pointer], eax |
lea ecx, [esi+DISK.SysCache.mutex] |
call mutex_init |
lea ecx, [esi+DISK.AppCache.mutex] |
call mutex_init |
; The following code is inherited from getcache.inc. |
mov edx, [esi+DISK.SysCache.pointer] |
and [esi+DISK.SysCache.search_start], 0 |
and [esi+DISK.AppCache.search_start], 0 |
mov eax, [esi+DISK.cache_size] |
shr eax, 3 |
mov [esi+DISK.SysCache.data_size], eax |
add edx, eax |
imul eax, 7 |
mov [esi+DISK.AppCache.data_size], eax |
mov [esi+DISK.AppCache.pointer], edx |
mov eax, [esi+DISK.SysCache.data_size] |
push ebx |
call calculate_for_hd |
pop ebx |
add eax, [esi+DISK.SysCache.pointer] |
mov [esi+DISK.SysCache.data], eax |
mov [esi+DISK.SysCache.sad_size], ecx |
push edi |
mov edi, [esi+DISK.SysCache.pointer] |
lea ecx, [ecx*3] |
xor eax, eax |
rep stosd |
pop edi |
mov eax, [esi+DISK.AppCache.data_size] |
push ebx |
call calculate_for_hd |
pop ebx |
add eax, [esi+DISK.AppCache.pointer] |
mov [esi+DISK.AppCache.data], eax |
mov [esi+DISK.AppCache.sad_size], ecx |
push edi |
mov edi, [esi+DISK.AppCache.pointer] |
lea ecx, [ecx*3] |
xor eax, eax |
rep stosd |
pop edi |
; 4. Return with nonzero al. |
mov al, 1 |
; 5. Return. |
.nothing: |
ret |
; No caching is required for this driver. Zero cache pointers and return with |
; nonzero al. |
.nocache: |
mov [esi+DISK.SysCache.pointer], eax |
mov [esi+DISK.AppCache.pointer], eax |
mov al, 1 |
ret |
; This internal function is called from disk_media_dereference to free the |
; allocated cache, if there is one. |
; esi = pointer to DISK structure |
disk_free_cache: |
; The algorithm is straightforward. |
mov eax, [esi+DISK.SysCache.pointer] |
test eax, eax |
jz .nothing |
stdcall kernel_free, eax |
.nothing: |
ret |
/kernel/branches/net/blkdev/flp_drv.inc |
---|
176,7 → 176,8 |
@@GetByteFromFDC: |
inc DX |
in AL,DX |
@@End_6: pop DX |
@@End_6: |
pop DX |
pop ECX |
ret |
222,7 → 223,8 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
; mov [flp_status],0 |
@@End_7: popa |
@@End_7: |
popa |
ret |
;********************************* |
456,7 → 458,8 |
jnz @@Err_1 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_1 |
@@Err_1: mov [FDC_Status],FDC_SectorNotFound |
@@Err_1: |
mov [FDC_Status], FDC_SectorNotFound |
; mov [flp_status],0 |
@@Exit_1: |
call save_timer_fdd_motor |
555,7 → 558,8 |
jnz @@Err_2 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_3 |
@@Err_2: mov [FDC_Status],FDC_SectorNotFound |
@@Err_2: |
mov [FDC_Status], FDC_SectorNotFound |
@@Exit_3: |
call save_timer_fdd_motor |
popad |
/kernel/branches/net/blkdev/rd.inc |
---|
1169,7 → 1169,8 |
add edi, 6 |
cmp word [edi], ' ' |
jnz .insert_tilde |
@@: dec edi |
@@: |
dec edi |
cmp byte [edi], ' ' |
jz @b |
inc edi |
/kernel/branches/net/bus/pci/PCIe.inc |
---|
0,0 → 1,119 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) 2010 KolibriOS team. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; PCIe.INC ;; |
;; ;; |
;; Extended PCI express services ;; |
;; ;; |
;; art_zh <artem@jerdev.co.uk> ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 1463 $ |
;*************************************************************************** |
; Function |
; pci_ext_config: |
; |
; Description |
; PCIe extended (memory-mapped) config space detection |
; |
; WARNINGs: |
; 1) Very Experimental! |
; 2) direct HT-detection (no ACPI or BIOS service used) |
; 3) Only AMD/HT processors currently supported |
; |
;*************************************************************************** |
PCIe_CONFIG_SPACE equ 0xF0000000 ; to be moved to const.inc |
mmio_pcie_cfg_addr dd 0x0 ; intel pcie space may be defined here |
mmio_pcie_cfg_lim dd 0x0 ; upper pcie space address |
align 4 |
pci_ext_config: |
mov ebx, [mmio_pcie_cfg_addr] |
or ebx, ebx |
jz @f |
or ebx, 0x7FFFFFFF ; required by PCI-SIG standards |
jnz .pcie_failed |
add ebx, 0x0FFFFC |
cmp ebx, [mmio_pcie_cfg_lim]; is the space limit correct? |
ja .pcie_failed |
jmp .pcie_cfg_mapped |
@@: |
mov ebx, [cpu_vendor] |
cmp ebx, dword [AMD_str] |
jne .pcie_failed |
mov bx, 0xC184 ; dev = 24, fn = 01, reg = 84h |
.check_HT_mmio: |
mov cx, bx |
mov ax, 0x0002 ; bus = 0, 1dword to read |
call pci_read_reg |
mov bx, cx |
sub bl, 4 |
and al, 0x80 ; check the NP bit |
jz .no_pcie_cfg |
shl eax, 8 ; bus:[27..20], dev:[19:15] |
or eax, 0x00007FFC ; fun:[14..12], reg:[11:2] |
mov [mmio_pcie_cfg_lim], eax |
mov cl, bl |
mov ax, 0x0002 ; bus = 0, 1dword to read |
call pci_read_reg |
mov bx, cx |
test al, 0x03 ; MMIO Base RW enabled? |
jz .no_pcie_cfg |
test al, 0x0C ; MMIO Base locked? |
jnz .no_pcie_cfg |
xor al, al |
shl eax, 8 |
test eax, 0x000F0000 ; MMIO Base must be bus0-aligned |
jnz .no_pcie_cfg |
mov [mmio_pcie_cfg_addr], eax |
add eax, 0x000FFFFC |
sub eax, [mmio_pcie_cfg_lim]; MMIO must cover at least one bus |
ja .no_pcie_cfg |
; -- it looks like a true PCIe config space; |
mov eax, [mmio_pcie_cfg_addr] ; physical address |
or eax, (PG_SHARED + PG_LARGE + PG_USER) |
mov ebx, PCIe_CONFIG_SPACE ; linear address |
mov ecx, ebx |
shr ebx, 20 |
add ebx, sys_pgdir ; PgDir entry @ |
@@: |
mov dword[ebx], eax ; map 4 buses |
invlpg [ecx] |
cmp bl, 4 |
jz .pcie_cfg_mapped ; fix it later |
add bl, 4 ; next PgDir entry |
add eax, 0x400000 ; eax += 4M |
add ecx, 0x400000 |
jmp @b |
.pcie_cfg_mapped: |
; -- glad to have the extended PCIe config field found |
; mov esi, boot_pcie_ok |
; call boot_log |
ret ; <<<<<<<<<<< OK >>>>>>>>>>> |
.no_pcie_cfg: |
xor eax, eax |
mov [mmio_pcie_cfg_addr], eax |
mov [mmio_pcie_cfg_lim], eax |
add bl, 12 |
cmp bl, 0xC0 ; MMIO regs lay below this offset |
jb .check_HT_mmio |
.pcie_failed: |
; mov esi, boot_pcie_fail |
; call boot_log |
ret ; <<<<<<<<< FAILURE >>>>>>>>> |
/kernel/branches/net/bus/pci/pci32.inc |
---|
32,63 → 32,91 |
;*************************************************************************** |
;mmio_pci_addr equ 0x400 ; set actual PCI address here to activate user-MMIO |
iglobal |
align 4 |
f62call: |
dd pci_fn_0 |
dd pci_fn_1 |
dd pci_fn_2 |
dd pci_service_not_supported ;3 |
dd pci_read_reg ;4 byte |
dd pci_read_reg ;5 word |
dd pci_read_reg ;6 dword |
dd pci_service_not_supported ;7 |
dd pci_write_reg ;8 byte |
dd pci_write_reg ;9 word |
dd pci_write_reg ;10 dword |
if defined mmio_pci_addr |
dd pci_mmio_init ;11 |
dd pci_mmio_map ;12 |
dd pci_mmio_unmap ;13 |
end if |
endg |
align 4 |
pci_api: |
;cross |
mov eax, ebx |
mov ebx, ecx |
mov ecx, edx |
cmp [pci_access_enabled],1 |
jne no_pci_access_for_applications |
jne pci_service_not_supported |
or al,al |
jnz pci_fn_1 |
movzx edx, al |
if defined mmio_pci_addr |
cmp al, 13 |
ja pci_service_not_supported |
else |
cmp al, 10 |
ja pci_service_not_supported |
end if |
call dword [f62call+edx*4] |
mov dword [esp+32], eax |
ret |
align 4 |
pci_api_drv: |
cmp [pci_access_enabled], 1 |
jne .fail |
cmp eax, 2 |
ja .fail |
jmp dword [f62call+eax*4] |
.fail: |
or eax, -1 |
ret |
;; ============================================ |
pci_fn_0: |
; PCI function 0: get pci version (AH.AL) |
movzx eax,word [BOOT_VAR+0x9022] |
ret |
pci_fn_1: |
cmp al,1 |
jnz pci_fn_2 |
; PCI function 1: get last bus in AL |
mov al,[BOOT_VAR+0x9021] |
ret |
pci_fn_2: |
cmp al,2 |
jne pci_fn_3 |
; PCI function 2: get pci access mechanism |
mov al,[BOOT_VAR+0x9020] |
ret |
pci_fn_3: |
cmp al,4 |
jz pci_read_reg ;byte |
cmp al,5 |
jz pci_read_reg ;word |
cmp al,6 |
jz pci_read_reg ;dword |
cmp al,8 |
jz pci_write_reg ;byte |
cmp al,9 |
jz pci_write_reg ;word |
cmp al,10 |
jz pci_write_reg ;dword |
if defined mmio_pci_addr |
cmp al,11 ; user-level MMIO functions |
jz pci_mmio_init |
cmp al,12 |
jz pci_mmio_map |
cmp al,13 |
jz pci_mmio_unmap |
end if |
no_pci_access_for_applications: |
pci_service_not_supported: |
or eax,-1 |
mov dword [esp+32], eax |
ret |
;*************************************************************************** |
464,6 → 492,7 |
@@: |
pop ecx ; ecx = block size, bytes (expanded to whole page) |
mov ebx, ecx ; user_alloc destroys eax, ecx, edx, but saves ebx |
and eax, 0xFFFFFFF0 |
push eax ; store MMIO physical address + keep 2DWords in the stack |
stdcall user_alloc, ecx |
or eax, eax |
516,7 → 545,8 |
uglobal |
align 4 |
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1) |
pci_emu_dat: times 30*10 db 0 |
pci_emu_dat: |
times 30*10 db 0 |
endg |
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
align 4 |
540,9 → 570,9 |
cmp ebp, 1 ; PCI_FUNCTION_ID |
jnz .not_PCI_BIOS_PRESENT |
mov edx, 'PCI ' |
mov al, [OS_BASE+0x2F0000 + 0x9020] |
mov bx, [OS_BASE+0x2F0000 + 0x9022] |
mov cl, [OS_BASE+0x2F0000 + 0x9021] |
mov al, [BOOT_VAR + 0x9020] |
mov bx, [BOOT_VAR + 0x9022] |
mov cl, [BOOT_VAR + 0x9021] |
xor ah, ah |
jmp .return_abcd |
550,7 → 580,8 |
cmp ebp, 2 ; FIND_PCI_DEVICE |
jne .not_FIND_PCI_DEVICE |
mov ebx, pci_emu_dat |
..nxt: cmp [ebx], dx |
..nxt: |
cmp [ebx], dx |
jne ..no |
cmp [ebx + 2], cx |
jne ..no |
559,7 → 590,8 |
mov bx, [ebx + 4] |
xor ah, ah |
jmp .return_ab |
..no: cmp word[ebx], 0 |
..no: |
cmp word[ebx], 0 |
je ..dev_not_found |
add ebx, 10 |
jmp ..nxt |
572,12 → 604,14 |
jne .not_FIND_PCI_CLASS_CODE |
mov esi, pci_emu_dat |
shl ecx, 8 |
..nxt2: cmp [esi], ecx |
..nxt2: |
cmp [esi], ecx |
jne ..no2 |
mov bx, [esi] |
xor ah, ah |
jmp .return_ab |
..no2: cmp dword[esi], 0 |
..no2: |
cmp dword[esi], 0 |
je ..dev_not_found |
add esi, 10 |
jmp ..nxt2 |
612,7 → 646,8 |
.not_WRITE_CONFIG: |
.unsupported_func: |
mov ah, 0x81 ; FUNC_NOT_SUPPORTED |
.return:mov dword[esp + 4 ], edi |
.return: |
mov dword[esp + 4 ], edi |
mov dword[esp + 8], esi |
.return_abcd: |
mov dword[esp + 24], edx |
/kernel/branches/net/const.inc |
---|
143,45 → 143,42 |
SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM) |
IRQ_PIC equ 0 |
IRQ_APIC equ 1 |
struc TSS |
{ |
._back rw 2 |
._esp0 rd 1 |
._ss0 rw 2 |
._esp1 rd 1 |
._ss1 rw 2 |
._esp2 rd 1 |
._ss2 rw 2 |
._cr3 rd 1 |
._eip rd 1 |
._eflags rd 1 |
._eax rd 1 |
._ecx rd 1 |
._edx rd 1 |
._ebx rd 1 |
._esp rd 1 |
._ebp rd 1 |
._esi rd 1 |
._edi rd 1 |
._es rw 2 |
._cs rw 2 |
._ss rw 2 |
._ds rw 2 |
._fs rw 2 |
._gs rw 2 |
._ldt rw 2 |
._trap rw 1 |
._io rw 1 |
struct TSS |
_back rw 2 |
_esp0 rd 1 |
_ss0 rw 2 |
_esp1 rd 1 |
_ss1 rw 2 |
_esp2 rd 1 |
_ss2 rw 2 |
_cr3 rd 1 |
_eip rd 1 |
_eflags rd 1 |
_eax rd 1 |
_ecx rd 1 |
_edx rd 1 |
_ebx rd 1 |
_esp rd 1 |
_ebp rd 1 |
_esi rd 1 |
_edi rd 1 |
_es rw 2 |
_cs rw 2 |
_ss rw 2 |
_ds rw 2 |
_fs rw 2 |
_gs rw 2 |
_ldt rw 2 |
_trap rw 1 |
_io rw 1 |
rb 24 |
._io_map_0 rb 4096 |
._io_map_1 rb 4096 |
} |
_io_map_0 rb 4096 |
_io_map_1 rb 4096 |
ends |
virtual at 0 |
TSS TSS |
end virtual |
TSS_SIZE equ (128+8192) |
OS_BASE equ 0x80000000 |
247,19 → 244,20 |
;unused ? only one reference |
MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF) |
LFBAddress equ (OS_BASE+0x000FE80) |
MEM_AMOUNT equ (OS_BASE+0x000FE8C) |
Screen_Max_X equ (OS_BASE+0x000FE00) |
Screen_Max_Y equ (OS_BASE+0x000FE04) |
BytesPerScanLine equ (OS_BASE+0x000FE08) |
SCR_MODE equ (OS_BASE+0x000FE0C) |
LFBAddress equ (OS_BASE+0x000FE80) |
BTN_ADDR equ (OS_BASE+0x000FE88) |
MEM_AMOUNT equ (OS_BASE+0x000FE8C) |
SYS_SHUTDOWN equ (OS_BASE+0x000FF00) |
TASK_ACTIVATE equ (OS_BASE+0x000FF01) |
REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0) |
BACKGROUND_CHANGED equ (OS_BASE+0x000FFF1) |
BANK_RW equ (OS_BASE+0x000FFF2) |
MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4) |
DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5) |
285,33 → 283,35 |
RAMDISK_FAT equ (OS_BASE+0x0280000) |
FLOPPY_FAT equ (OS_BASE+0x0282000) |
CLEAN_ZONE equ 0x284000 |
IDE_DMA equ 0x284000 |
BgrAuxTable equ (OS_BASE+0x0298000) |
; unused? |
SB16Buffer equ (OS_BASE+0x2A0000) |
SB16Buffer equ (OS_BASE+0x02A0000) |
SB16_Status equ (OS_BASE+0x02B0000) |
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) |
VMODE_BASE equ (OS_BASE+0x0328000) |
skin_data equ (OS_BASE+0x0330000) |
draw_data equ (OS_BASE+0x0338000); |
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) |
BgrDrawMode equ (OS_BASE+0x033BFF4) |
BgrDataWidth equ (OS_BASE+0x033BFF8) |
BgrDataHeight equ (OS_BASE+0x033BFFC) |
skin_data equ (OS_BASE+0x0318000) |
draw_data equ (OS_BASE+0x0320000) |
sys_pgmap equ (OS_BASE+0x033C000) |
BgrDrawMode equ (OS_BASE+0x0323FF4) |
BgrDataWidth equ (OS_BASE+0x0323FF8) |
BgrDataHeight equ (OS_BASE+0x0323FFC) |
sys_pgmap equ (OS_BASE+0x0324000) |
UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000) |
virtual at (OS_BASE+0x05FFF80) |
tss TSS |
end virtual |
587,20 → 587,6 |
display_t display_t |
end virtual |
struc HEAP_DATA |
{ |
.mutex rd 1 |
.refcount rd 1 |
.heap_base rd 1 |
.heap_top rd 1 |
.app_mem rd 1 |
} |
HEAP_DATA_SIZE equ 20 |
virtual at 0 |
HEAP_DATA HEAP_DATA |
end virtual |
struc BOOT_DATA |
{ .bpp dd ? |
.scanline dd ? |
639,7 → 625,7 |
end virtual |
struc MEM_STATE |
{ .mutex rd 1 |
{ .mutex MUTEX |
.smallmap rd 1 |
.treemap rd 1 |
.topsize rd 1 |
658,7 → 644,7 |
.kernel_pages dd ? |
.kernel_tables dd ? |
.sys_page_dir dd ? |
.pg_mutex dd ? |
.mutex MUTEX |
} |
;struc LIB |
765,3 → 751,27 |
virtual at 0 |
CSYM COFF_SYM |
end virtual |
struc LHEAD |
{ |
.next dd ? ;next object in list |
.prev dd ? ;prev object in list |
.sizeof: |
} |
virtual at 0 |
LHEAD LHEAD |
end virtual |
struc IRQH |
{ |
.list LHEAD |
.handler dd ? ;handler roututine |
.data dd ? ;user-specific data |
.sizeof: |
} |
virtual at 0 |
IRQH IRQH |
end virtual |
/kernel/branches/net/core/apic.inc |
---|
0,0 → 1,417 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
IRQ_COUNT dd 24 |
endg |
uglobal |
irq_mode rd 1 |
IOAPIC_base rd 1 |
LAPIC_BASE rd 1 |
endg |
APIC_ID equ 0x20 |
APIC_TPR equ 0x80 |
APIC_EOI equ 0xb0 |
APIC_LDR equ 0xd0 |
APIC_DFR equ 0xe0 |
APIC_SVR equ 0xf0 |
APIC_ISR equ 0x100 |
APIC_ESR equ 0x280 |
APIC_ICRL equ 0x300 |
APIC_ICRH equ 0x310 |
APIC_LVT_LINT0 equ 0x350 |
APIC_LVT_LINT1 equ 0x360 |
APIC_LVT_err equ 0x370 |
; APIC timer |
APIC_LVT_timer equ 0x320 |
APIC_timer_div equ 0x3e0 |
APIC_timer_init equ 0x380 |
APIC_timer_cur equ 0x390 |
; IOAPIC |
IOAPIC_ID equ 0x0 |
IOAPIC_VER equ 0x1 |
IOAPIC_ARB equ 0x2 |
IOAPIC_REDTBL equ 0x10 |
align 4 |
APIC_init: |
mov [irq_mode], IRQ_PIC |
cmp [acpi_ioapic_base], 0 |
jz .no_apic |
cmp [acpi_lapic_base], 0 |
jz .no_apic |
stdcall load_file, dev_data_path |
test eax, eax |
jz .no_apic |
mov [acpi_dev_data], eax |
mov [acpi_dev_size], ebx |
call IRQ_mask_all |
; IOAPIC init |
stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW |
mov [IOAPIC_base], eax |
mov eax, IOAPIC_VER |
call IOAPIC_read |
shr eax, 16 |
inc al |
movzx eax, al |
cmp al, IRQ_RESERVED |
jbe @f |
mov al, IRQ_RESERVED |
@@: |
mov [IRQ_COUNT], eax |
; Reroute IOAPIC & mask all interrupts |
xor ecx, ecx |
mov eax, IOAPIC_REDTBL |
@@: |
mov ebx, eax |
call IOAPIC_read |
mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical |
mov al, cl |
add al, 0x20; vector |
or eax, 0x10000; Mask Interrupt |
cmp ecx, 16 |
jb .set |
or eax, 0xa000;<<< level-triggered active-low for IRQ16+ |
.set: |
xchg eax, ebx |
call IOAPIC_write |
inc eax |
mov ebx, eax |
call IOAPIC_read |
or eax, 0xff000000; Destination Field |
xchg eax, ebx |
call IOAPIC_write |
inc eax |
inc ecx |
cmp ecx, [IRQ_COUNT] |
jb @b |
call LAPIC_init |
mov [irq_mode], IRQ_APIC |
mov al, 0x70 |
out 0x22, al |
mov al, 1 |
out 0x23, al |
call pci_irq_fixup |
.no_apic: |
ret |
;=========================================================== |
align 4 |
LAPIC_init: |
; Check MSR support |
;.... |
; Get LAPIC base address |
; mov ecx, 0x1b |
; rdmsr ; it may be replaced to |
; and ax, 0xf000 ; mov eax, 0xfee00000 |
stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW |
mov [LAPIC_BASE], eax |
mov esi, eax |
; Program Destination Format Register for Flat mode. |
mov eax, [esi + APIC_DFR] |
or eax, 0xf0000000 |
mov [esi + APIC_DFR], eax |
; Program Logical Destination Register. |
mov eax, [esi + APIC_LDR] |
;and eax, 0xff000000 |
and eax, 0x00ffffff |
or eax, 0x01000000;!!!!!!!!!!!! |
mov [esi + APIC_LDR], eax |
; Task Priority Register initialization. |
mov eax, [esi + APIC_TPR] |
and eax, 0xffffff00 |
mov [esi + APIC_TPR], eax |
; Flush the queue |
mov edx, 0 |
.nxt2: |
mov ecx, 32 |
mov eax, [esi + APIC_ISR + edx] |
.nxt: |
shr eax, 1 |
jnc @f |
mov dword [esi + APIC_EOI], 0; EOI |
@@: |
loop .nxt |
add edx, 0x10 |
cmp edx, 0x170 |
jbe .nxt2 |
; Spurious-Interrupt Vector Register initialization. |
mov eax, [esi + APIC_SVR] |
or eax, 0x1ff |
and eax, 0xfffffdff |
mov [esi + APIC_SVR], eax |
; Initialize LVT LINT0 register. (INTR) |
mov eax, 0x00700 |
; mov eax, 0x10700 |
mov [esi + APIC_LVT_LINT0], eax |
; Initialize LVT LINT1 register. (NMI) |
mov eax, 0x00400 |
mov [esi + APIC_LVT_LINT1], eax |
; Initialize LVT Error register. |
mov eax, [esi + APIC_LVT_err] |
or eax, 0x10000; bit 16 |
mov [esi + APIC_LVT_err], eax |
; LAPIC timer |
; pre init |
mov dword[esi + APIC_timer_div], 1011b; 1 |
mov dword[esi + APIC_timer_init], 0xffffffff; max val |
push esi |
mov esi, 640 ; wait 0.64 sec |
call delay_ms |
pop esi |
mov eax, [esi + APIC_timer_cur]; read current tick couner |
xor eax, 0xffffffff ; eax = 0xffffffff - eax |
shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec |
; Start (every 0.01 sec) |
mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20 |
mov dword[esi + APIC_timer_init], eax |
ret |
;=========================================================== |
; IOAPIC implementation |
align 4 |
IOAPIC_read: |
; in : EAX - IOAPIC register |
; out: EAX - readed value |
push esi |
mov esi, [IOAPIC_base] |
mov [esi], eax |
mov eax, [esi + 0x10] |
pop esi |
ret |
align 4 |
IOAPIC_write: |
; in : EAX - IOAPIC register |
; EBX - value |
; out: none |
push esi |
mov esi, [IOAPIC_base] |
mov [esi], eax |
mov [esi + 0x10], ebx |
pop esi |
ret |
;=========================================================== |
; Remap all IRQ to 0x20+ Vectors |
; IRQ0 to vector 0x20, IRQ1 to vector 0x21.... |
align 4 |
PIC_init: |
cli |
mov al, 0x11 ; icw4, edge triggered |
out 0x20, al |
out 0xA0, al |
mov al, 0x20 ; generate 0x20 + |
out 0x21, al |
mov al, 0x28 ; generate 0x28 + |
out 0xA1, al |
mov al, 0x04 ; slave at irq2 |
out 0x21, al |
mov al, 0x02 ; at irq9 |
out 0xA1, al |
mov al, 0x01 ; 8086 mode |
out 0x21, al |
out 0xA1, al |
call IRQ_mask_all |
; mov dword[irq_type_to_set], IRQ_TYPE_PIC |
ret |
; ----------------------------------------- |
; TIMER SET TO 1/100 S |
align 4 |
PIT_init: |
mov al, 0x34 ; set to 100Hz |
out 0x43, al |
mov al, 0x9b ; lsb 1193180 / 1193 |
out 0x40, al |
mov al, 0x2e ; msb |
out 0x40, al |
ret |
; ----------------------------------------- |
align 4 |
unmask_timer: |
cmp [irq_mode], IRQ_APIC |
je @f |
stdcall enable_irq, 0 |
ret |
@@: |
; use PIT |
; in some systems PIT no connected to IOAPIC |
; mov eax, 0x14 |
; call IOAPIC_read |
; mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical |
; mov al, 0x20 |
; or eax, 0x10000 ; Mask Interrupt |
; mov ebx, eax |
; mov eax, 0x14 |
; call IOAPIC_write |
; stdcall enable_irq, 2 |
; ret |
; use LAPIC timer |
mov esi, [LAPIC_BASE] |
mov eax, [esi + APIC_LVT_timer] |
and eax, 0xfffeffff |
mov [esi + APIC_LVT_timer], eax |
ret |
; ----------------------------------------- |
; Disable all IRQ |
align 4 |
IRQ_mask_all: |
cmp [irq_mode], IRQ_APIC |
je .APIC |
mov al, 0xFF |
out 0x21, al |
out 0xA1, al |
mov ecx, 0x1000 |
ret |
.APIC: |
mov ecx, [IRQ_COUNT] |
mov eax, 0x10 |
@@: |
mov ebx, eax |
call IOAPIC_read |
or eax, 0x10000; bit 16 |
xchg eax, ebx |
call IOAPIC_write |
inc eax |
inc eax |
loop @b |
ret |
; ----------------------------------------- |
; End Of Interrupt |
; cl - IRQ number |
align 4 |
irq_eoi: ; __fastcall |
cmp [irq_mode], IRQ_APIC |
je .APIC |
cmp cl, 8 |
mov al, 0x20 |
jb @f |
out 0xa0, al |
@@: |
out 0x20, al |
ret |
.APIC: |
mov eax, [LAPIC_BASE] |
mov dword [eax + APIC_EOI], 0; EOI |
ret |
; ----------------------------------------- |
; from dll.inc |
align 4 |
proc enable_irq stdcall, irq_line:dword |
mov ebx, [irq_line] |
cmp [irq_mode], IRQ_APIC |
je .APIC |
mov edx, 0x21 |
cmp ebx, 8 |
jb @F |
mov edx, 0xA1 |
sub ebx, 8 |
@@: |
in al, dx |
btr eax, ebx |
out dx, al |
ret |
.APIC: |
shl ebx, 1 |
add ebx, 0x10 |
mov eax, ebx |
call IOAPIC_read |
and eax, 0xfffeffff; bit 16 |
xchg eax, ebx |
call IOAPIC_write |
ret |
endp |
align 4 |
pci_irq_fixup: |
push ebp |
mov esi, [acpi_dev_data] |
mov ebx, [acpi_dev_size] |
lea edi, [esi+ebx] |
.iterate: |
cmp esi, edi |
jae .done |
mov eax, [esi] |
cmp eax, -1 |
je .done |
movzx ebx, al |
movzx ebp, ah |
stdcall pci_read32, ebp, ebx, 0 |
cmp eax, [esi+4] |
jne .skip |
mov eax, [esi+8] |
stdcall pci_write8, ebp, ebx, 0x3C, eax |
.skip: |
add esi, 16 |
jmp .iterate |
.done: |
.fail: |
pop ebp |
ret |
/kernel/branches/net/core/conf_lib.inc |
---|
13,7 → 13,8 |
$Revision$ |
iglobal |
conf_path_sect: db 'path',0 |
conf_path_sect: |
db 'path',0 |
conf_fname db '/sys/sys.conf',0 |
endg |
75,62 → 76,7 |
udev_midibase db 'midibase',0 |
udev_midibase_def db '0x320',0 |
endg |
;set up netvork configuration |
proc set_network_conf |
locals |
par db 30 dup(?) |
endl |
pushad |
;[net] |
;active |
lea eax,[par] |
invoke ini.get_int,conf_fname, unet, unet_active, 0 |
or eax,eax |
jz .do_not_set_net |
mov eax, [stack_config] |
and eax, 0xFFFFFF80 |
add eax, 3 |
mov [stack_config], eax |
call ash_eth_enable |
;addr |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_addr, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [stack_ip], eax |
;mask |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_mask, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [subnet_mask], eax |
;gate |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_gate, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [gateway_ip], eax |
.do_not_set_net: |
popad |
ret |
endp |
iglobal |
unet db 'net',0 |
unet_active db 'active',0 |
unet_addr db 'addr',0 |
unet_mask db 'mask',0 |
unet_gate db 'gate',0 |
unet_def db 0 |
endg |
; convert string to DWord |
proc strtoint stdcall,strs |
pushad |
262,36 → 208,3 |
popad |
ret |
endp |
; convert string to DWord for IP addres |
proc do_inet_adr stdcall,strs |
pushad |
mov esi,[strs] |
mov ebx,0 |
.next: |
push esi |
@@: |
lodsb |
or al,al |
jz @f |
cmp al,'.' |
jz @f |
jmp @b |
@@: |
mov cl, al |
mov [esi-1],byte 0 |
;pop eax |
call strtoint_dec |
rol eax,24 |
ror ebx,8 |
add ebx,eax |
or cl,cl |
jz @f |
jmp .next |
@@: |
mov [esp+28],ebx |
popad |
ret |
endp |
/kernel/branches/net/core/debug.inc |
---|
13,7 → 13,8 |
cmp ebx, 9 |
ja @f |
jmp dword [sys_debug_services_table+ebx*4] |
@@: ret |
@@: |
ret |
iglobal |
align 4 |
sys_debug_services_table: |
93,7 → 94,8 |
cmp cl, 5 |
jnz .ret |
mov cl, 2 |
.2: mov [CURRENT_TASK+eax+TASKDATA.state], cl |
.2: |
mov [CURRENT_TASK+eax+TASKDATA.state], cl |
.ret: |
sti |
ret |
108,9 → 110,12 |
cmp cl, 2 |
jnz .ret |
mov cl, 5 |
.2: mov [CURRENT_TASK+eax+TASKDATA.state], cl |
.ret: ret |
.1: dec ecx |
.2: |
mov [CURRENT_TASK+eax+TASKDATA.state], cl |
.ret: |
ret |
.1: |
dec ecx |
jmp .2 |
debug_resume: |
122,7 → 127,8 |
shl eax, 5 |
jz .ret |
call do_resume |
.ret: sti |
.ret: |
sti |
ret |
debug_getcontext: |
323,7 → 329,7 |
call get_debuggee_slot |
jc .err |
shr eax, 5 |
; mov ebx, esi |
mov ecx, edi |
call read_process_memory |
sti |
mov dword [esp+32], eax |
349,7 → 355,7 |
call get_debuggee_slot |
jc debug_read_process_memory.err |
shr eax, 5 |
; mov ebx, esi |
mov ecx, edi |
call write_process_memory |
sti |
mov [esp+32], eax |
368,8 → 374,8 |
.1: |
mov eax, ebp |
shl eax, 8 |
mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem] |
test edx, edx |
mov esi, [SLOT_BASE+eax+APPDATA.dbg_event_mem] |
test esi, esi |
jz .ret |
; read buffer header |
push ecx |
376,15 → 382,15 |
push eax |
push eax |
mov eax, ebp |
mov ebx, esp |
mov ecx, 8 |
mov ecx, esp |
mov edx, 8 |
call read_process_memory |
cmp eax, ecx |
cmp eax, edx |
jz @f |
add esp, 12 |
jmp .ret |
@@: |
cmp dword [ebx], 0 |
cmp dword [ecx], 0 |
jg @f |
.2: |
pop ecx |
400,26 → 406,26 |
cli |
jmp .1 |
@@: |
mov ecx, [ebx+8] |
add ecx, [ebx+4] |
cmp ecx, [ebx] |
mov edx, [ecx+8] |
add edx, [ecx+4] |
cmp edx, [ecx] |
ja .2 |
; advance buffer position |
push ecx |
mov ecx, 4 |
sub ebx, ecx |
push edx |
mov edx, 4 |
sub ecx, edx |
mov eax, ebp |
add edx, ecx |
add esi, edx |
call write_process_memory |
pop eax |
; write message |
mov eax, ebp |
add edx, ecx |
add edx, [ebx+8] |
add ebx, 20 |
pop ecx |
pop ecx |
pop ecx |
add esi, edx |
add esi, [ecx+8] |
add ecx, 20 |
pop edx |
pop edx |
pop edx |
call write_process_memory |
; new debug event |
mov eax, ebp |
/kernel/branches/net/core/dll.inc |
---|
9,190 → 9,14 |
DRV_COMPAT equ 5 ;minimal required drivers version |
DRV_CURRENT equ 5 ;current drivers model version |
DRV_CURRENT equ 6 ;current drivers model version |
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT |
PID_KERNEL equ 1 ;os_idle thread |
align 4 |
proc attach_int_handler stdcall, irq:dword, handler:dword, access_rights:dword |
push ebx |
mov ebx, [irq] ;irq num |
test ebx, ebx |
jz .err |
cmp ebx, 15 ; hidnplayr says: we only have 16 IRQ's |
ja .err |
mov eax, [handler] |
test eax, eax |
jz .err |
cmp [irq_owner + 4 * ebx], 0 |
je @f |
mov ecx, [irq_rights + 4 * ebx] ; Rights : 0 - full access, 1 - read only, 2 - forbidden |
test ecx, ecx |
jnz .err |
@@: |
mov [irq_tab+ebx*4], eax |
mov eax, [access_rights] |
mov [irq_rights + 4 * ebx], eax |
mov [irq_owner + 4 * ebx], PID_KERNEL ; all handlers belong to a kernel |
stdcall enable_irq, [irq] |
pop ebx |
mov eax, 1 |
ret |
.err: |
pop ebx |
xor eax, eax |
ret |
endp |
uglobal |
irq_rights rd 16 |
endg |
proc get_int_handler stdcall, irq:dword |
mov eax, [irq] |
cmp [irq_rights + 4 * eax], dword 1 |
ja .err |
mov eax, [irq_tab + 4 * eax] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc detach_int_handler |
ret |
endp |
align 4 |
proc enable_irq stdcall, irq_line:dword |
mov ebx, [irq_line] |
mov edx, 0x21 |
cmp ebx, 8 |
jb @F |
mov edx, 0xA1 |
sub ebx,8 |
@@: |
in al,dx |
btr eax, ebx |
out dx, al |
ret |
endp |
align 16 |
;; proc irq_serv |
irq_serv: |
.irq_1: |
push 1 |
jmp .main |
align 4 |
.irq_2: |
push 2 |
jmp .main |
align 4 |
.irq_3: |
push 3 |
jmp .main |
align 4 |
.irq_4: |
push 4 |
jmp .main |
align 4 |
.irq_5: |
push 5 |
jmp .main |
; align 4 |
; .irq_6: |
; push 6 |
; jmp .main |
align 4 |
.irq_7: |
push 7 |
jmp .main |
align 4 |
.irq_8: |
push 8 |
jmp .main |
align 4 |
.irq_9: |
push 9 |
jmp .main |
align 4 |
.irq_10: |
push 10 |
jmp .main |
align 4 |
.irq_11: |
push 11 |
jmp .main |
align 4 |
.irq_12: |
push 12 |
jmp .main |
; align 4 |
; .irq_13: |
; push 13 |
; jmp .main |
; align 4 |
; .irq_14: |
; push 14 |
; jmp .main |
; align 4 |
; .irq_15: |
; push 15 |
; jmp .main |
align 16 |
.main: |
save_ring3_context |
mov eax, [esp + 32] |
mov bx, app_data ;os_data |
mov ds, bx |
mov es, bx |
cmp [v86_irqhooks+eax*8], 0 |
jnz v86_irq |
mov ebx, [irq_tab+eax*4] |
test ebx, ebx |
jz .exit |
call ebx |
mov [check_idle_semaphore],5 |
.exit: |
cmp dword [esp + 32], 8 |
mov al, 0x20 |
jb @f |
out 0xa0, al |
@@: |
out 0x20, al |
restore_ring3_context |
add esp, 4 |
iret |
align 4 |
proc get_notify stdcall, p_ev:dword |
.wait: |
212,7 → 36,7 |
align 4 |
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword |
push ebx edx |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
220,13 → 44,13 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
pop edx ebx |
pop ebx |
ret |
endp |
align 4 |
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword |
push ebx edx |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
234,13 → 58,13 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
pop edx ebx |
pop ebx |
ret |
endp |
align 4 |
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword |
push ebx edx |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
248,13 → 72,13 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
pop edx ebx |
pop ebx |
ret |
endp |
align 4 |
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword |
push ebx edx |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
263,13 → 87,13 |
mov bl, byte [reg] |
mov ecx, [val] |
call pci_write_reg |
pop edx ebx |
pop ebx |
ret |
endp |
align 4 |
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword |
push ebx edx |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
278,13 → 102,13 |
mov bl, byte [reg] |
mov ecx, [val] |
call pci_write_reg |
pop edx ebx |
pop ebx |
ret |
endp |
align 4 |
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword |
push ebx edx |
push ebx |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
293,7 → 117,7 |
mov bl, byte [reg] |
mov ecx, [val] |
call pci_write_reg |
pop edx ebx |
pop ebx |
ret |
endp |
544,10 → 368,8 |
mov [name], ebx |
pushad |
push eax |
lea eax, [cmd] |
lea ebx, [cmd] |
call file_system_lfn |
pop eax |
popad |
ret |
endp |
597,6 → 419,8 |
stdcall kernel_alloc, [file_size] |
mov [file], eax |
test eax, eax |
jz .fail |
stdcall read_file, [file_name], eax, dword 0, [file_size] |
cmp ebx, [file_size] |
797,6 → 621,7 |
ret |
endp |
align 4 |
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \ |
delta:dword |
locals |
1620,70 → 1445,3 |
call free ;release object memory |
ret |
if 0 |
irq: |
.irq0: |
pusfd |
pushad |
push IRQ_0 |
jmp .master |
.irq_1: |
pusfd |
pushad |
push IRQ_1 |
jmp .master |
.master: |
mov ax, app_data |
mov ds, eax |
mov es, eax |
mov ebx, [esp+4] ;IRQ_xx |
mov eax, [irq_handlers+ebx+4] |
call intr_handler |
mov ecx, [esp+4] |
cmp [irq_actids+ecx*4], 0 |
je @F |
in al, 0x21 |
bts eax, ecx |
out 0x21, al |
mov al, 0x20 |
out 0x20, al |
jmp .restart |
.slave: |
mov ax, app_data |
mov ds, eax |
mov es, eax |
mov ebx, [esp+4] ;IRQ_xx |
mov eax, [irq_handlers+ebx+4] |
call intr_handler |
mov ecx, [esp+4] |
sub ecx, 8 |
cmp [irq_actids+ecx*4], 0 |
je @F |
in al, 0xA1 |
bts eax, ecx |
out 0xA1, al |
mov al, 0x20 |
out 0xA0, al |
out 0x20, al |
.restart: |
mov ebx, [next_slot] |
test ebx, ebx |
jz @F |
mov [next_task],0 |
mov esi, [prev_slot] |
call do_change_task |
add esp, 4 |
iretd |
end if |
/kernel/branches/net/core/export.inc |
---|
28,7 → 28,8 |
local name |
dd (name-OS_BASE) |
common |
ordinal: count = 0 |
ordinal: |
count = 0 |
forward |
dw count |
count = count+1 |
/kernel/branches/net/core/exports.inc |
---|
16,12 → 16,16 |
szGetService db 'GetService',0 |
szServiceHandler db 'ServiceHandler',0 |
szAttachIntHandler db 'AttachIntHandler',0 |
szGetIntHandler db 'GetIntHandler', 0 |
; szGetIntHandler db 'GetIntHandler', 0 |
szFpuSave db 'FpuSave',0 |
szFpuRestore db 'FpuRestore',0 |
szReservePortArea db 'ReservePortArea',0 |
szBoot_Log db 'Boot_Log',0 |
szMutexInit db 'MutexInit',0 |
szMutexLock db 'MutexLock',0 |
szMutexUnlock db 'MutexUnlock',0 |
szPciApi db 'PciApi', 0 |
szPciRead32 db 'PciRead32', 0 |
szPciRead16 db 'PciRead16', 0 |
71,6 → 75,9 |
szSleep db 'Sleep',0 |
szGetTimerTicks db 'GetTimerTicks',0 |
szGetDisplay db 'GetDisplay',0 |
szSetScreen db 'SetScreen',0 |
szStrncat db 'strncat',0 |
szStrncpy db 'strncpy',0 |
szstrncmp db 'strncmp',0 |
78,6 → 85,13 |
szStrchr db 'strchr',0 |
szStrrchr db 'strrchr',0 |
szDiskAdd db 'DiskAdd',0 |
szDiskDel db 'DiskDel',0 |
szDiskMediaChanged db 'DiskMediaChanged',0 |
szTimerHS db 'TimerHS',0 |
szCancelTimerHS db 'CancelTimerHS',0 |
szNetRegDev db 'NetRegDev',0 |
szNetUnRegDev db 'NetUnRegDev',0 |
szNetPtrToNum db 'NetPtrToNum',0 |
91,13 → 105,17 |
dd szGetService , get_service |
dd szServiceHandler , srv_handler |
dd szAttachIntHandler, attach_int_handler |
dd szGetIntHandler , get_int_handler |
; dd szGetIntHandler , get_int_handler |
dd szFpuSave , fpu_save |
dd szFpuRestore , fpu_restore |
dd szReservePortArea , r_f_port_area |
dd szBoot_Log , boot_log |
dd szPciApi , pci_api |
dd szMutexInit , mutex_init ;gcc fastcall |
dd szMutexLock , mutex_lock ;gcc fastcall |
dd szMutexUnlock , mutex_unlock ;gcc fastcall |
dd szPciApi , pci_api_drv |
dd szPciRead32 , pci_read32 |
dd szPciRead16 , pci_read16 |
dd szPciRead8 , pci_read8 |
145,6 → 163,9 |
dd szSleep , delay_ms |
dd szGetTimerTicks , get_timer_ticks |
dd szGetDisplay , get_display |
dd szSetScreen , set_screen |
dd szStrncat , strncat |
dd szStrncpy , strncpy |
dd szstrncmp , strncmp |
152,6 → 173,13 |
dd szStrchr , strchr |
dd szStrrchr , strrchr |
dd szDiskAdd , disk_add |
dd szDiskDel , disk_del |
dd szDiskMediaChanged, disk_media_changed |
dd szTimerHS , timer_hs |
dd szCancelTimerHS , cancel_timer_hs |
dd szNetRegDev , NET_add_device |
dd szNetUnRegDev , NET_remove_device |
dd szNetPtrToNum , NET_ptr_to_num |
/kernel/branches/net/core/ext_lib.inc |
---|
158,7 → 158,8 |
proc dll.Load, import_table:dword |
mov esi,[import_table] |
.next_lib: mov edx,[esi] |
.next_lib: |
mov edx, [esi] |
or edx,edx |
jz .exit |
push esi |
168,7 → 169,8 |
mov al, '/' |
stosb |
mov esi,sysdir_path |
@@: lodsb |
@@: |
lodsb |
stosb |
or al,al |
jnz @b |
179,7 → 181,8 |
pop esi |
push esi |
mov esi,[esi+4] |
@@: lodsb |
@@: |
lodsb |
stosb |
or al,al |
jnz @b |
195,9 → 198,11 |
pop esi |
add esi,8 |
jmp .next_lib |
.exit: xor eax,eax |
.exit: |
xor eax, eax |
ret |
.fail: add esp,4 |
.fail: |
add esp, 4 |
xor eax,eax |
inc eax |
ret |
208,7 → 213,8 |
mov esi,[imp] |
test esi,esi |
jz .done |
.next: lodsd |
.next: |
lodsd |
test eax,eax |
jz .done |
stdcall dll.GetProcAddress,[exp],eax |
216,8 → 222,10 |
jz @f |
mov [esi-4],eax |
jmp .next |
@@: mov dword[esp],0 |
.done: pop eax |
@@: |
mov dword[esp], 0 |
.done: |
pop eax |
ret |
endp |
234,7 → 242,8 |
proc dll.GetProcAddress, exp:dword,sz_name:dword |
mov edx,[exp] |
.next: test edx,edx |
.next: |
test edx, edx |
jz .end |
stdcall strncmp,[edx],[sz_name], dword -1 |
test eax,eax |
241,8 → 250,10 |
jz .ok |
add edx,8 |
jmp .next |
.ok: mov eax,[edx+4] |
.end: ret |
.ok: |
mov eax, [edx+4] |
.end: |
ret |
endp |
;----------------------------------------------------------------------------- |
276,7 → 287,8 |
add ecx,-4 |
cmp ecx,[eax-4] |
je .exit |
@@: mov eax,ebx |
@@: |
mov eax, ebx |
call mem.Alloc |
xchg eax,[esp] |
or eax,eax |
288,7 → 300,8 |
cmp ecx,[edi-4] |
jbe @f |
mov ecx,[edi-4] |
@@: add ecx,3 |
@@: |
add ecx, 3 |
shr ecx,2 |
cld |
rep movsd |
/kernel/branches/net/core/heap.inc |
---|
9,17 → 9,17 |
struc MEM_BLOCK |
{ .next_block dd ? |
{ |
.list LHEAD |
.next_block dd ? ;+8 |
.prev_block dd ? ;+4 |
.list_fd dd ? ;+8 |
.list_bk dd ? ;+12 |
.base dd ? ;+16 |
.size dd ? ;+20 |
.flags dd ? ;+24 |
.handle dd ? ;+28 |
.sizeof: |
} |
MEM_LIST_OFFSET equ 8 |
FREE_BLOCK equ 4 |
USED_BLOCK equ 8 |
DONT_FREE_BLOCK equ 10h |
28,12 → 28,11 |
MEM_BLOCK MEM_BLOCK |
end virtual |
MEM_BLOCK_SIZE equ 8*4 |
block_next equ MEM_BLOCK.next_block |
block_prev equ MEM_BLOCK.prev_block |
list_fd equ MEM_BLOCK.list_fd |
list_bk equ MEM_BLOCK.list_bk |
list_fd equ MEM_BLOCK.list.next |
list_bk equ MEM_BLOCK.list.prev |
block_base equ MEM_BLOCK.base |
block_size equ MEM_BLOCK.size |
block_flags equ MEM_BLOCK.flags |
47,69 → 46,94 |
@@: |
} |
macro remove_from_list op |
{ mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
test edx, edx |
jz @f |
mov [edx+list_bk], ecx |
@@: |
test ecx, ecx |
jz @f |
mov [ecx+list_fd], edx |
@@: |
mov [op+list_fd],0 |
mov [op+list_bk],0 |
} |
align 4 |
md: |
.add_to_used: |
mov eax, [esi+block_base] |
mov ebx, [esi+block_base] |
shr ebx, 6 |
add eax, ebx |
shr ebx, 6 |
add eax, ebx |
shr eax, 12 |
and eax, 63 |
inc [mem_hash_cnt+eax*4] |
macro remove_from_free op |
{ |
remove_from_list op |
lea ecx, [mem_used_list+eax*8] |
list_add esi, ecx |
mov [esi+block_flags], USED_BLOCK |
mov eax, [esi+block_size] |
sub [heap_free], eax |
ret |
align 4 |
.find_used: |
mov ecx, eax |
mov ebx, eax |
shr ebx, 6 |
add ecx, ebx |
shr ebx, 6 |
add ecx, ebx |
shr ecx, 12 |
and ecx, 63 |
mov eax, [op+block_size] |
calc_index eax |
cmp [mem_block_list+eax*4], op |
jne @f |
mov [mem_block_list+eax*4], edx |
@@: |
cmp [mem_block_list+eax*4], 0 |
jne @f |
btr [mem_block_mask], eax |
@@: |
} |
lea ebx, [mem_used_list+ecx*8] |
mov esi, ebx |
.next: |
mov esi, [esi+list_fd] |
cmp esi, ebx |
je .fail |
macro remove_from_used op |
{ |
mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
mov [edx+list_bk], ecx |
mov [ecx+list_fd], edx |
mov [op+list_fd], 0 |
mov [op+list_bk], 0 |
} |
cmp eax, [esi+block_base] |
jne .next |
ret |
.fail: |
xor esi, esi |
ret |
align 4 |
.del_from_used: |
call .find_used |
test esi, esi |
jz .done |
cmp [esi+block_flags], USED_BLOCK |
jne .fatal |
dec [mem_hash_cnt+ecx*4] |
list_del esi |
.done: |
ret |
.fatal: ;FIXME panic here |
xor esi, esi |
ret |
;Initial heap state |
; |
;+heap_size terminator USED_BLOCK |
;+4096*MEM_BLOCK.sizeof free space FREE_BLOCK |
;HEAP_BASE heap_descriptors USED_BLOCK |
; |
align 4 |
proc init_kernel_heap |
mov ecx, 64 |
mov edi, mem_block_list |
xor eax, eax |
cld |
rep stosd |
@@: |
mov eax, edi |
stosd |
stosd |
loop @B |
mov ecx, 512/4 |
mov edi, mem_block_map |
not eax |
rep stosd |
mov ecx, 64 |
mov edi, mem_used_list |
@@: |
mov eax, edi |
stosd |
stosd |
loop @B |
mov [mem_block_start], mem_block_map |
mov [mem_block_end], mem_block_map+512 |
mov [mem_block_arr], HEAP_BASE |
mov eax, mem_used.fd-MEM_LIST_OFFSET |
mov [mem_used.fd], eax |
mov [mem_used.bk], eax |
stdcall alloc_pages, dword 32 |
mov ecx, 32 |
mov edx, eax |
121,8 → 145,10 |
dec ecx |
jnz .l1 |
mov edi, HEAP_BASE |
mov ebx, HEAP_BASE+MEM_BLOCK_SIZE |
mov edi, HEAP_BASE ;descriptors |
mov ebx, HEAP_BASE+MEM_BLOCK.sizeof ;free space |
mov ecx, HEAP_BASE+MEM_BLOCK.sizeof*2 ;terminator |
xor eax, eax |
mov [edi+block_next], ebx |
mov [edi+block_prev], eax |
129,18 → 155,24 |
mov [edi+list_fd], eax |
mov [edi+list_bk], eax |
mov [edi+block_base], HEAP_BASE |
mov [edi+block_size], 4096*MEM_BLOCK_SIZE |
mov [edi+block_size], 4096*MEM_BLOCK.sizeof |
mov [edi+block_flags], USED_BLOCK |
mov [ebx+block_next], eax |
mov [ebx+block_prev], eax |
mov [ebx+list_fd], eax |
mov [ebx+list_bk], eax |
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE |
mov [ecx+block_next], eax |
mov [ecx+block_prev], ebx |
mov [edi+list_fd], eax |
mov [edi+list_bk], eax |
mov [edi+block_base], eax |
mov [edi+block_size], eax |
mov [edi+block_flags], USED_BLOCK |
mov [ebx+block_next], ecx |
mov [ebx+block_prev], edi |
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK.sizeof |
mov ecx, [pg_data.kernel_pages] |
shl ecx, 12 |
sub ecx, HEAP_BASE-OS_BASE+4096*MEM_BLOCK_SIZE |
sub ecx, HEAP_BASE-OS_BASE+4096*MEM_BLOCK.sizeof |
mov [heap_size], ecx |
mov [heap_free], ecx |
mov [ebx+block_size], ecx |
149,11 → 181,24 |
mov [mem_block_mask], eax |
mov [mem_block_mask+4],0x80000000 |
mov [mem_block_list+63*4], ebx |
mov byte [mem_block_map], 0xFC |
and [heap_mutex], 0 |
mov [heap_blocks], 4095 |
mov [free_blocks], 4094 |
mov ecx, mem_block_list+63*8 |
list_add ebx, ecx |
mov ecx, 4096-3-1 |
mov eax, HEAP_BASE+MEM_BLOCK.sizeof*4 |
mov [next_memblock], HEAP_BASE+MEM_BLOCK.sizeof*3 |
@@: |
mov [eax-MEM_BLOCK.sizeof], eax |
add eax, MEM_BLOCK.sizeof |
loop @B |
mov [eax-MEM_BLOCK.sizeof], dword 0 |
mov ecx, heap_mutex |
call mutex_init |
mov [heap_blocks], 4094 |
mov [free_blocks], 4093 |
ret |
endp |
190,11 → 235,18 |
bsf edi, edx |
jz .high_mask |
add ebx, edi |
mov edi, [mem_block_list+ebx*4] |
.check_size: |
lea ecx, [mem_block_list+ebx*8] |
mov edi, ecx |
.next: |
mov edi, [edi+list_fd] |
cmp edi, ecx |
je .err |
cmp eax, [edi+block_size] |
ja .next |
ret |
.err: |
xor edi, edi |
ret |
.high_mask: |
add esi, 4 |
203,66 → 255,24 |
add ebx, 32 |
mov edx, [esi] |
jmp .find |
.next: |
mov edi, [edi+list_fd] |
test edi, edi |
jnz .check_size |
.err: |
xor edi, edi |
ret |
align 4 |
alloc_mem_block: |
mov ebx, [mem_block_start] |
mov ecx, [mem_block_end] |
.l1: |
bsf eax,[ebx]; |
jnz found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
xor eax,eax |
ret |
found: |
btr [ebx], eax |
mov [mem_block_start],ebx |
sub ebx, mem_block_map |
lea eax,[eax+ebx*8] |
shl eax, 5 |
add eax, [mem_block_arr] |
dec [free_blocks] |
ret |
align 4 |
free_mem_block: |
mov dword [eax], 0 |
mov dword [eax+4], 0 |
mov dword [eax+8], 0 |
mov dword [eax+12], 0 |
mov dword [eax+16], 0 |
; mov dword [eax+20], 0 |
mov dword [eax+24], 0 |
mov dword [eax+28], 0 |
mov ebx, [next_memblock] |
mov [eax], ebx |
mov [next_memblock], eax |
xor ebx, ebx |
sub eax, [mem_block_arr] |
shr eax, 5 |
mov ebx, mem_block_map |
bts [ebx], eax |
mov dword [eax+4], ebx |
mov dword [eax+8], ebx |
mov dword [eax+12], ebx |
mov dword [eax+16], ebx |
; mov dword [eax+20], 0 ;don't clear block size |
mov dword [eax+24], ebx |
mov dword [eax+28], ebx |
inc [free_blocks] |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [mem_block_start], eax |
ja @f |
ret |
@@: |
mov [mem_block_start], eax |
ret |
.err: |
xor eax, eax |
ret |
align 4 |
proc alloc_kernel_space stdcall, size:dword |
277,18 → 287,20 |
and eax, not 4095 |
mov [size], eax |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
cmp eax, [heap_free] |
ja .error |
mov ecx, heap_mutex |
call mutex_lock |
mov eax, [size] |
call get_small_block ; eax |
test edi, edi |
jz .error |
jz .error_unlock |
cmp [edi+block_flags], FREE_BLOCK |
jne .error |
jne .error_unlock |
mov [block_ind], ebx ;index of allocated block |
296,11 → 308,13 |
cmp eax, [size] |
je .m_eq_size |
call alloc_mem_block |
and eax, eax |
jz .error |
mov esi, [next_memblock] ;new memory block |
test esi, esi |
jz .error_unlock |
mov esi, eax ;esi - splitted block |
dec [free_blocks] |
mov eax, [esi] |
mov [next_memblock], eax |
mov [esi+block_next], edi |
mov eax, [edi+block_prev] |
308,10 → 322,8 |
mov [edi+block_prev], esi |
mov [esi+list_fd], 0 |
mov [esi+list_bk], 0 |
and eax, eax |
jz @f |
mov [eax+block_next], esi |
@@: |
mov ebx, [edi+block_base] |
mov [esi+block_base], ebx |
mov edx, [size] |
320,75 → 332,48 |
sub [edi+block_size], edx |
mov eax, [edi+block_size] |
shr eax, 12 |
sub eax, 1 |
cmp eax, 63 |
jna @f |
mov eax, 63 |
@@: |
calc_index eax |
cmp eax, [block_ind] |
je .m_eq_ind |
je .add_used |
remove_from_list edi |
list_del edi |
mov ecx, [block_ind] |
mov [mem_block_list+ecx*4], edx |
test edx, edx |
lea edx, [mem_block_list+ecx*8] |
cmp edx, [edx] |
jnz @f |
btr [mem_block_mask], ecx |
@@: |
mov edx, [mem_block_list+eax*4] |
mov [edi+list_fd], edx |
test edx, edx |
jz @f |
mov [edx+list_bk], edi |
@@: |
mov [mem_block_list+eax*4], edi |
bts [mem_block_mask], eax |
.m_eq_ind: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [esi+list_fd], edx |
mov [esi+list_bk], ecx |
mov [ecx+list_fd], esi |
mov [edx+list_bk], esi |
lea edx, [mem_block_list+eax*8] ;edx= list head |
list_add edi, edx |
.add_used: |
mov [esi+block_flags], USED_BLOCK |
call md.add_to_used |
mov ecx, heap_mutex |
call mutex_unlock |
mov eax, [esi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
pop edi |
pop esi |
pop ebx |
ret |
.m_eq_size: |
remove_from_list edi |
mov [mem_block_list+ebx*4], edx |
and edx, edx |
list_del edi |
lea edx, [mem_block_list+ebx*8] |
cmp edx, [edx] |
jnz @f |
btr [mem_block_mask], ebx |
@@: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [edi+list_fd], edx |
mov [edi+list_bk], ecx |
mov [ecx+list_fd], edi |
mov [edx+list_bk], edi |
mov esi, edi |
jmp .add_used |
mov [edi+block_flags], USED_BLOCK |
mov eax, [edi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
pop edi |
pop esi |
pop ebx |
ret |
.error_unlock: |
mov ecx, heap_mutex |
call mutex_unlock |
.error: |
xor eax, eax |
mov [heap_mutex], eax |
pop edi |
pop esi |
pop ebx |
397,66 → 382,49 |
align 4 |
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
push ebx |
push esi |
push edi |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
mov ecx, heap_mutex |
call mutex_lock |
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
call md.del_from_used |
test esi, esi |
jz .fail |
mov eax, [esi+block_size] |
add [heap_free], eax |
mov edi, [esi+block_next] |
test edi, edi |
jz .prev |
cmp [edi+block_flags], FREE_BLOCK |
jne .prev |
remove_from_free edi |
list_del edi |
mov edx, [edi+block_next] |
mov [esi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], esi |
@@: |
mov ecx, [edi+block_size] |
add [esi+block_size], ecx |
calc_index ecx |
lea edx, [mem_block_list+ecx*8] |
cmp edx, [edx] |
jne @F |
btr [mem_block_mask], ecx |
@@: |
mov eax, edi |
call free_mem_block |
.prev: |
mov edi, [esi+block_prev] |
test edi, edi |
jz .insert |
cmp [edi+block_flags], FREE_BLOCK |
jne .insert |
remove_from_used esi |
mov edx, [esi+block_next] |
mov [edi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], edi |
@@: |
mov eax, esi |
call free_mem_block |
465,67 → 433,40 |
add eax, ecx |
mov [edi+block_size], eax |
calc_index eax |
calc_index ecx |
calc_index eax ;new index |
calc_index ecx ;old index |
cmp eax, ecx |
je .m_eq |
push ecx |
remove_from_list edi |
list_del edi |
pop ecx |
cmp [mem_block_list+ecx*4], edi |
jne @f |
mov [mem_block_list+ecx*4], edx |
@@: |
cmp [mem_block_list+ecx*4], 0 |
jne @f |
lea edx, [mem_block_list+ecx*8] |
cmp edx, [edx] |
jne .add_block |
btr [mem_block_mask], ecx |
@@: |
mov esi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], edi |
mov [edi+list_fd], esi |
test esi, esi |
jz @f |
mov [esi+list_bk], edi |
@@: |
.add_block: |
bts [mem_block_mask], eax |
lea edx, [mem_block_list+eax*8] |
list_add edi, edx |
.m_eq: |
mov ecx, heap_mutex |
call mutex_unlock |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
pop edi |
pop esi |
pop ebx |
not eax |
ret |
.insert: |
remove_from_used esi |
mov [esi+block_flags], FREE_BLOCK |
mov eax, [esi+block_size] |
calc_index eax |
mov edi, esi |
jmp .add_block |
mov edi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], esi |
mov [esi+list_fd], edi |
test edi, edi |
jz @f |
mov [edi+list_bk], esi |
@@: |
bts [mem_block_mask], eax |
mov [esi+block_flags],FREE_BLOCK |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
pop edi |
pop esi |
pop ebx |
ret |
.fail: |
mov ecx, heap_mutex |
call mutex_unlock |
xor eax, eax |
mov [heap_mutex], eax |
pop edi |
pop esi |
pop ebx |
ret |
endp |
605,37 → 546,31 |
align 4 |
proc kernel_free stdcall, base:dword |
push ebx esi |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
mov ecx, heap_mutex |
call mutex_lock |
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
call md.find_used |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
mov ecx, heap_mutex |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
and [heap_mutex], 0 |
call mutex_unlock |
push ecx |
mov ecx, [esi+block_size]; |
mov eax, [esi+block_base] |
mov ecx, [esi+block_size] |
shr ecx, 12 |
call release_pages ;eax, ecx |
pop ecx |
stdcall free_kernel_space, [base] |
pop esi ebx |
ret |
.fail: |
and [heap_mutex], 0 |
call mutex_unlock |
xor eax, eax |
pop esi ebx |
ret |
endp |
1521,7 → 1456,7 |
test edi, edi |
jz .next |
lea eax, [edi+SMEM.name] |
lea edi, [edi+SMEM.name] |
stdcall strncmp, [name], edi, 32 |
test eax, eax |
jne .next |
1528,6 → 1463,7 |
stdcall user_free, [esi+SMAP.base] |
mov eax, esi |
call [esi+APPOBJ.destroy] |
@@: |
popfd |
/kernel/branches/net/core/irq.inc |
---|
0,0 → 1,229 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
IRQ_RESERVED equ 24 |
IRQ_POOL_SIZE equ 48 |
uglobal |
align 16 |
irqh_tab rd LHEAD.sizeof * IRQ_RESERVED / 4 |
irqh_pool rd IRQH.sizeof * IRQ_POOL_SIZE /4 |
next_irqh rd 1 |
irq_active_set rd 1 |
irq_failed rd IRQ_RESERVED |
endg |
align 4 |
init_irqs: |
mov ecx, IRQ_RESERVED |
mov edi, irqh_tab |
@@: |
mov eax, edi |
stosd |
stosd |
loop @B |
mov ecx, IRQ_POOL_SIZE-1 |
mov eax, irqh_pool+IRQH.sizeof |
mov [next_irqh], irqh_pool |
@@: |
mov [eax-IRQH.sizeof], eax |
add eax, IRQH.sizeof |
loop @B |
mov [eax-IRQH.sizeof], dword 0 |
ret |
align 4 |
proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword |
locals |
.irqh dd ? |
endl |
and [.irqh], 0 |
push ebx |
mov ebx, [irq] ;irq num |
test ebx, ebx |
jz .err |
cmp ebx, IRQ_RESERVED |
jae .err |
mov edx, [handler] |
test edx, edx |
jz .err |
pushfd |
cli |
;allocate handler |
mov ecx, [next_irqh] |
test ecx, ecx |
jz .fail |
mov eax, [ecx] |
mov [next_irqh], eax |
mov [.irqh], ecx |
mov [irq_failed+ebx*4], 0;clear counter |
mov eax, [user_data] |
mov [ecx+IRQH.handler], edx |
mov [ecx+IRQH.data], eax |
lea edx, [irqh_tab+ebx*8] |
list_add_tail ecx, edx ;clobber eax |
stdcall enable_irq, ebx |
.fail: |
popfd |
.err: |
pop ebx |
mov eax, [.irqh] |
ret |
endp |
if 0 |
align 4 |
proc get_int_handler stdcall, irq:dword |
mov eax, [irq] |
cmp eax, 15 |
ja .fail |
mov eax, [irq_tab + 4 * eax] |
ret |
.fail: |
xor eax, eax |
ret |
endp |
end if |
align 4 |
proc detach_int_handler |
ret |
endp |
macro irq_serv_h [num] { |
forward |
align 4 |
.irq_#num : |
push num |
jmp .main |
} |
align 16 |
irq_serv: |
; .irq_1: |
; push 1 |
; jmp .main |
; etc... |
irq_serv_h 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15 |
irq_serv_h 16, 17, 18, 19, 20, 21, 22, 23 |
purge irq_serv_h |
align 16 |
.main: |
save_ring3_context |
mov ebp, [esp + 32] |
mov bx, app_data;os_data |
mov ds, bx |
mov es, bx |
cmp [v86_irqhooks+ebp*8], 0 |
jnz v86_irq |
cmp bp, 6 |
jnz @f |
push ebp |
call [fdc_irq_func] |
pop ebp |
@@: |
cmp bp, 14 |
jnz @f |
push ebp |
call [irq14_func] |
pop ebp |
@@: |
cmp bp, 15 |
jnz @f |
push ebp |
call [irq15_func] |
pop ebp |
@@: |
bts [irq_active_set], ebp |
lea esi, [irqh_tab+ebp*8] ; esi= list head |
mov ebx, esi |
.next: |
mov ebx, [ebx+IRQH.list.next]; ebx= irqh pointer |
cmp ebx, esi |
je .done |
push ebx ; FIX THIS |
push edi |
push esi |
push [ebx+IRQH.data] |
call [ebx+IRQH.handler] |
add esp, 4 |
pop esi |
pop edi |
pop ebx |
test eax, eax |
jz .next |
btr [irq_active_set], ebp |
jmp .next |
.done: |
btr [irq_active_set], ebp |
jnc .exit |
inc [irq_failed+ebp*4] |
.exit: |
mov [check_idle_semaphore], 5 |
mov ecx, ebp |
call irq_eoi |
restore_ring3_context |
add esp, 4 |
iret |
align 4 |
irqD: |
push eax |
push ecx |
xor eax, eax |
out 0xf0, al |
mov cl, 13 |
call irq_eoi |
pop ecx |
pop eax |
iret |
/kernel/branches/net/core/malloc.inc |
---|
20,7 → 20,7 |
; esi= nb |
; ebx= idx |
; |
align 16 |
align 4 |
malloc: |
push esi |
31,8 → 31,8 |
and esi, -8 |
add esi, 8 |
mov ebx, mst.mutex |
call wait_mutex ;ebx |
mov ecx, mst.mutex |
call mutex_lock |
cmp esi, 256 |
jae .large |
92,9 → 92,13 |
pop edi |
pop ebp |
.done: |
mov esi, eax |
mov ecx, mst.mutex |
call mutex_unlock |
mov eax, esi |
pop esi |
mov [mst.mutex], 0 |
ret |
.split: |
lea ebx, [edx+8] ;ebx=mem |
133,10 → 137,10 |
mov [edx+12], eax ; F->bk = r; |
mov [eax+8], edx ; r->fd = F; |
mov [eax+12], ecx ; r->bk = B; |
mov eax, ebx |
pop esi |
mov [mst.mutex], 0 |
ret |
jmp .done |
.small: |
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) |
150,9 → 154,8 |
call malloc_small |
test eax, eax |
jz .from_top |
pop esi |
and [mst.mutex], 0 |
ret |
jmp .done |
.large: |
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0) |
189,19 → 192,19 |
mov [edx+4], eax |
mov [ecx+4], esi |
lea eax, [ecx+8] |
pop esi |
and [mst.mutex], 0 |
ret |
jmp .done |
.fail: |
xor eax, eax |
pop esi |
and [mst.mutex], 0 |
ret |
jmp .done |
; param |
; eax= mem |
align 4 |
free: |
test eax, eax |
jz .exit |
free: |
push edi |
mov edi, eax |
add edi, -8 |
211,8 → 214,8 |
test byte [edi+4], 2 |
je .fail |
mov ebx, mst.mutex |
call wait_mutex ;ebx |
mov ecx, mst.mutex |
call mutex_lock |
; psize = p->head & (~3); |
289,11 → 292,16 |
mov [mst.top], edi |
mov [edi+4], eax |
.fail2: |
and [mst.mutex], 0 |
mov esi, eax |
mov ecx, mst.mutex |
call mutex_unlock |
mov eax, esi |
pop esi |
.fail: |
pop edi |
.exit: |
ret |
@@: |
; nsize = next->head & ~INUSE_BITS; |
410,13 → 418,15 |
mov [esi+8], edx ;P->fd = F |
mov [esi+12], eax ;P->bk = B |
pop esi |
and [mst.mutex], 0 |
mov ecx, mst.mutex |
call mutex_unlock |
ret |
.large: |
mov ebx, eax |
call insert_large_chunk |
pop esi |
and [mst.mutex], 0 |
mov ecx, mst.mutex |
call mutex_unlock |
ret |
1025,5 → 1035,8 |
cmp eax, mst.smallbins+512 |
jb @B |
mov ecx, mst.mutex |
call mutex_init |
ret |
/kernel/branches/net/core/memory.inc |
---|
171,9 → 171,14 |
push ebx |
push edi |
mov eax, [size] |
add eax, [base] |
add eax, 4095 |
and eax, -4096 |
mov ecx, [base] |
and ecx, -4096 |
sub eax, ecx |
mov [size], eax |
stdcall alloc_kernel_space, eax |
test eax, eax |
jz .fail |
189,9 → 194,7 |
or edx, [flags] |
@@: |
mov [page_tabs+eax*4], edx |
; push eax |
invlpg [ebx] |
; pop eax |
inc eax |
add ebx, edi |
add edx, edi |
214,30 → 217,32 |
align 4 |
commit_pages: |
push edi |
test ecx, ecx |
jz .fail |
push edi |
push eax |
push ecx |
mov ecx, pg_data.mutex |
call mutex_lock |
pop ecx |
pop eax |
mov edi, ebx |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
shr edi, 12 |
lea edi, [page_tabs+edi*4] |
@@: |
stosd |
invlpg [ebx] |
add eax, 0x1000 |
add ebx, 0x1000 |
loop @B |
mov edx, 0x1000 |
mov ebx, edi |
shr ebx, 12 |
@@: |
mov [page_tabs+ebx*4], eax |
; push eax |
invlpg [edi] |
; pop eax |
add edi, edx |
add eax, edx |
inc ebx |
dec ecx |
jnz @B |
mov [pg_data.pg_mutex],ecx |
pop edi |
mov ecx, pg_data.mutex |
call mutex_unlock |
.fail: |
pop edi |
ret |
248,16 → 253,22 |
align 4 |
release_pages: |
pushad |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
push ebp |
push esi |
push edi |
push ebx |
mov esi, eax |
mov edi, eax |
shr esi, 10 |
add esi, page_tabs |
shr esi, 12 |
lea esi, [page_tabs+esi*4] |
push ecx |
mov ecx, pg_data.mutex |
call mutex_lock |
pop ecx |
mov ebp, [pg_data.pages_free] |
mov ebx, [page_start] |
mov edx, sys_pgmap |
264,9 → 275,7 |
@@: |
xor eax, eax |
xchg eax, [esi] |
push eax |
invlpg [edi] |
pop eax |
test eax, 1 |
jz .next |
285,11 → 294,16 |
.next: |
add edi, 0x1000 |
add esi, 4 |
dec ecx |
jnz @B |
loop @B |
mov [pg_data.pages_free], ebp |
and [pg_data.pg_mutex],0 |
popad |
mov ecx, pg_data.mutex |
call mutex_unlock |
pop ebx |
pop edi |
pop esi |
pop ebp |
ret |
; param |
423,8 → 437,8 |
align 4 |
proc new_mem_resize stdcall, new_size:dword |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov ecx, pg_data.mutex |
call mutex_lock |
mov edi, [new_size] |
add edi,4095 |
456,7 → 470,8 |
pop eax |
call free_page |
.next: add edi, 1 |
.next: |
add edi, 1 |
cmp edi, esi |
jb @B |
464,8 → 479,10 |
mov ebx, [new_size] |
call update_mem_size |
mov ecx, pg_data.mutex |
call mutex_unlock |
xor eax, eax |
dec [pg_data.pg_mutex] |
ret |
.expand: |
539,9 → 556,11 |
pop edi |
pop esi |
.exit: |
mov ecx, pg_data.mutex |
call mutex_unlock |
xor eax, eax |
inc eax |
dec [pg_data.pg_mutex] |
ret |
endp |
779,7 → 798,8 |
; and eax, 0xFFFFF000 |
; stdcall map_page, edi, eax |
@@: mov edi, [lin_addr] |
@@: |
mov edi, [lin_addr] |
and edi, 0xFFFFF000 |
mov ecx, [buf_size] |
add ecx, 4095 |
839,7 → 859,8 |
jz .exit |
stdcall map_page,edi,eax,PG_UW |
@@: mov edi, [lin_addr] |
@@: |
mov edi, [lin_addr] |
and edi, 0xFFFFF000 |
mov ecx, [buf_size] |
add ecx, 4095 |
970,7 → 991,8 |
add edx, 4095 |
and edx, not 4095 |
.touch: mov eax, [ecx] |
.touch: |
mov eax, [ecx] |
add ecx, 0x1000 |
cmp ecx, edx |
jb .touch |
/kernel/branches/net/core/peload.inc |
---|
283,10 → 283,18 |
alloc_page, 'AllocPage', \ ; gcc ABI |
alloc_pages, 'AllocPages', \ ; stdcall |
commit_pages, 'CommitPages', \ ; eax, ebx, ecx |
\ |
create_event, 'CreateEvent', \ ; ecx, esi |
destroy_event, 'DestroyEvent', \ ; |
raise_event, 'RaiseEvent', \ ; eax, ebx, edx, esi |
wait_event, 'WaitEvent', \ ; eax, ebx |
get_event_ex, 'GetEvent', \ ; edi |
\ |
create_kernel_object, 'CreateObject', \ |
create_ring_buffer, 'CreateRingBuffer', \ ; stdcall |
destroy_kernel_object, 'DestroyObject', \ |
free_kernel_space, 'FreeKernelSpace', \ ; stdcall |
free_page, 'FreePage', \ ; eax |
kernel_alloc, 'KernelAlloc', \ ; stdcall |
kernel_free, 'KernelFree', \ ; stdcall |
malloc, 'Kmalloc', \ |
294,9 → 302,14 |
map_io_mem, 'MapIoMem', \ ; stdcall |
get_pg_addr, 'GetPgAddr', \ ; eax |
\ |
mutex_init, 'MutexInit', \ ; gcc fastcall |
mutex_lock, 'MutexLock', \ ; gcc fastcall |
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall |
\ |
get_display, 'GetDisplay', \ |
set_screen, 'SetScreen', \ |
pci_api, 'PciApi', \ |
window._.get_rect, 'GetWindowRect', \ ; gcc fastcall |
pci_api_drv, 'PciApi', \ |
pci_read8, 'PciRead8', \ ; stdcall |
pci_read16, 'PciRead16', \ ; stdcall |
pci_read32, 'PciRead32', \ ; stdcall |
304,6 → 317,7 |
pci_write16, 'PciWrite16', \ ; stdcall |
pci_write32, 'PciWrite32', \ ; stdcall |
\ |
get_pid, 'GetPid', \ |
get_service, 'GetService', \ ; |
reg_service, 'RegService', \ ; stdcall |
attach_int_handler, 'AttachIntHandler', \ ; stdcall |
311,8 → 325,12 |
user_free, 'UserFree', \ ; stdcall |
unmap_pages, 'UnmapPages', \ ; eax, ecx |
sys_msg_board_str, 'SysMsgBoardStr', \ |
get_timer_ticks, 'GetTimerTicks', \ |
get_stack_base, 'GetStackBase', \ |
delay_hs, 'Delay', \ ; ebx |
set_mouse_data, 'SetMouseData' |
set_mouse_data, 'SetMouseData', \ ; |
set_keyboard_data, 'SetKeyboardData', \ ; gcc fastcall |
timer_hs, 'TimerHs' ; stdcall |
/kernel/branches/net/core/sched.inc |
---|
27,8 → 27,8 |
add [next_usage_update],100 |
call updatecputimes |
.nocounter: |
mov al,0x20 ; send End Of Interrupt signal |
out 0x20,al |
xor ecx, ecx ; send End Of Interrupt signal |
call irq_eoi |
btr dword[DONT_SWITCH], 0 |
jc .return |
call find_next_task |
60,7 → 60,8 |
end if |
call find_next_task |
jz .return ; the same task -> skip switch |
@@: mov byte[DONT_SWITCH], 1 |
@@: |
mov byte[DONT_SWITCH], 1 |
call do_change_task |
.return: |
popad |
121,7 → 122,8 |
jb @f |
xor bh, bh |
mov edi,CURRENT_TASK |
@@: inc bh ; ebx += APPDATA.size |
@@: |
inc bh ; ebx += APPDATA.size |
add edi,0x20 ; edi += TASKDATA.size |
mov al, [edi+TASKDATA.state] |
test al, al |
140,7 → 142,8 |
sub ecx, [ebx+APPDATA.wait_begin] |
cmp ecx, [ebx+APPDATA.wait_timeout] |
jb .loop |
@@: mov [ebx+APPDATA.wait_param], eax ; retval for wait |
@@: |
mov [ebx+APPDATA.wait_param], eax ; retval for wait |
mov [edi+TASKDATA.state], 0 |
.found: |
mov [CURRENT_TASK],bh |
214,10 → 217,96 |
mov reg,eax |
} lodsReg dr0, dr1, dr2, dr3, dr7 |
purge lodsReg |
@@: ret |
@@: |
ret |
;end. |
struct MUTEX_WAITER |
list LHEAD |
task dd ? |
ends |
;void __fastcall mutex_init(struct mutex *lock) |
align 4 |
mutex_init: |
mov [ecx+MUTEX.lhead.next], ecx |
mov [ecx+MUTEX.lhead.prev], ecx |
mov [ecx+MUTEX.count], 1 |
ret |
;void __fastcall mutex_lock(struct mutex *lock) |
align 4 |
mutex_lock: |
dec [ecx+MUTEX.count] |
jns .done |
pushfd |
cli |
sub esp, sizeof.MUTEX_WAITER |
list_add_tail esp, ecx ;esp= new waiter, ecx= list head |
mov edx, [TASK_BASE] |
mov [esp+MUTEX_WAITER.task], edx |
.forever: |
mov eax, -1 |
xchg eax, [ecx+MUTEX.count] |
dec eax |
jz @F |
mov [edx+TASKDATA.state], 1 |
call change_task |
jmp .forever |
@@: |
mov edx, [esp+MUTEX_WAITER.list.next] |
mov eax, [esp+MUTEX_WAITER.list.prev] |
mov [eax+MUTEX_WAITER.list.next], edx |
mov [edx+MUTEX_WAITER.list.prev], eax |
cmp [ecx+MUTEX.lhead.next], ecx |
jne @F |
mov [ecx+MUTEX.count], 0 |
@@: |
add esp, sizeof.MUTEX_WAITER |
popfd |
.done: |
ret |
;void __fastcall mutex_unlock(struct mutex *lock) |
align 4 |
mutex_unlock: |
pushfd |
cli |
mov eax, [ecx+MUTEX.lhead.next] |
cmp eax, ecx |
mov [ecx+MUTEX.count], 1 |
je @F |
mov eax, [eax+MUTEX_WAITER.task] |
mov [eax+TASKDATA.state], 0 |
@@: |
popfd |
ret |
purge MUTEX_WAITER |
if 0 |
struc TIMER |
{ |
.next dd ? |
/kernel/branches/net/core/sys32.inc |
---|
20,7 → 20,8 |
mov esi, sys_int |
mov ecx, 0x40 |
mov eax, (10001110b shl 24) + os_code |
@@: movsw ;low word of code-entry |
@@: |
movsw ;low word of code-entry |
stosd ;interrupt gate type : os_code selector |
movsw ;high word of code-entry |
loop @b |
39,17 → 40,22 |
times 12 dd unknown_interrupt ;int_20..int_31 |
;interrupt handlers addresses (for interrupt gate construction) |
; 0x20 .. 0x2F - IRQ handlers |
dd irq0, irq_serv.irq_1, irq_serv.irq_2 |
if USE_COM_IRQ |
dd irq_serv.irq_3, irq_serv.irq_4 |
else |
dd p_irq3, p_irq4 ;??? íåñòûêîâêà |
end if |
dd irq_serv.irq_5, p_irq6, irq_serv.irq_7 |
dd irq_serv.irq_5, irq_serv.irq_6, irq_serv.irq_7 |
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 |
dd irq_serv.irq_11, irq_serv.irq_12, irqD,p_irq14,p_irq15 |
times 16 dd unknown_interrupt ;int_0x30..int_0x3F |
dd irq_serv.irq_11, irq_serv.irq_12, irqD, irq_serv.irq_14, irq_serv.irq_15 |
dd irq_serv.irq_16 |
dd irq_serv.irq_17 |
dd irq_serv.irq_18 |
dd irq_serv.irq_19 |
dd irq_serv.irq_20 |
dd irq_serv.irq_21 |
dd irq_serv.irq_22 |
dd irq_serv.irq_23 |
times 32 - IRQ_RESERVED dd unknown_interrupt |
;int_0x40 gate trap (for directly copied) |
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 |
122,8 → 128,9 |
reg_esi equ esp+0x04 |
reg_edi equ esp+0x00 |
Mov ds,ax,app_data ; çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ |
mov es,ax ; â ñåãìåíòíûå ðåãèñòðû |
mov ax, app_data ;èñêëþ÷åíèå |
mov ds, ax ;çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ |
mov es, ax ;â ðåãèñòðû |
cld ; è ïðèâîäèì DF ê ñòàíäàðòó |
movzx ebx,bl |
; redirect to V86 manager? (EFLAGS & 0x20000) != 0? |
132,13 → 139,15 |
cmp bl,14 ; #PF |
jne @f |
call page_fault_handler ; SEE: core/memory.inc |
@@: mov esi, [current_slot] |
@@: |
mov esi, [current_slot] |
btr [esi+APPDATA.except_mask], ebx |
jnc @f |
mov eax,[esi+APPDATA.exc_handler] |
test eax, eax |
jnz IRetToUserHook |
@@: cli |
@@: |
cli |
mov eax, [esi+APPDATA.debugger_slot] |
test eax, eax |
jnz .debug |
159,10 → 168,12 |
mov dr6, edx |
mov edx, dr7 |
mov cl, not 8 |
.l1: shl dl,2 |
.l1: |
shl dl, 2 |
jc @f |
and bl, cl |
@@: sar cl,1 |
@@: |
sar cl, 1 |
jc .l1 |
mov cl, 3 ; debug_message code=debug_exception |
.notify: |
186,11 → 197,21 |
stosd |
mov [edi], ebx |
restore_ring3_context |
; simply return control to interrupted process |
unknown_interrupt: |
iretd |
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
; bl - error vector |
show_error_parameters: |
cmp bl, 0x06 |
jnz .no_ud |
push ebx |
mov ebx, ud_user_message |
mov ebp, notifyapp |
call fs_execute_from_sysdir_param |
pop ebx |
.no_ud: |
mov edx,[TASK_BASE] ;not scratched below |
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid] |
cmp bl, 0x08 |
197,8 → 218,10 |
jb .l0 |
cmp bl, 0x0e |
jbe .l1 |
.l0: mov bl, 0x09 |
.l1: mov eax,[msg_fault_sel+ebx*4 - 0x08*4] |
.l0: |
mov bl, 0x09 |
.l1: |
mov eax, [msg_fault_sel+ebx*4 - 0x08*4] |
DEBUGF 1, "K : %s\n", eax |
mov eax, [reg_cs3+4] |
mov edi, msg_sel_app |
207,7 → 230,8 |
je @f |
mov edi, msg_sel_ker |
mov ebx, [reg_esp0+4] |
@@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] |
@@: |
DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] |
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] |
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx |
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi |
228,154 → 252,8 |
restore reg_esi |
restore reg_edi |
; irq1 -> hid/keyboard.inc |
macro irqh [num] { |
p_irq#num : |
mov edi, num |
jmp irqhandler |
} |
p_irq6: |
save_ring3_context |
mov ax, app_data ;os_data |
mov ds, ax |
mov es, ax |
mov edi, 6 |
cmp [v86_irqhooks+edi*8], 0 |
jnz v86_irq2 |
call fdc_irq |
call ready_for_next_irq |
restore_ring3_context |
iret |
p_irq14: |
save_ring3_context |
mov ax, app_data ;os_data |
mov ds, ax |
mov es, ax |
mov edi, 14 |
cmp [v86_irqhooks+edi*8], 0 |
jnz v86_irq2 |
; mov byte [BOOT_VAR + 0x48E], 0xFF |
call [irq14_func] |
call ready_for_next_irq_1 |
restore_ring3_context |
iret |
p_irq15: |
save_ring3_context |
mov ax, app_data ;os_data |
mov ds, ax |
mov es, ax |
mov edi, 15 |
cmp [v86_irqhooks+edi*8], 0 |
jnz v86_irq2 |
; mov byte [BOOT_VAR + 0x48E], 0xFF |
call [irq15_func] |
call ready_for_next_irq_1 |
restore_ring3_context |
iret |
ready_for_next_irq: |
mov eax,5 |
mov [check_idle_semaphore],eax |
; mov al, 0x20 |
add eax,(0x20-0x5) |
out 0x20, al |
ret |
;destroy eax |
ready_for_next_irq_1: |
mov eax,5 |
mov [check_idle_semaphore],eax |
; mov al, 0x20 |
add eax,(0x20-0x5) |
out 0xa0,al |
out 0x20, al |
ret |
irqD: |
push eax |
xor eax,eax |
out 0xf0,al |
mov al,0x20 |
out 0xa0,al |
out 0x20,al |
pop eax |
iret |
irqh 2,3,4,5,7,8,9,10,11 |
irqhandler: |
mov esi,edi ; 1 |
shl esi,6 ; 1 |
add esi,irq00read ; 1 |
shl edi,12 ; 1 |
add edi,IRQ_SAVE |
mov ecx,16 |
irqnewread: |
dec ecx |
js irqover |
movzx edx, word [esi] ; 2+ |
test edx, edx ; 1 |
jz irqover |
mov ebx, [edi] ; address of begin of buffer in edi ; + 0x0 dword - data size |
mov eax, 4000 ; + 0x4 dword - data begin offset |
cmp ebx, eax |
je irqfull |
add ebx, [edi + 0x4] ; add data size to data begin offset |
cmp ebx, eax ; if end of buffer, begin cycle again |
jb @f |
xor ebx, ebx |
@@: |
add ebx, edi |
movzx eax, byte[esi + 3] ; get type of data being received 1 - byte, 2 - word |
dec eax |
jz irqbyte |
dec eax |
jnz noirqword |
in ax,dx |
cmp ebx, 3999 ; check for address odd in the end of buffer |
jne .odd |
mov [ebx + 0x10], ax |
jmp .add_size |
.odd: |
mov [ebx + 0x10], al ; I could make mistake here :) |
mov [edi + 0x10], ah |
.add_size: |
add dword [edi], 2 |
jmp nextport |
irqbyte: |
in al,dx |
mov [ebx + 0x10],al |
inc dword [edi] |
nextport: |
add esi,4 |
jmp irqnewread |
noirqword: |
irqfull: |
irqover: |
ret |
align 4 |
set_application_table_status: |
push eax |
390,7 → 268,7 |
ret |
align 4 |
clear_application_table_status: |
push eax |
416,6 → 294,7 |
; * eax = 0 - óñïåøíî |
; * eax = 1 - íåäîñòàòî÷íî ïàìÿòè |
align 4 |
sys_resize_app_memory: |
; ebx = 1 - resize |
; ecx = new amount of memory |
437,6 → 316,7 |
; param |
; esi= slot |
align 4 |
terminate: ; terminate application |
.slot equ esp ;locals |
708,25 → 588,6 |
and [bgrlock], 0 |
@@: |
pusha ; remove all irq reservations |
mov eax,esi |
shl eax, 5 |
mov eax,[eax+CURRENT_TASK+TASKDATA.pid] |
mov edi,irq_owner |
xor ebx, ebx |
xor edx, edx |
newirqfree: |
cmp [edi + 4 * ebx], eax |
jne nofreeirq |
mov [edi + 4 * ebx], edx ; remove irq reservation |
mov [irq_tab + 4 * ebx], edx ; remove irq handler |
mov [irq_rights + 4 * ebx], edx ; set access rights to full access |
nofreeirq: |
inc ebx |
cmp ebx, 16 |
jb newirqfree |
popa |
pusha ; remove all port reservations |
mov edx,esi |
shl edx, 5 |
812,17 → 673,18 |
and [application_table_status],0 |
;mov esi,process_terminated |
;call sys_msg_board_str |
mov eax, [.slot] |
call SOCKET_process_end |
add esp, 4 |
ret |
restore .slot |
iglobal |
if lang eq ru |
boot_sched_1 db '®§¤ ¨¥ GDT TSS 㪠§ ⥫ï',0 |
boot_sched_2 db '®§¤ ¨¥ IDT â ¡«¨æë',0 |
else |
boot_sched_1 db 'Building gdt tss pointer',0 |
boot_sched_2 db 'Building IDT table',0 |
end if |
endg |
/kernel/branches/net/core/syscall.inc |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
17,6 → 17,7 |
mov edx, esi |
mov esi, edi |
movzx edi, byte[esp+28 + 4] |
sub edi, 53 |
call dword [servetable+edi*4] |
ret |
101,78 → 102,17 |
align 4 |
servetable: |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd file_system ; 58-Common file system interface |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd 0 |
dd sound_interface ; 55-Sound interface |
dd 0 |
dd 0 |
dd file_system ; 58-Common file system interface |
dd 0 |
dd sys_IPC ; 60-Inter Process Communication |
dd sys_gs ; 61-Direct graphics access |
dd sys_pci ; 62-PCI functions |
dd 0 ; 62-PCI functions |
dd sys_msg_board ; 63-System message board |
dd 0 |
dd syscall_putimage_palette; 65-PutImagePalette |
dd sys_process_def ; 66-Process definitions - keyboard |
dd sys_window_move ; 67-Window move or resize |
dd 0 |
dd 0 |
dd file_system_lfn ; 70-Common file system interface, version 2 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; NEW SYSTEM FUNCTIONS TABLE ;; |
180,7 → 120,7 |
align 4 |
servetable2: |
dd sys_drawwindow ; 0-DrawWindow |
dd syscall_draw_window ; 0-DrawWindow |
dd syscall_setpixel ; 1-SetPixel |
dd sys_getkey ; 2-GetKey |
dd sys_clock ; 3-GetTime |
221,11 → 161,11 |
dd syscall_drawline ; 38-DrawLine |
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,. |
dd set_app_param ; 40-WantEvents |
dd syscall_getirqowner ; 41-GetIrqOwner |
dd get_irq_data ; 42-ReadIrqData |
dd undefined_syscall ; 41- deprecated GetIrqOwner |
dd undefined_syscall ; 42- deprecated ReadIrqData |
dd sys_outport ; 43-SendDeviceData |
dd sys_programirq ; 44-ProgramIrqs |
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq |
dd undefined_syscall ; 44- deprecated ProgramIrqs |
dd undefined_syscall ; 45- deprecated ReserveIrq and FreeIrq |
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea |
dd display_number ; 47-WriteNum |
dd syscall_display_settings ; 48-SetRedrawType and SetButtonType |
232,28 → 172,28 |
dd sys_apm ; 49-Advanced Power Management (APM) |
dd syscall_set_window_shape ; 50-Window shape & scale |
dd syscall_threads ; 51-Threads |
dd undefined_syscall ; 52-Stack driver status |
dd undefined_syscall ; 53-Socket interface |
dd undefined_syscall ; 52 old network stack |
dd undefined_syscall ; 53 old network stack |
dd undefined_syscall ; 54-reserved |
dd cross_order ; 55-Sound interface |
dd sound_interface ; 55-Sound interface |
dd undefined_syscall ; 56-reserved |
dd sys_pcibios ; 57-PCI BIOS32 |
dd cross_order ; 58-Common file system interface |
dd undefined_syscall ; 59-reserved |
dd cross_order ; 60-Inter Process Communication |
dd cross_order ; 61-Direct graphics access |
dd cross_order ; 62-PCI functions |
dd sys_IPC ; 60-Inter Process Communication |
dd sys_gs ; 61-Direct graphics access |
dd pci_api ;cross_order ; 62-PCI functions |
dd cross_order ; 63-System message board |
dd sys_resize_app_memory ; 64-Resize application memory usage |
dd cross_order ; 65-PutImagePalette |
dd cross_order ; 66-Process definitions - keyboard |
dd cross_order ; 67-Window move or resize |
dd sys_putimage_palette ; 65-PutImagePalette |
dd sys_process_def ; 66-Process definitions - keyboard |
dd syscall_move_window ; 67-Window move or resize |
dd f68 ; 68-Some internal services |
dd sys_debug_services ; 69-Debug |
dd cross_order ; 70-Common file system interface, version 2 |
dd syscall_windowsettings ; 71-Window settings |
dd file_system_lfn ; 70-Common file system interface, version 2 |
dd syscall_window_settings ; 71-Window settings |
dd sys_sendwindowmsg ; 72-Send window message |
dd undefined_syscall ; 73-reserved for blitter |
dd blit_32 ; 73-blitter; |
dd sys_network ; 74-Network stack |
dd sys_socket ; 75-Sockets |
dd sys_protocols ; 76-Protocols |
/kernel/branches/net/core/taskman.inc |
---|
48,6 → 48,7 |
fs_execute_from_sysdir: |
xor ebx, ebx |
fs_execute_from_sysdir_param: |
xor edx, edx |
mov esi, sysdir_path |
126,7 → 127,7 |
@@: |
lea eax, [filename] |
stdcall load_file, eax |
mov ecx, -ERROR_FILE_NOT_FOUND |
mov esi, -ERROR_FILE_NOT_FOUND |
test eax, eax |
jz .err_file |
135,13 → 136,10 |
lea ebx, [hdr_cmdline] |
call test_app_header |
mov ecx, -0x1F |
mov esi, -0x1F |
test eax, eax |
jz .err_hdr |
;mov esi, new_process_loading |
;call sys_msg_board_str ; write message to message board |
.wait_lock: |
cmp [application_table_status],0 |
je .get_lock |
158,7 → 156,7 |
call get_new_process_place |
test eax, eax |
mov ecx, -0x20 ; too many processes |
mov esi, -0x20 ; too many processes |
jz .err |
mov [slot], eax |
193,7 → 191,7 |
mov [save_cr3], ebx |
stdcall create_app_space,[hdr_mem],[file_base],[file_size] |
mov ecx, -30 ; no memory |
mov esi, -30; no memory |
test eax, eax |
jz .failed |
249,7 → 247,7 |
.err_file: |
xor eax, eax |
mov [application_table_status],eax |
mov eax, ecx |
mov eax, esi |
ret |
endp |
359,8 → 357,8 |
app_tabs dd ? |
endl |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov ecx, pg_data.mutex |
call mutex_lock |
xor eax, eax |
mov [dir_addr], eax |
479,11 → 477,13 |
.done: |
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP |
dec [pg_data.pg_mutex] |
mov ecx, pg_data.mutex |
call mutex_unlock |
mov eax, [dir_addr] |
ret |
.fail: |
dec [pg_data.pg_mutex] |
mov ecx, pg_data.mutex |
call mutex_unlock |
cmp [dir_addr], 0 |
je @f |
stdcall destroy_app_space, [dir_addr], 0 |
553,10 → 553,10 |
jg .ret |
;if there isn't threads then clear memory. |
mov esi, [dlls_list] |
call destroy_all_hdlls |
call destroy_all_hdlls;ecx=APPDATA |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov ecx, pg_data.mutex |
call mutex_lock |
mov eax, [pg_dir] |
and eax, not 0xFFF |
582,7 → 582,8 |
.exit: |
stdcall map_page,[tmp_task_ptab],0,PG_UNMAP |
stdcall map_page,[tmp_task_pdir],0,PG_UNMAP |
dec [pg_data.pg_mutex] |
mov ecx, pg_data.mutex |
call mutex_unlock |
.ret: |
ret |
endp |
955,25 → 956,7 |
ret |
endp |
; param |
; ebx=mutex |
align 4 |
wait_mutex: |
;;Maxis use atomic bts for mutex 4.4.2009 |
push eax |
push ebx |
.do_wait: |
bts dword [ebx],0 |
jnc .locked |
call change_task |
jmp .do_wait |
.locked: |
pop ebx |
pop eax |
ret |
align 4 |
tls_app_entry: |
call init_heap |
1166,4 → 1149,13 |
ret |
endp |
align 4 |
get_stack_base: |
mov eax, [current_slot] |
mov eax, [eax+APPDATA.pl0_stack] |
ret |
include "debug.inc" |
/kernel/branches/net/core/timers.inc |
---|
0,0 → 1,205 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 2381 $ |
; Simple implementation of timers. All timers are organized in a double-linked |
; list, and the OS loop after every timer tick processes the list. |
; This structure describes a timer for the kernel. |
struct TIMER |
Next dd ? |
Prev dd ? |
; These fields organize a double-linked list of all timers. |
TimerFunc dd ? |
; Function to be called when the timer is activated. |
UserData dd ? |
; The value that is passed as is to .TimerFunc. |
Time dd ? |
; Time at which the timer should be activated. |
Interval dd ? |
; Interval between activations of the timer, in 0.01s. |
ends |
iglobal |
align 4 |
; The head of timer list. |
timer_list: |
dd timer_list |
dd timer_list |
endg |
uglobal |
; These two variables are used to synchronize access to the global list. |
; Logically, they form an recursive mutex. Physically, the first variable holds |
; the slot number of the current owner or 0, the second variable holds the |
; recursion count. |
; The mutex should be recursive to allow a timer function to add/delete other |
; timers or itself. |
timer_list_owner dd 0 |
timer_list_numlocks dd 0 |
; A timer function can delete any timer, including itself and the next timer in |
; the chain. To handle such situation correctly, we keep the next timer in a |
; global variable, so the removing operation can update it. |
timer_next dd 0 |
endg |
; This internal function acquires the lock for the global list. |
lock_timer_list: |
mov edx, [CURRENT_TASK] |
@@: |
xor eax, eax |
lock cmpxchg [timer_list_owner], edx |
jz @f |
cmp eax, edx |
jz @f |
call change_task |
jmp @b |
@@: |
inc [timer_list_numlocks] |
ret |
; This internal function releases the lock for the global list. |
unlock_timer_list: |
dec [timer_list_numlocks] |
jnz .nothing |
mov [timer_list_owner], 0 |
.nothing: |
ret |
; This function adds a timer. |
; If deltaStart is nonzero, the timer is activated after deltaStart hundredths |
; of seconds starting from the current time. If interval is nonzero, the timer |
; is activated every deltaWork hundredths of seconds starting from the first |
; activation. The activated timer calls timerFunc as stdcall function with one |
; argument userData. |
; Return value is NULL if something has failed or some value which is opaque |
; for the caller. Later this value can be used for cancel_timer_hs. |
proc timer_hs stdcall uses ebx, deltaStart:dword, interval:dword, \ |
timerFunc:dword, userData:dword |
; 1. Allocate memory for the TIMER structure. |
; 1a. Call the allocator. |
push sizeof.TIMER |
pop eax |
call malloc |
; 1b. If allocation failed, return (go to 5) with eax = 0. |
test eax, eax |
jz .nothing |
; 2. Setup the TIMER structure. |
xchg ebx, eax |
; 2a. Copy values from the arguments. |
mov ecx, [interval] |
mov [ebx+TIMER.Interval], ecx |
mov ecx, [timerFunc] |
mov [ebx+TIMER.TimerFunc], ecx |
mov ecx, [userData] |
mov [ebx+TIMER.UserData], ecx |
; 2b. Get time of the next activation. |
mov ecx, [deltaStart] |
test ecx, ecx |
jnz @f |
mov ecx, [interval] |
@@: |
add ecx, [timer_ticks] |
mov [ebx+TIMER.Time], ecx |
; 3. Insert the TIMER structure to the global list. |
; 3a. Acquire the lock. |
call lock_timer_list |
; 3b. Insert an item at ebx to the tail of the timer_list. |
mov eax, timer_list |
mov ecx, [eax+TIMER.Prev] |
mov [ebx+TIMER.Next], eax |
mov [ebx+TIMER.Prev], ecx |
mov [eax+TIMER.Prev], ebx |
mov [ecx+TIMER.Next], ebx |
; 3c. Release the lock. |
call unlock_timer_list |
; 4. Return with eax = pointer to TIMER structure. |
xchg ebx, eax |
.nothing: |
; 5. Returning. |
ret |
endp |
; This function removes a timer. |
; The only argument is [esp+4] = the value which was returned from timer_hs. |
cancel_timer_hs: |
push ebx ; save used register to be stdcall |
; 1. Remove the TIMER structure from the global list. |
; 1a. Acquire the lock. |
call lock_timer_list |
mov ebx, [esp+4+4] |
; 1b. Delete an item at ebx from the double-linked list. |
mov eax, [ebx+TIMER.Next] |
mov ecx, [ebx+TIMER.Prev] |
mov [eax+TIMER.Prev], ecx |
mov [ecx+TIMER.Next], eax |
; 1c. If we are removing the next timer in currently processing chain, |
; the next timer for this timer becomes new next timer. |
cmp ebx, [timer_next] |
jnz @f |
mov [timer_next], eax |
@@: |
; 1d. Release the lock. |
call unlock_timer_list |
; 2. Free the TIMER structure. |
xchg eax, ebx |
call free |
; 3. Return. |
pop ebx ; restore used register to be stdcall |
ret 4 ; purge one dword argument to be stdcall |
; This function is regularly called from osloop. It processes the global list |
; and activates the corresponding timers. |
check_timers: |
; 1. Acquire the lock. |
call lock_timer_list |
; 2. Loop over all registered timers, checking time. |
; 2a. Get the first item. |
mov eax, [timer_list+TIMER.Next] |
mov [timer_next], eax |
.loop: |
; 2b. Check for end of list. |
cmp eax, timer_list |
jz .done |
; 2c. Get and store the next timer. |
mov edx, [eax+TIMER.Next] |
mov [timer_next], edx |
; 2d. Check time for timer activation. |
; We can't just compare [timer_ticks] and [TIMER.Time], since overflows are |
; possible: if the current time is 0FFFFFFFFh ticks and timer should be |
; activated in 3 ticks, the simple comparison will produce incorrect result. |
; So we calculate the difference [timer_ticks] - [TIMER.Time]; if it is |
; non-negative, the time is over; if it is negative, then either the time is |
; not over or we have not processed this timer for 2^31 ticks, what is very |
; unlikely. |
mov edx, [timer_ticks] |
sub edx, [eax+TIMER.Time] |
js .next |
; The timer should be activated now. |
; 2e. Store the timer data in the stack. This is required since 2f can delete |
; the timer, invalidating the content. |
push [eax+TIMER.UserData] ; parameter for TimerFunc |
push [eax+TIMER.TimerFunc] ; to be restored in 2g |
; 2f. Calculate time of next activation or delete the timer if it is one-shot. |
mov ecx, [eax+TIMER.Interval] |
add [eax+TIMER.Time], ecx |
test ecx, ecx |
jnz .nodelete |
stdcall cancel_timer_hs, eax |
.nodelete: |
; 2g. Activate timer, using data from the stack. |
pop eax |
call eax |
.next: |
; 2h. Advance to the next timer and continue the loop. |
mov eax, [timer_next] |
jmp .loop |
.done: |
; 3. Release the lock. |
call unlock_timer_list |
; 4. Return. |
ret |
/kernel/branches/net/core/v86.inc |
---|
91,10 → 91,10 |
; now V86 specific: initialize known addresses in first Mb |
pop eax |
; first page - BIOS data (shared between all machines!) |
; physical address = 0x2f0000 |
; linear address = BOOT_VAR = OS_BASE + 0x2f0000 |
mov dword [eax], (BOOT_VAR - OS_BASE) or 111b |
mov dword [eax+800h], BOOT_VAR |
; physical address = 0 |
; linear address = OS_BASE |
mov dword [eax], 111b |
mov dword [eax+800h], OS_BASE |
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!) |
; physical address = 0x9C000 |
; linear address = 0x8009C000 |
219,12 → 219,12 |
mov [sys_v86_machine], eax |
test eax, eax |
jz .ret |
mov byte [BOOT_VAR + 0x500], 0xCD |
mov byte [BOOT_VAR + 0x501], 0x13 |
mov byte [BOOT_VAR + 0x502], 0xF4 |
mov byte [BOOT_VAR + 0x503], 0xCD |
mov byte [BOOT_VAR + 0x504], 0x10 |
mov byte [BOOT_VAR + 0x505], 0xF4 |
mov byte [OS_BASE + 0x500], 0xCD |
mov byte [OS_BASE + 0x501], 0x13 |
mov byte [OS_BASE + 0x502], 0xF4 |
mov byte [OS_BASE + 0x503], 0xCD |
mov byte [OS_BASE + 0x504], 0x10 |
mov byte [OS_BASE + 0x505], 0xF4 |
mov esi, eax |
mov ebx, [eax+V86_machine.pagedir] |
; one page for stack, two pages for results (0x2000 bytes = 16 sectors) |
328,7 → 328,7 |
cmp edx, -1 |
jz .noirqhook |
uglobal |
v86_irqhooks rd 16*2 |
v86_irqhooks rd IRQ_RESERVED * 2 |
endg |
cmp [v86_irqhooks+edx*8], 0 |
jz @f |
371,7 → 371,8 |
jne @f |
xor eax, eax |
mov dr6, eax |
@@: mov eax, [esp+v86_regs.size+10h+18h] |
@@: |
mov eax, [esp+v86_regs.size+10h+18h] |
cmp word [esp+v86_regs.eip], ax |
jnz @f |
shr eax, 16 |
805,7 → 806,6 |
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx |
mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx |
mov cr3, eax |
; mov [irq_tab+5*4], 0 |
sti |
popad |
839,9 → 839,10 |
; mov byte [BOOT_VAR + 48Eh], 0FFh |
; ret |
align 4 |
v86_irq: |
; push irq/pushad/jmp v86_irq |
; eax = irq |
; ebp = irq |
lea esi, [esp+1Ch] |
lea edi, [esi+4] |
mov ecx, 8 |
848,7 → 849,7 |
std |
rep movsd |
cld |
mov edi, eax |
mov edi, ebp |
pop eax |
v86_irq2: |
mov esi, [v86_irqhooks+edi*8] ; get VM handle |
898,12 → 899,8 |
pop ecx |
.cont: |
loop .scan |
mov al, 20h |
out 20h, al |
cmp edi, 8 |
jb @f |
out 0A0h, al |
@@: |
mov ecx, edi |
call irq_eoi |
popad |
iretd |
.found: |
/kernel/branches/net/data16.inc |
---|
12,7 → 12,8 |
preboot_lfb db 0 |
preboot_bootlog db 0 |
boot_drive db 0 |
bx_from_load: dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007] |
bx_from_load: |
dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007] |
; a,b,c,d - âèí÷åñòåðû, r - ðàì äèñê |
; # äèñêà... ñèìâîë, à íå áàéò. '1', à íå 1 |
22,10 → 23,12 |
dd 0 |
dw 0 |
if ~ defined extended_primary_loader ; restart from memory is not supported in extended primary loader cfg |
kernel_restart_bootblock: |
db 1 ; version |
dw 1 ; floppy image is in memory |
dd 0 ; cannot save parameters |
end if |
; table for move to extended memory (int 15h, ah=87h) |
align 8 |
53,3 → 56,36 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
if defined extended_primary_loader |
; look in PrimaryLoader.txt for the description |
bootdevice dw 0 ; ax from primary loader |
bootfs dw 0 ; bx from primary loader |
bootcallback dd 0 ; ds:si from primary loader |
; data for configuration file loading, look in PrimaryLoader.txt |
config_file_struct: |
dw 0, 4000h ; load to 4000:0000 |
dw 16 ; read no more than 16*4K = 64K |
db 'config.ini',0 |
; data for configuration file parsing |
macro config_variable string,parser |
{ |
local len |
len dw 0 |
db string |
store word $ - len - 2 at len |
dw parser |
} |
config_file_variables: |
config_variable 'timeout', parse_timeout |
config_variable 'resolution', parse_resolution |
config_variable 'vbemode', parse_vbemode |
; config_variable 'vrr', parse_vrr |
config_variable 'biosdisks', parse_biosdisks |
config_variable 'imgfrom', parse_imgfrom |
dw 0 |
; data for image file loading, look in PrimaryLoader.txt |
image_file_struct: |
dw 0, 4000h ; load to 4000:0000 |
dw 16 ; read no more than 16*4K = 64K |
db 'kolibri.img',0 |
end if |
/kernel/branches/net/data32.inc |
---|
47,20 → 47,43 |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
if lang eq ru |
boot_fonts db 'à¨äâë § £à㦥ë',0 |
boot_memdetect db '®«¨ç¥á⢮ ®¯¥à ⨢®© ¯ ¬ïâ¨',' ',' ¡',0 |
boot_tss db 'áâ ®¢ª TSSs',0 |
boot_cpuid db '⥨¥ CPUIDs',0 |
boot_devices db '®¨áª ãáâனáâ¢',0 |
boot_timer db 'áâ ®¢ª â ©¬¥à ',0 |
boot_irqs db '¥à¥®¯à¥¤¥«¥¨¥ IRQ',0 |
boot_setmouse db 'áâ ®¢ª ¬ëè¨',0 |
boot_windefs db 'áâ ®¢ª áâ஥ª ®ª® ¯® 㬮«ç ¨î',0 |
boot_bgr db 'áâ ®¢ª ä® ',0 |
boot_resirqports db '¥§¥à¢¨à®¢ ¨¥ IRQ ¨ ¯®à⮢',0 |
boot_setrports db 'áâ ®¢ª ¤à¥á®¢ IRQ',0 |
boot_setostask db '®§¤ ¨¥ ¯à®æ¥áá ï¤à ',0 |
boot_allirqs db 'âªàë⨥ ¢á¥å IRQ',0 |
boot_tsc db '⥨¥ TSC',0 |
boot_cpufreq db ' áâ®â ¯à®æ¥áá®à ',' ',' æ',0 |
boot_pal_ega db 'áâ ®¢ª EGA/CGA 320x200 ¯ «¨âàë',0 |
boot_pal_vga db 'áâ ®¢ª VGA 640x480 ¯ «¨âàë',0 |
boot_failed db ' £à㧪 ¯¥à¢®£® ¯à¨«®¦¥¨ï ¥ 㤠« áì',0 |
boot_mtrr db 'áâ ®¢ª MTRR',0 |
if preboot_blogesc |
boot_tasking db 'ᥠ£®â®¢® ¤«ï § ¯ã᪠, ¦¬¨âॠESC ¤«ï áâ àâ ',0 |
end if |
else |
boot_fonts db 'Fonts loaded',0 |
boot_memdetect db 'Determining amount of memory',0 |
boot_fonts db 'Fonts loaded',0 |
boot_tss db 'Setting TSSs',0 |
boot_cpuid db 'Reading CPUIDs',0 |
boot_devices db 'Detecting devices',0 |
boot_timer db 'Setting timer',0 |
boot_irqs db 'Reprogramming IRQs',0 |
boot_setmouse db 'Setting mouse',0 |
boot_windefs db 'Setting window defaults',0 |
boot_bgr db 'Calculating background',0 |
boot_resirqports db 'Reserving IRQs & ports',0 |
boot_setrports db 'Setting addresses for IRQs',0 |
boot_setostask db 'Setting OS task',0 |
boot_allirqs db 'Unmasking all IRQs',0 |
boot_allirqs db 'Unmasking IRQs',0 |
boot_tsc db 'Reading TSC',0 |
boot_cpufreq db 'CPU frequency is ',' ',' MHz',0 |
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0 |
70,7 → 93,11 |
if preboot_blogesc |
boot_tasking db 'All set - press ESC to start',0 |
end if |
end if |
boot_APIC_found db 'APIC enabled', 0 |
boot_APIC_nfound db 'APIC not found', 0 |
;new_process_loading db 'K : New Process - loading',13,10,0 |
;new_process_running db 'K : New Process - done',13,10,0 |
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 |
101,6 → 128,12 |
read_firstapp db '/sys/' |
firstapp db 'LAUNCHER',0 |
notifyapp db '@notify',0 |
if lang eq ru |
ud_user_message db '訡ª : ¥¯®¤¤¥à¦¨¢ ¥¬ ï ¨áâàãªæ¨ï ¯à®æ¥áá®à ',0 |
else |
ud_user_message db 'Error: unsupported processor instruction',0 |
end if |
char db '/sys/FONTS/CHAR.MT',0 |
char2 db '/sys/FONTS/CHAR2.MT',0 |
108,9 → 141,10 |
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 |
align 4 |
259,51 → 293,23 |
align 16 |
cur_saved_data rb 4096 |
fpu_data: rb 512 |
fpu_data: |
rb 512 |
; device irq owners |
irq_owner rd 16 ; process id |
mem_block_list rd 64*2 |
mem_used_list rd 64*2 |
mem_hash_cnt rd 64 |
; on irq read ports |
irq00read rd 16 |
irq01read rd 16 |
irq02read rd 16 |
irq03read rd 16 |
irq04read rd 16 |
irq05read rd 16 |
irq06read rd 16 |
irq07read rd 16 |
irq08read rd 16 |
irq09read rd 16 |
irq10read rd 16 |
irq11read rd 16 |
irq12read rd 16 |
irq13read rd 16 |
irq14read rd 16 |
irq15read rd 16 |
irq_tab rd 16 |
mem_block_map rb 512 |
mem_block_list rd 64 |
large_block_list rd 31 |
mem_block_mask rd 2 |
large_block_mask rd 1 |
mem_used.fd rd 1 |
mem_used.bk rd 1 |
mem_block_arr rd 1 |
mem_block_start rd 1 |
mem_block_end rd 1 |
heap_mutex rd 1 |
heap_mutex MUTEX |
heap_size rd 1 |
heap_free rd 1 |
heap_blocks rd 1 |
free_blocks rd 1 |
mem_block_mask rd 2 |
next_memblock rd 1 |
mst MEM_STATE |
page_start rd 1 |
368,6 → 374,7 |
hdbase rd 1 ; for boot 0x1f0 |
hdid rd 1 |
hdpos rd 1 ; for boot 0x1 |
label known_part dword |
fat32part rd 1 ; for boot 0x1 |
cdpos rd 1 |
/kernel/branches/net/detect/dev_fd.inc |
---|
28,3 → 28,10 |
jnz wait_cmos |
in al,0x71 |
mov [DRIVE_DATA],al |
test al, al |
jz @f |
in al, 0x21 |
and al, 10111111b ; Enable IRQ6 |
out 0x21, al |
@@: |
/kernel/branches/net/detect/dev_hdcd.inc |
---|
124,7 → 124,8 |
ret |
@@Error6: |
mov [DevErrorCode],6 |
@@End: ret |
@@End: |
ret |
iglobal |
258,15 → 259,20 |
mov [DevErrorCode],0 |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Err1: mov [DevErrorCode],1 |
@@Err1: |
mov [DevErrorCode], 1 |
ret |
@@Err2: mov [DevErrorCode],2 |
@@Err2: |
mov [DevErrorCode], 2 |
ret |
@@Err3: mov [DevErrorCode],3 |
@@Err3: |
mov [DevErrorCode], 3 |
ret |
@@Err4: mov [DevErrorCode],4 |
@@Err4: |
mov [DevErrorCode], 4 |
ret |
@@Err5: mov [DevErrorCode],5 |
@@Err5: |
mov [DevErrorCode], 5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
ret |
373,11 → 379,14 |
mov [DevErrorCode],0 |
ret |
; Îáðàáîòêà îøèáîê |
@@Err1_2: mov [DevErrorCode],1 |
@@Err1_2: |
mov [DevErrorCode], 1 |
ret |
@@Err3_2: mov [DevErrorCode],3 |
@@Err3_2: |
mov [DevErrorCode], 3 |
ret |
@@Err4_2: mov [DevErrorCode],4 |
@@Err4_2: |
mov [DevErrorCode], 4 |
; Çàïèñàòü êîä îøèáêè |
ret |
/kernel/branches/net/detect/getcache.inc |
---|
209,4 → 209,4 |
; mov [cache_ide0_pointer],HD_CACHE |
; mov [cache_ide0_system_data],HD_CACHE+65536 |
; mov [cache_ide0_system_sad_size],1919 |
popa |
popa |
/kernel/branches/net/detect/sear_par.inc |
---|
20,15 → 20,20 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
mov [fat32part],1 |
mov [known_part], 1 |
search_partitions_ide0_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide1 |
call set_PARTITION_variables |
test [problem_partition], 2 |
jnz search_partitions_ide1 ; not found part |
test [problem_partition], 1 |
jnz @F ; not found known_part |
;cmp [problem_partition],0 |
;jne search_partitions_ide1 |
inc byte [DRIVE_DATA+2] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
@@: |
inc [known_part] |
jmp search_partitions_ide0_1 |
search_partitions_ide1: |
37,15 → 42,20 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
mov [fat32part],1 |
mov [known_part], 1 |
search_partitions_ide1_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide2 |
call set_PARTITION_variables |
test [problem_partition], 2 |
jnz search_partitions_ide2 |
test [problem_partition], 1 |
jnz @F |
;cmp [problem_partition],0 |
;jne search_partitions_ide2 |
inc byte [DRIVE_DATA+3] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
@@: |
inc [known_part] |
jmp search_partitions_ide1_1 |
search_partitions_ide2: |
54,15 → 64,20 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
mov [fat32part],1 |
mov [known_part], 1 |
search_partitions_ide2_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide3 |
call set_PARTITION_variables |
test [problem_partition], 2 |
jnz search_partitions_ide3 |
test [problem_partition], 1 |
jnz @F |
;cmp [problem_partition],0 |
;jne search_partitions_ide3 |
inc byte [DRIVE_DATA+4] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
@@: |
inc [known_part] |
jmp search_partitions_ide2_1 |
search_partitions_ide3: |
71,15 → 86,20 |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
mov [fat32part],1 |
mov [known_part], 1 |
search_partitions_ide3_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne end_search_partitions_ide |
call set_PARTITION_variables |
test [problem_partition], 2 |
jnz end_search_partitions_ide |
test [problem_partition], 1 |
jnz @F |
;cmp [problem_partition],0 |
;jne end_search_partitions_ide |
inc byte [DRIVE_DATA+5] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
@@: |
inc [known_part] |
jmp search_partitions_ide3_1 |
end_search_partitions_ide: |
91,16 → 111,21 |
push ecx |
mov eax, [hdpos] |
and [BiosDiskPartitions+(eax-80h)*4], 0 |
mov [fat32part], 1 |
mov [known_part], 1 |
search_partitions_bd: |
call set_FAT32_variables |
cmp [problem_partition], 0 |
jne end_search_partitions_bd |
call set_PARTITION_variables |
test [problem_partition], 2 |
jnz end_search_partitions_bd |
test [problem_partition], 1 |
jnz @F |
;cmp [problem_partition], 0 |
;jne end_search_partitions_bd |
mov eax, [hdpos] |
inc [BiosDiskPartitions+(eax-80h)*4] |
call partition_data_transfer |
add [transfer_adress], 100 |
inc [fat32part] |
@@: |
inc [known_part] |
jmp search_partitions_bd |
end_search_partitions_bd: |
pop ecx |
110,7 → 135,7 |
partition_data_transfer: |
mov edi,[transfer_adress] |
mov esi,PARTITION_START |
mov esi, PARTITION_START ;start of file_system_data |
mov ecx,(file_system_data_size+3)/4 |
rep movsd |
ret |
130,24 → 155,3 |
end_search_partitions: |
;PARTITION_START dd 0x3f |
;PARTITION_END dd 0 |
;SECTORS_PER_FAT dd 0x1f3a |
;NUMBER_OF_FATS dd 0x2 |
;SECTORS_PER_CLUSTER dd 0x8 |
;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes |
;ROOT_CLUSTER dd 2 ; first rootdir cluster |
;FAT_START dd 0 ; start of fat table |
;ROOT_START dd 0 ; start of rootdir (only fat16) |
;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) |
;DATA_START dd 0 ; start of data area (=first cluster 2) |
;LAST_CLUSTER dd 0 ; last availabe cluster |
;ADR_FSINFO dd 0 ; used only by fat32 |
; |
;fatRESERVED dd 0x0FFFFFF6 |
;fatBAD dd 0x0FFFFFF7 |
;fatEND dd 0x0FFFFFF8 |
;fatMASK dd 0x0FFFFFFF |
; |
;fat_type db 0 ; 0=none, 16=fat16, 32=fat32 |
/kernel/branches/net/fdo.inc |
---|
62,13 → 62,11 |
jmp ..label |
..str db _str,0 |
..label: |
; add esp,4*8+4 |
esp equ esp+4*8+4 |
mov edx,..str |
esp equ _esp |
; sub esp,4*8+4 |
else |
esp equ esp+4*8+4 |
mov edx,_str |
esp equ _esp |
end if |
if ~_num eq |
if _num eqtype eax |
254,7 → 252,8 |
debug_func fdo_debug_outstr |
debug_beginf |
mov eax,1 |
.l1: dec esi |
.l1: |
dec esi |
js .l2 |
movzx ebx,byte[edx] |
or bl,bl |
263,7 → 262,8 |
call ecx ; sys_msg_board |
inc edx |
jmp .l1 |
.l2: ret |
.l2: |
ret |
debug_endf |
debug_func fdo_debug_outdec |
277,20 → 277,24 |
mov al,'-' |
call fdo_debug_outchar |
pop eax |
@@: push 10 |
@@: |
push 10 |
pop ecx |
push -'0' |
.l1: xor edx,edx |
.l1: |
xor edx, edx |
div ecx |
push edx |
test eax,eax |
jnz .l1 |
.l2: pop eax |
.l2: |
pop eax |
add al,'0' |
jz .l3 |
call fdo_debug_outchar |
jmp .l2 |
.l3: ret |
.l3: |
ret |
debug_endf |
debug_func fdo_debug_outhex |
301,7 → 305,8 |
add cl,8 |
shl cl,2 |
rol eax,cl |
.l1: rol eax,4 |
.l1: |
rol eax, 4 |
push eax |
and eax,0x0000000F |
mov al,[__fdo_hexdigits+eax] |
/kernel/branches/net/fs/ext2.inc |
---|
0,0 → 1,1318 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; 02.02.2010 turbanoff - support 70.5 ;; |
;; 23.01.2010 turbanoff - support 70.0 70.1 ;; |
;; ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 2381 $ |
EXT2_BAD_INO = 1 |
EXT2_ROOT_INO = 2 |
EXT2_ACL_IDX_INO = 3 |
EXT2_ACL_DATA_INO = 4 |
EXT2_BOOT_LOADER_INO= 5 |
EXT2_UNDEL_DIR_INO = 6 |
;type inode |
EXT2_S_IFREG = 0x8000 |
EXT2_S_IFDIR = 0x4000 |
;user inode right's |
EXT2_S_IRUSR = 0x0100 |
EXT2_S_IWUSR = 0x0080 |
EXT2_S_IXUSR = 0x0040 |
;group inode right's |
EXT2_S_IRGRP = 0x0020 |
EXT2_S_IWGRP = 0x0010 |
EXT2_S_IXGRP = 0x0008 |
;other inode right's |
EXT2_S_IROTH = 0x0004 |
EXT2_S_IWOTH = 0x0002 |
EXT2_S_IXOTH = 0x0001 |
EXT2_777_MODE = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \ |
EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \ |
EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR |
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге |
EXT2_FT_DIR = 2 ;это папка |
FS_FT_HIDDEN = 2 |
FS_FT_DIR = 0x10 ;это папка |
FS_FT_ASCII = 0 ;имя в ascii |
FS_FT_UNICODE = 1 ;имя в unicode |
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 |
uglobal |
EXT2_files_in_folder dd ? ;всего файлов в папке |
EXT2_read_in_folder dd ? ;сколько файлов "считали" |
EXT2_end_block dd ? ;конец очередного блока папки |
EXT2_counter_blocks dd ? |
EXT2_filename rb 256 |
EXT2_parent_name rb 256 |
EXT2_name_len dd ? |
endg |
struct EXT2_INODE_STRUC |
i_mode dw ? |
i_uid dw ? |
i_size dd ? |
i_atime dd ? |
i_ctime dd ? |
i_mtime dd ? |
i_dtime dd ? |
i_gid dw ? |
i_links_count dw ? |
i_blocks dd ? |
i_flags dd ? |
i_osd1 dd ? |
i_block rd 15 |
i_generation dd ? |
i_file_acl dd ? |
i_dir_acl dd ? |
i_faddr dd ? |
i_osd2 dd ? ; 1..12 |
ends |
struct EXT2_DIR_STRUC |
inode dd ? |
rec_len dw ? |
name_len db ? |
file_type db ? |
name db ? ; 0..255 |
ends |
struct EXT2_BLOCK_GROUP_DESC |
block_bitmap dd ? |
inode_bitmap dd ? |
inode_table dd ? |
free_blocks_count dw ? |
free_inodes_count dw ? |
used_dirs_count dw ? |
ends |
struct EXT2_SB_STRUC |
inodes_count dd ? ;+0 |
blocks_count dd ? ;+4 |
r_block_count dd ? ;+8 |
free_block_count dd ? ;+12 |
free_inodes_count dd ? ;+16 |
first_data_block dd ? ;+20 |
log_block_size dd ? ;+24 |
log_frag_size dd ? ;+28 |
blocks_per_group dd ? ;+32 |
frags_per_group dd ? ;+36 |
inodes_per_group dd ? ;+40 |
mtime dd ? ;+44 |
wtime dd ? ;+48 |
mnt_count dw ? ;+52 |
max_mnt_count dw ? ;+54 |
magic dw ? ;+56 |
state dw ? ;+58 |
errors dw ? ;+60 |
minor_rev_level dw ? ;+62 |
lastcheck dd ? ;+64 |
check_intervals dd ? ;+68 |
creator_os dd ? ;+72 |
rev_level dd ? ;+76 |
def_resuid dw ? ;+80 |
def_resgid dw ? ;+82 |
first_ino dd ? ;+84 |
inode_size dw ? ;+88 |
block_group_nr dw ? ;+90 |
feature_compat dd ? ;+92 |
feature_incompat dd ? ;+96 |
feature_ro_compat dd ? ;+100 |
uuid rb 16 ;+104 |
volume_name rb 16 ;+120 |
last_mounted rb 64 ;+136 |
algo_bitmap dd ? ;+200 |
prealloc_blocks db ? ;+204 |
preallock_dir_blocks db ? ;+205 |
dw ? ;+206 alignment |
journal_uuid rb 16 ;+208 |
journal_inum dd ? ;+224 |
journal_dev dd ? ;+228 |
last_orphan dd ? ;+232 |
hash_seed rd 4 ;+236 |
def_hash_version db ? ;+252 |
rb 3 ;+253 reserved |
default_mount_options dd ? ;+256 |
first_meta_bg dd ? ;+260 |
ends |
ext2_test_superblock: |
cmp [fs_type], 0x83 |
jne .no |
mov eax, [PARTITION_START] |
add eax, 2 ;superblock start at 1024b |
call hd_read |
cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3 |
ja .no |
cmp word [ebx+56], 0xEF53 ;s_magic |
jne .no |
cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1) |
jne .no |
mov eax, [ebx+96] |
test eax, EXT2_FEATURE_INCOMPAT_FILETYPE |
jz .no |
test eax, not EXT2_FEATURE_INCOMPAT_FILETYPE |
jnz .no |
; OK, this is correct EXT2 superblock |
clc |
ret |
.no: |
; No, this superblock isn't EXT2 |
stc |
ret |
ext2_setup: |
mov [fs_type], 2 |
push 512 |
call kernel_alloc ; mem for superblock |
mov esi, ebx |
mov edi, eax |
mov ecx, 512/4 |
rep movsd ; copy sb to reserved mem |
mov ebx, eax |
mov [ext2_data.sb], eax |
mov eax, [ebx + EXT2_SB_STRUC.blocks_count] |
sub eax, [ebx + EXT2_SB_STRUC.first_data_block] |
dec eax |
xor edx, edx |
div [ebx + EXT2_SB_STRUC.blocks_per_group] |
inc eax |
mov [ext2_data.groups_count], eax |
mov ecx, [ebx+24] |
inc ecx |
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb |
mov eax, 1 |
shl eax, cl |
mov [ext2_data.count_block_in_block], eax |
shl eax, 7 |
mov [ext2_data.count_pointer_in_block], eax |
mov edx, eax ; потом еще квадрат найдем |
shl eax, 2 |
mov [ext2_data.block_size], eax |
push eax eax ; 2 kernel_alloc |
mov eax, edx |
mul edx |
mov [ext2_data.count_pointer_in_block_square], eax |
call kernel_alloc |
mov [ext2_data.ext2_save_block], eax ; and for temp block |
call kernel_alloc |
mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc |
movzx ebp, word [ebx+88] |
mov ecx, [ebx+32] |
mov edx, [ebx+40] |
mov [ext2_data.inode_size], ebp |
mov [ext2_data.blocks_per_group], ecx |
mov [ext2_data.inodes_per_group], edx |
push ebp ebp ebp ;3 kernel_alloc |
call kernel_alloc |
mov [ext2_data.ext2_save_inode], eax |
call kernel_alloc |
mov [ext2_data.ext2_temp_inode], eax |
call kernel_alloc |
mov [ext2_data.root_inode], eax |
mov ebx, eax |
mov eax, EXT2_ROOT_INO |
call ext2_get_inode ; read root inode |
jmp return_from_part_set |
;================================================================== |
;in: eax = i_block |
; ebx = pointer to return memory |
ext2_get_block: |
push eax ebx ecx |
mov ecx, [ext2_data.log_block_size] |
shl eax, cl |
add eax, [PARTITION_START] |
mov ecx, [ext2_data.count_block_in_block] |
@@: |
call hd_read |
inc eax |
add ebx, 512 |
loop @B |
pop ecx ebx eax |
ret |
;=================================================================== |
; in: ecx = номер блока в inode (0..) |
; ebp = адрес inode |
; out: ecx = адрес очередного блока |
ext2_get_inode_block: |
cmp ecx, 12 ; 0..11 - direct block address |
jb .get_direct_block |
sub ecx, 12 |
cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect block |
jb .get_indirect_block |
sub ecx, [ext2_data.count_pointer_in_block] |
cmp ecx, [ext2_data.count_pointer_in_block_square] |
jb .get_double_indirect_block |
sub ecx, [ext2_data.count_pointer_in_block_square] |
;.get_triple_indirect_block: |
push eax edx ebx |
mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4] |
mov ebx, [ext2_data.ext2_temp_block] |
call ext2_get_block |
xor edx, edx |
mov eax, ecx |
div [ext2_data.count_pointer_in_block_square] |
;eax - номер в полученном блоке edx - номер дальше |
mov eax, [ebx + eax*4] |
call ext2_get_block |
mov eax, edx |
jmp @F |
.get_double_indirect_block: |
push eax edx ebx |
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] |
mov ebx, [ext2_data.ext2_temp_block] |
call ext2_get_block |
mov eax, ecx |
@@: |
xor edx, edx |
div [ext2_data.count_pointer_in_block] |
mov eax, [ebx + eax*4] |
call ext2_get_block |
mov ecx, [ebx + edx*4] |
pop ebx edx eax |
ret |
.get_indirect_block: |
push eax ebx |
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] |
mov ebx, [ext2_data.ext2_temp_block] |
call ext2_get_block |
mov ecx, [ebx + ecx*4] |
pop ebx eax |
ret |
.get_direct_block: |
mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4] |
ret |
;=================================================================== |
;get content inode by num |
;in: eax = inode_num |
; ebx = address of inode content |
ext2_get_inode: |
pushad |
mov edi, ebx ;сохраним адрес inode |
dec eax |
xor edx, edx |
div [ext2_data.inodes_per_group] |
push edx ;locale num in group |
mov edx, 32 |
mul edx ; address block_group in global_desc_table |
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы |
; найдем блок в котором он находится |
div [ext2_data.block_size] |
mov ecx, [ext2_data.sb] |
add eax, [ecx + EXT2_SB_STRUC.first_data_block] |
inc eax |
mov ebx, [ext2_data.ext2_temp_block] |
call ext2_get_block |
add ebx, edx ; локальный номер в блоке |
mov eax, [ebx+8] ; номер блока - в терминах ext2 |
mov ecx, [ext2_data.log_block_size] |
shl eax, cl |
add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512) |
;eax - указывает на таблицу inode-ов на hdd |
mov esi, eax ;сохраним его пока в esi |
; прибавим локальный адрес inode-а |
pop eax ; index |
mov ecx, [ext2_data.inode_size] |
mul ecx ; (index * inode_size) |
mov ebp, 512 |
div ebp ;поделим на размер блока |
add eax, esi ;нашли адрес блока для чтения |
mov ebx, [ext2_data.ext2_temp_block] |
call hd_read |
mov esi, edx ;добавим "остаток" |
add esi, ebx ;к адресу |
; mov ecx, [ext2_data.inode_size] |
rep movsb ;копируем inode |
popad |
ret |
;---------------------------------------------------------------- |
; in: esi -> children |
; ebx -> pointer to dir block |
; out: esi -> name without parent or not_changed |
; ebx -> dir_rec of inode children or trash |
ext2_test_block_by_name: |
push eax ecx edx edi |
mov edx, ebx |
add edx, [ext2_data.block_size] ;запомним конец блока |
.start_rec: |
cmp [ebx + EXT2_DIR_STRUC.inode], 0 |
jz .next_rec |
push esi |
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] |
mov edi, EXT2_filename |
lea esi, [ebx + EXT2_DIR_STRUC.name] |
call utf8toansi_str |
mov ecx, edi |
sub ecx, EXT2_filename ;кол-во байт в получившейся строке |
mov edi, EXT2_filename |
mov esi, [esp] |
@@: |
jecxz .test_find |
dec ecx |
lodsb |
call char_toupper |
mov ah, [edi] |
inc edi |
xchg al, ah |
call char_toupper |
cmp al, ah |
je @B |
@@: ;не подошло |
pop esi |
.next_rec: |
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] |
add ebx, eax ;к след. записи |
cmp ebx, edx ;проверим конец ли |
jb .start_rec |
jmp .ret |
.test_find: |
cmp byte [esi], 0 |
je .find ;нашли конец |
cmp byte [esi], '/' |
jne @B |
inc esi |
.find: |
pop eax ;удаляем из стека сохраненое значение |
.ret: |
pop edi edx ecx eax |
ret |
;---------------------------------------------------------------- |
; |
; ext2_HdReadFolder - read disk folder |
; |
; esi points to filename |
; ebx pointer to structure 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
ext2_HdReadFolder: |
cmp byte [esi], 0 |
jz .doit |
push ecx ebx |
call ext2_find_lfn |
jnc .doit2 |
pop ebx |
.not_found: |
pop ecx |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.doit: |
mov ebp, [ext2_data.root_inode] |
push ecx |
jmp @F |
.doit2: |
pop ebx |
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
jz .not_found |
@@: |
xor eax, eax |
mov edi, edx |
mov ecx, 32/4 |
rep stosd ; fill header zero |
pop edi ; edi = число блоков для чтения |
push edx ebx |
;--------------------------------------------- final step |
and [EXT2_read_in_folder], 0 |
and [EXT2_files_in_folder], 0 |
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] |
mov [EXT2_counter_blocks], eax |
add edx, 32 ; (header pointer in stack) edx = current mem for return |
xor esi, esi ; esi = номер блока по порядку |
.new_block_folder: ;reserved label |
mov ecx, esi ; получим номер блока |
call ext2_get_inode_block |
mov eax, ecx |
mov ebx, [ext2_data.ext2_save_block] |
call ext2_get_block ; и считываем блок с hdd |
mov eax, ebx ; eax = current dir record |
add ebx, [ext2_data.block_size] |
mov [EXT2_end_block], ebx ; запомним конец очередного блока |
pop ecx |
mov ecx, [ecx] ; ecx = first wanted (flags ommited) |
.find_wanted_start: |
jecxz .find_wanted_end |
.find_wanted_cycle: |
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
jz @F |
inc [EXT2_files_in_folder] |
dec ecx |
@@: |
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len] |
cmp ebx, 12 ; минимальная длина записи |
jb .end_error |
test ebx, 0x3 ; длина записи должна делиться на 4 |
jnz .end_error |
add eax, ebx ; к следующей записи |
cmp eax, [EXT2_end_block] ; проверяем "конец" |
jb .find_wanted_start |
push .find_wanted_start |
.end_block: ;вылетили из цикла |
mov ebx, [ext2_data.count_block_in_block] |
sub [EXT2_counter_blocks], ebx |
jbe .end_dir |
inc esi ;получаем новый блок |
push ecx |
mov ecx, esi |
call ext2_get_inode_block |
mov eax, ecx |
mov ebx, [ext2_data.ext2_save_block] |
call ext2_get_block |
pop ecx |
mov eax, ebx |
add ebx, [ext2_data.block_size] |
mov [EXT2_end_block], ebx |
ret ; опять в цикл |
.wanted_end: |
loop .find_wanted_cycle ; ecx = -1 |
.find_wanted_end: |
mov ecx, edi |
.wanted_start: ; ищем first_wanted+count |
jecxz .wanted_end |
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
jz .empty_rec |
inc [EXT2_files_in_folder] |
inc [EXT2_read_in_folder] |
mov edi, edx |
push eax ecx |
xor eax, eax |
mov ecx, 40 / 4 |
rep stosd |
pop ecx eax |
push eax esi edx ;получим inode |
mov eax, [eax + EXT2_DIR_STRUC.inode] |
mov ebx, [ext2_data.ext2_temp_inode] |
call ext2_get_inode |
lea edi, [edx + 8] |
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат |
xor edx, edx |
add eax, 3054539008 ;(369 * 365 + 89) * 24 * 3600 |
adc edx, 2 |
call ntfs_datetime_to_bdfe.sec |
mov eax, [ebx + EXT2_INODE_STRUC.i_atime] |
xor edx, edx |
add eax, 3054539008 |
adc edx, 2 |
call ntfs_datetime_to_bdfe.sec |
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] |
xor edx, edx |
add eax, 3054539008 |
adc edx, 2 |
call ntfs_datetime_to_bdfe.sec |
pop edx ; пока достаем только буфер |
test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер |
jnz @F ; не возвращаем |
mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size |
stosd |
mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size |
stosd |
xor dword [edx], FS_FT_DIR |
@@: |
xor dword [edx], FS_FT_DIR |
pop esi eax |
or dword [edx+4], FS_FT_ASCII ; symbol type in name |
;теперь скопируем имя, сконвертировав из UTF-8 в CP866 |
push eax ecx esi |
movzx ecx, [eax + EXT2_DIR_STRUC.name_len] |
lea edi, [edx + 40] |
lea esi, [eax + EXT2_DIR_STRUC.name] |
call utf8toansi_str |
pop esi ecx eax |
and byte [edi], 0 |
cmp byte [edx + 40], '.' |
jne @F |
or dword [edx], FS_FT_HIDDEN |
@@: |
add edx, 40 + 264 ; go to next record |
dec ecx ; если запись пустая ecx не надо уменьшать |
.empty_rec: |
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len] |
cmp ebx, 12 ; минимальная длина записи |
jb .end_error |
test ebx, 0x3 ; длина записи должна делиться на 4 |
jnz .end_error |
add eax, ebx |
cmp eax, [EXT2_end_block] |
jb .wanted_start |
push .wanted_start ; дошли до конца очередного блока |
jmp .end_block |
.end_dir: |
pop eax ; мусор (адрес возврата в цикл) |
.end_error: |
pop edx |
mov ebx, [EXT2_read_in_folder] |
mov ecx, [EXT2_files_in_folder] |
mov dword [edx], 1 ;version |
xor eax, eax |
mov [edx+4], ebx |
mov [edx+8], ecx |
lea edi, [edx + 12] |
mov ecx, 20 / 4 |
rep stosd |
ret |
;====================== end ext2_HdReadFolder |
utf8toansi_str: |
; convert UTF-8 string to ASCII-string (codepage 866) |
; in: ecx=length source, esi->source, edi->buffer |
; destroys: eax,esi,edi |
jecxz .ret |
.start: |
lodsw |
cmp al, 0x80 |
jb .ascii |
xchg al, ah ; big-endian |
cmp ax, 0xd080 |
jz .yo1 |
cmp ax, 0xd191 |
jz .yo2 |
cmp ax, 0xd090 |
jb .unk |
cmp ax, 0xd180 |
jb .rus1 |
cmp ax, 0xd190 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 0xf0 ; Ё capital |
jmp .doit |
.yo2: |
mov al, 0xf1 ; ё small |
jmp .doit |
.rus1: |
sub ax, 0xd090 - 0x80 |
jmp .doit |
.rus2: |
sub ax, 0xd18f - 0xEF |
.doit: |
stosb |
sub ecx, 2 |
ja .start |
ret |
.ascii: |
stosb |
dec esi |
dec ecx |
jnz .start |
.ret: |
ret |
;---------------------------------------------------------------- |
; |
; ext2_HdRead - read hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
ext2_HdRead: |
cmp byte [esi], 0 |
jnz @F |
.this_is_nofile: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
@@: |
push ecx ebx |
call ext2_find_lfn |
pop ebx ecx |
jnc .doit |
;.not_found: |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.doit: |
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG |
jz .this_is_nofile |
;-----------------------------------------------------------------------------final step |
mov edi, edx ; edi = pointer to return mem |
mov esi, ebx ; esi = pointer to first_wanted |
;///// сравним хватит ли нам файла или нет |
mov ebx, [esi+4] |
mov eax, [esi] ; ebx : eax - стартовый номер байта |
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
ja .size_great |
jb .size_less |
cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
ja .size_great |
.size_less: |
xor ebx, ebx |
mov eax, ERROR_END_OF_FILE |
ret |
.size_great: |
add eax, ecx ;add to first_wanted кол-во байт для чтения |
adc ebx, 0 |
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
ja .size_great_great |
jb .size_great_less |
cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
jae .size_great_great ; а если равно, то не важно куда |
.size_great_less: |
or [EXT2_files_in_folder], 1 ;читаем по границе размера |
mov ecx, [ebp + EXT2_INODE_STRUC.i_size] |
sub ecx, [esi] ;(размер - старт) |
jmp @F |
.size_great_great: |
and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили |
@@: |
push ecx ;save for return |
test esi, esi |
jz .zero_start |
;пока делаем п..ц криво =) |
mov edx, [esi+4] |
mov eax, [esi] |
div [ext2_data.block_size] |
mov [EXT2_counter_blocks], eax ;номер блока запоминаем |
push ecx |
mov ecx, eax |
call ext2_get_inode_block |
mov ebx, [ext2_data.ext2_save_block] |
mov eax, ecx |
call ext2_get_block |
pop ecx |
add ebx, edx |
neg edx |
add edx, [ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока |
cmp ecx, edx |
jbe .only_one_block |
mov eax, ecx |
sub eax, edx |
mov ecx, edx |
mov esi, ebx |
rep movsb ;кусок 1-го блока |
jmp @F |
.zero_start: |
mov eax, ecx |
;теперь в eax кол-во оставшихся байт для чтения |
@@: |
mov ebx, edi ;чтение блока прям в ->ebx |
xor edx, edx |
div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx |
mov edi, eax ;кол-во целых блоков в edi |
@@: |
test edi, edi |
jz .finish_block |
inc [EXT2_counter_blocks] |
mov ecx, [EXT2_counter_blocks] |
call ext2_get_inode_block |
mov eax, ecx ;а ebx уже забит нужным значением |
call ext2_get_block |
add ebx, [ext2_data.block_size] |
dec edi |
jmp @B |
.finish_block: ;в edx - кол-во байт в последнем блоке |
test edx, edx |
jz .end_read |
mov ecx, [EXT2_counter_blocks] |
inc ecx |
call ext2_get_inode_block |
mov edi, ebx |
mov eax, ecx |
mov ebx, [ext2_data.ext2_save_block] |
call ext2_get_block |
mov ecx, edx |
.only_one_block: |
mov esi, ebx |
rep movsb ;кусок last блока |
.end_read: |
pop ebx |
cmp [EXT2_files_in_folder], 0 |
jz @F |
mov eax, ERROR_END_OF_FILE |
ret |
@@: |
xor eax, eax |
ret |
;======================== |
;in : esi -> name not save: eax ebx ecx |
;out: ebp -> inode cf=0 |
; ebp -> trash cf=1 |
ext2_find_lfn: |
mov ebp, [ext2_data.root_inode] |
.next_folder: |
or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode |
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков |
add eax, [ext2_data.count_block_in_block] |
mov [EXT2_end_block], eax |
.next_block_folder: |
mov eax, [ext2_data.count_block_in_block] |
sub [EXT2_end_block], eax |
jz .not_found |
inc [EXT2_counter_blocks] |
mov ecx, [EXT2_counter_blocks] |
call ext2_get_inode_block |
mov eax, ecx |
mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record |
call ext2_get_block |
mov eax, esi |
call ext2_test_block_by_name |
cmp eax, esi ;нашли имя? |
jz .next_block_folder |
cmp byte [esi], 0 |
jz .get_inode_ret |
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR |
jne .not_found ;нашли, но это не папка |
mov eax, [ebx + EXT2_DIR_STRUC.inode] |
mov ebx, [ext2_data.ext2_save_inode] ;все же папка. |
call ext2_get_inode |
mov ebp, ebx |
jmp .next_folder |
.not_found: |
stc |
ret |
.get_inode_ret: |
mov [EXT2_end_block], ebx ; сохраняем указатеть на dir_rec |
mov eax, [ebx + EXT2_DIR_STRUC.inode] |
mov ebx, [ext2_data.ext2_save_inode] |
call ext2_get_inode |
mov ebp, ebx |
clc |
ret |
;======================== |
ext2_HdGetFileInfo: |
cmp byte [esi], 0 |
jz .doit |
call ext2_find_lfn |
jnc .doit2 |
;.not_found: |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.doit: |
mov ebp, [ext2_data.root_inode] |
mov ebx, .doit ;неважно что лишь бы этому адресу не '.' |
jmp @F |
.doit2: |
mov ebx, [EXT2_end_block] |
add ebx, EXT2_DIR_STRUC.name |
@@: |
xor eax, eax |
mov edi, edx |
mov ecx, 40/4 |
rep stosd ; fill zero |
cmp byte [ebx], '.' |
jnz @F |
or dword [edx], FS_FT_HIDDEN |
@@: |
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR |
jnz @F |
mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size |
mov ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ;high size |
mov dword [edx+32], eax |
mov dword [edx+36], ebx |
xor dword [edx], FS_FT_DIR |
@@: |
xor dword [edx], FS_FT_DIR |
lea edi, [edx + 8] |
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] |
xor edx, edx |
add eax, 3054539008 |
adc edx, 2 |
call ntfs_datetime_to_bdfe.sec |
mov eax, [ebx + EXT2_INODE_STRUC.i_atime] |
xor edx, edx |
add eax, 3054539008 |
adc edx, 2 |
call ntfs_datetime_to_bdfe.sec |
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] |
xor edx, edx |
add eax, 3054539008 |
adc edx, 2 |
call ntfs_datetime_to_bdfe.sec |
xor eax, eax |
ret |
ext2_HdRewrite: |
ext2_HdWrite: |
ext2_HdSetFileEnd: |
ext2_HdSetFileInfo: |
ext2_HdDelete: |
ext2_HdCreateFolder: |
xor ebx, ebx |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
;---------------------------------------------------------------- |
; |
; ext2_HdCreateFolder - create new folder |
; |
; esi points to filename |
; |
; ret eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
cmp byte [esi], 0 |
jz .not_found |
cmp byte [esi], '/' |
jz .not_found |
mov ebx, esi ; save source pointer |
xor edi, edi ; slah pointer |
@@: |
lodsb |
cmp al, 0 |
jz .zero |
cmp al, '/' |
jz .slash |
jmp @B |
.slash: |
lodsb |
cmp al, 0 |
jz .zero ; уберем слеш из имени |
cmp al, '/' |
jz .not_found |
mov edi, esi ; edi -> next symbol after '/' |
dec edi |
jmp @B |
.zero: |
dec esi |
test edi, edi |
jz .doit |
;слеш был |
mov eax, esi |
sub eax, edi |
mov [EXT2_name_len], eax |
mov ecx, edi |
sub ecx, ebx |
dec ecx ;выкинули '/' из имени ролителя |
mov esi, ebx |
mov edi, EXT2_parent_name |
rep movsb |
; esi - pointer to last slash |
mov edx, esi |
mov esi, EXT2_parent_name |
call ext2_find_lfn |
jnc .doit2 |
.not_found: |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.doit: |
mov ebp, [ext2_data.root_inode] |
mov edx, ebx ; имя создаваемой папки |
sub esi, ebx |
mov [EXT2_name_len], esi |
.doit2: |
;ebp -> parent_inode ebx->name_new_folder [EXT2_name_len]=length of name |
; стратегия выбора группы для нового inode: (так делает линукс) |
; 1) Ищем группу в которой меньше всего папок и в есть свободное место |
; 2) Если такая группа не нашлась, то берем группу в которой больше свободного места |
call ext2_balloc |
jmp ext2_HdDelete |
push ebx |
push ebp |
mov ecx, [ext2_data.sb] |
cmp [ecx + EXT2_SB_STRUC.free_inodes_count], 0 ; есть ли место для inode |
jz .no_space |
mov eax, [ecx + EXT2_SB_STRUC.free_block_count] |
sub eax, [ecx + EXT2_SB_STRUC.r_block_count] |
cmp eax, 2 ; и как минимум на 2 блока |
jb .no_space |
mov ecx, [ext2_data.groups_count] |
mov esi, [ext2_data.global_desc_table] |
mov edi, -1 ;указатель на лучшую группу |
mov edx, 0 |
.find_group_dir: |
jecxz .end_find_group_dir |
movzx eax, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count] |
cmp eax, edx |
jbe @F |
cmp [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count], 0 |
jz @F |
mov edi, esi |
movzx edx, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count] |
@@: |
dec ecx |
add esi, 32 ;размер структуры |
jmp .find_group_dir |
.end_find_group_dir: |
cmp edx, 0 |
jz .no_space |
;нашли группу, получим битовую карту inode-ов (найдем locale number) |
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap] |
mov ebx, [ext2_data.ext2_save_block] |
call ext2_get_block |
;теперь цикл по всем битам |
mov esi, ebx |
mov ecx, [ext2_data.inodes_per_group] |
shr ecx, 5 ;делим на 32 |
mov ebp, ecx ; всего сохраним в ebp |
or eax, -1 ; ищем первый свободный inode (!= -1) |
repne scasd |
jnz .test_last_dword ;нашли или нет |
mov eax, [esi-4] |
sub ebp, ecx |
dec ebp |
shl ebp, 5 ; глобальный номер локального номера |
mov ecx, 32 |
@@: |
test eax, 1 |
jz @F |
shr eax, 1 |
loop @B |
@@: |
mov eax, 32 |
sub eax, ecx |
add ebp, eax ; locale num of inode |
mov eax, [esi-4] |
;устанавливаем в eax крайний справа нулевой бит в 1 |
mov ecx, eax |
inc ecx |
or eax, ecx ; x | (x+1) |
mov [esi-4], eax |
mov ebx, [ext2_data.ext2_save_block] |
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap] |
call ext2_set_block |
;считаем таблицу inode |
sub edi, [ext2_data.global_desc_table] |
shr edi, 5 |
mov eax, edi |
mul [ext2_data.inodes_per_group] |
add eax, ebp |
inc eax ; теперь в eax (ebp) номер inode-а |
mov ebp, eax |
;call ext2_get_inode_address |
mov ebx, [ext2_data.ext2_save_block] |
call hd_read |
add edx, ebx ; в edx адрес нужного inode |
;забьем 0 для начала |
mov edi, edx |
mov ecx, [ext2_data.inode_size] |
shr ecx, 2 |
xor eax, eax |
rep stosd |
mov edi, edx |
mov eax, EXT2_S_IFDIR or EXT2_777_MODE |
stosd ; i_mode |
xor eax, eax |
stosd ; i_uid |
mov eax, [ext2_data.block_size] |
stosd ; i_size |
xor eax, eax |
stosd ; i_atime |
stosd ; i_ctime |
stosd ; i_mtime |
stosd ; i_dtime |
stosd ; i_gid |
inc eax |
stosd ; i_links_count |
mov eax, [ext2_data.count_block_in_block] |
stosd ; i_blocks |
.test_last_dword: |
xor ebx, ebx |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
.no_space: |
or ebx, -1 |
mov eax, ERROR_DISK_FULL |
ret |
;выделяет новый блок, если это можно |
;иначе возвращает eax=0 |
ext2_balloc: |
mov ecx, [ext2_data.sb] |
mov eax, [ecx + EXT2_SB_STRUC.free_block_count] |
sub eax, [ecx + EXT2_SB_STRUC.r_block_count] |
jbe .no_space |
mov ecx, [ext2_data.groups_count] |
mov edi, [ext2_data.global_desc_table] |
;mov esi, -1 ;указатель на лучшую группу |
mov edx, 0 |
.find_group: |
jecxz .end_find_group |
movzx eax, [edi + EXT2_BLOCK_GROUP_DESC.free_blocks_count] |
cmp eax, edx |
jbe @F |
mov esi, edi |
mov edx, eax |
@@: |
dec ecx |
add edi, 32 ;размер структуры |
jmp .find_group |
.end_find_group: |
cmp edx, 0 |
jz .no_space |
;нашли группу, получим битовую карту block-ов |
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.block_bitmap] |
mov ebx, [ext2_data.ext2_save_block] |
call ext2_get_block |
;теперь цикл по всем битам |
mov edi, ebx |
mov ecx, [ext2_data.blocks_per_group] |
shr ecx, 5 ;делим на 32 |
mov ebp, ecx ;всего сохраним в ebp |
or eax, -1 ;ищем первый свободный inode (!= -1) |
repe scasd |
jz .test_last_dword ;нашли или нет |
mov eax, [edi-4] |
sub ebp, ecx |
dec ebp |
shl ebp, 5 ; ebp = 32*(номер div 32). Теперь найдем (номер mod 32) |
mov ecx, 32 |
@@: |
test eax, 1 |
jz @F |
shr eax, 1 |
loop @B |
@@: |
mov eax, 32 |
sub eax, ecx |
add ebp, eax ; ebp = номер блока в группе |
mov eax, [edi-4] |
mov ecx, eax |
inc ecx |
or eax, ecx ; x | (x+1) - устанавливает в 1 крайний справа нулевой бит (block used) |
mov [edi-4], eax |
mov ebx, [ext2_data.ext2_save_block] |
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.inode_bitmap] |
; call ext2_set_block ; и пишем на hdd новую битовую маску |
;============== тут получаем номер блока |
mov eax, [ext2_data.blocks_per_group] |
sub esi, [ext2_data.global_desc_table] |
shr esi, 5 ;esi - номер группы |
mul esi |
add ebp, eax ;(номер_группы) * (blocks_per_group) + локальный номер в группе |
mov eax, [ext2_data.sb] |
add ebp, [eax + EXT2_SB_STRUC.first_data_block] |
;теперь поправим глобальную дескрипторную таблицу и суперблок |
mov ebx, [ext2_data.sb] |
dec [ebx + EXT2_SB_STRUC.free_block_count] |
mov eax, 2 |
add eax, [PARTITION_START] |
call hd_write |
mov eax, [ebx + EXT2_SB_STRUC.first_data_block] |
inc eax |
dec [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count];edi все еще указывает на группу в которой мы выделил блок |
call ext2_set_block |
mov eax, ebx |
ret |
.test_last_dword: |
lodsd |
mov ecx, [ext2_data.blocks_per_group] |
and ecx, not (32-1) ;обнуляем все кроме последних 5 бит |
mov edx, ecx |
mov ebx, 1 |
@@: |
jecxz .no_space |
mov edx, ebx |
or edx, eax ; тестируем очередной бит |
shl ebx, 1 |
jmp @B |
@@: |
sub edx, ecx |
dec edx ;номер в последнем блоке |
.no_space: |
xor eax, eax |
ret |
;in: eax = i_block |
; ebx = pointer to memory |
ext2_set_block: |
push eax ebx ecx |
mov ecx, [ext2_data.log_block_size] |
shl eax, cl |
add eax, [PARTITION_START] |
mov ecx, [ext2_data.count_block_in_block] |
@@: |
call hd_write |
inc eax |
add ebx, 512 |
loop @B |
pop ecx ebx eax |
ret |
/kernel/branches/net/fs/fat32.inc |
---|
60,6 → 60,7 |
ERROR_DISK_FULL = 8 |
ERROR_FAT_TABLE = 9 |
ERROR_ACCESS_DENIED = 10 |
ERROR_DEVICE = 11 |
PUSHAD_EAX equ [esp+28] |
PUSHAD_ECX equ [esp+24] |
93,10 → 94,13 |
uglobal |
align 4 |
fat_cache: times 512 db 0 |
fat_cache: |
times 512 db 0 |
Sector512: ; label for dev_hdcd.inc |
buffer: times 512 db 0 |
fsinfo_buffer: times 512 db 0 |
buffer: |
times 512 db 0 |
fsinfo_buffer: |
times 512 db 0 |
endg |
uglobal |
1049,6 → 1053,8 |
jz @f |
cmp [fs_type], 1 |
jz ntfs_HdRead |
cmp [fs_type], 2 |
jz ext2_HdRead |
or ebx, -1 |
mov eax, ERROR_UNKNOWN_FS |
ret |
1200,6 → 1206,8 |
fs_HdReadFolder: |
cmp [fs_type], 1 |
jz ntfs_HdReadFolder |
cmp [fs_type], 2 |
jz ext2_HdReadFolder |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
1586,6 → 1594,8 |
.common: |
cmp [fs_type], 1 |
jz ntfs_HdRewrite |
cmp [fs_type], 2 |
jz ext2_HdRewrite |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
2120,6 → 2130,8 |
fs_HdWrite: |
cmp [fs_type], 1 |
jz ntfs_HdWrite |
cmp [fs_type], 2 |
jz ext2_HdWrite |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
2336,7 → 2348,8 |
sub dword [esp], 0x200 |
jae @f |
and dword [esp], 0 |
@@: jmp .write_loop |
@@: |
jmp .write_loop |
hd_extend_file.zero_size: |
xor eax, eax |
2445,7 → 2458,8 |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: stc |
@@: |
stc |
ret |
;---------------------------------------------------------------- |
2463,6 → 2477,8 |
fs_HdSetFileEnd: |
cmp [fs_type], 1 |
jz ntfs_HdSetFileEnd |
cmp [fs_type], 2 |
jz ext2_HdSetFileEnd |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
2695,6 → 2711,8 |
fs_HdGetFileInfo: |
cmp [fs_type], 1 |
jz ntfs_HdGetFileInfo |
cmp [fs_type], 2 |
jz ext2_HdGetFileInfo |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
2723,6 → 2741,8 |
fs_HdSetFileInfo: |
cmp [fs_type], 1 |
jz ntfs_HdSetFileInfo |
cmp [fs_type], 2 |
jz ext2_HdSetFileInfo |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
2773,6 → 2793,8 |
fs_HdDelete: |
cmp [fs_type], 1 |
jz ntfs_HdDelete |
cmp [fs_type], 2 |
jz ext2_HdDelete |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
/kernel/branches/net/fs/fs.inc |
---|
21,12 → 21,14 |
iglobal |
dir0: db 'HARDDISK ' |
dir0: |
db 'HARDDISK ' |
db 'RAMDISK ' |
db 'FLOPPYDISK ' |
db 0 |
dir1: db 'FIRST ' |
dir1: |
db 'FIRST ' |
db 'SECOND ' |
db 'THIRD ' |
db 'FOURTH ' |
34,7 → 36,8 |
not_select_IDE db 0 |
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10 |
hd_address_table: |
dd 0x1f0,0x00,0x1f0,0x10 |
dd 0x170,0x00,0x170,0x10 |
endg |
388,7 → 391,7 |
.s: |
sub eax,ebx |
.f: |
add eax,[fat32part] |
add eax, [known_part]; add eax,[fat32part] |
dec eax |
xor edx,edx |
imul eax,100 |
793,5 → 796,6 |
stc |
jmp i4 |
partition_string: dd 0 |
partition_string: |
dd 0 |
db 32 |
/kernel/branches/net/fs/fs_lfn.inc |
---|
8,8 → 8,8 |
$Revision$ |
image_of_eax EQU esp+36 |
image_of_ebx EQU esp+24 |
image_of_eax EQU esp+32 |
image_of_ebx EQU esp+20 |
; System function 70 - files with long names (LFN) |
; diamond, 2006 |
85,13 → 85,13 |
fs_additional_handlers: |
dd biosdisk_handler, biosdisk_enum_root |
dd dyndisk_handler, dyndisk_enum_root |
; add new handlers here |
dd 0 |
endg |
file_system_lfn: |
; in: eax->fileinfo block |
; in: ebx->fileinfo block |
; operation codes: |
; 0 : read file |
; 1 : read folder |
105,7 → 105,6 |
; 9 : create directory |
; parse file name |
xchg ebx, eax |
lea esi, [ebx+20] |
lodsb |
test al, al |
169,8 → 168,8 |
cmp dword [ebx], 1 |
jnz .access_denied |
xor eax, eax |
mov ebp, [ebx+12] |
mov edx, [ebx+16] |
mov ebp, [ebx+12] ;количество блоков для считывания |
mov edx, [ebx+16] ;куда записывать рузельтат |
; add edx, std_application_base_address |
push dword [ebx+4] ; first block |
mov ebx, [ebx+8] ; flags |
385,7 → 384,8 |
.notfounda: |
cmp edi, esp |
jnz .notfound |
add esp, 8 |
call dword [edi+4] |
add esp, 16 |
jmp .notfound |
.found1: |
537,7 → 537,7 |
mov dword [image_of_eax], 5 ; not found |
ret |
@@: |
mov [fat32part], ecx |
mov [known_part], ecx ; mov [fat32part], ecx |
push ebx esi |
call choice_necessity_partition_1 |
pop esi ebx |
852,6 → 852,8 |
jmp file_system_lfn.maindir_noesi |
@@: |
push ecx |
push ecx |
push biosdisk_cleanup |
push fs_OnBd |
mov edi, esp |
jmp file_system_lfn.found2 |
860,10 → 862,11 |
cmp eax, [BiosDiskPartitions+ecx*4] |
inc eax |
cmc |
biosdisk_cleanup: |
ret |
fs_OnBd: |
pop edx edx |
pop edx edx edx edx |
; edx = disk number, ecx = partition number |
; esi+ebp = name |
call reserve_hd1 |
904,7 → 907,7 |
xor eax, eax |
ret |
.big: |
push ecx |
push ecx edx |
push -'0' |
mov ecx, 10 |
@@: |
919,7 → 922,7 |
add al, '0' |
stosb |
jnz @b |
pop ecx |
pop edx ecx |
pop eax |
inc eax |
ret |
1015,9 → 1018,11 |
stosb |
mov ecx,edx |
rep movsb ;copy string |
.ret: ret |
.ret: |
ret |
.error: add esp,8 |
.error: |
add esp, 8 |
or dword [esp+32],-1 ;error not found zerro at string ->[eax+APPDATA.cur_dir] |
ret |
.set: |
/kernel/branches/net/fs/iso9660.inc |
---|
5,7 → 5,7 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision:1322 $ |
$Revision$ |
uglobal |
54,12 → 54,14 |
je .reserve_ok_2 |
sti |
call change_task |
jmp .IDE_Channel_1 |
jmp .IDE_Channel_2 |
.reserve_ok_1: |
mov [IDE_Channel_1],1 |
sti |
ret |
.reserve_ok_2: |
mov [IDE_Channel_2],1 |
sti |
ret |
free_cd_channel: |
67,9 → 69,11 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
mov [IDE_Channel_1],0 |
sti |
ret |
.IDE_Channel_2: |
mov [IDE_Channel_2],0 |
sti |
ret |
uglobal |
/kernel/branches/net/fs/ntfs.inc |
---|
95,8 → 95,8 |
ntfs_setup: ; CODE XREF: part_set.inc |
; By given bootsector, initialize some NTFS variables |
call ntfs_test_bootsec |
jc problem_fat_dec_count |
; call ntfs_test_bootsec ; checking boot sector was already |
; jc problem_fat_dec_count |
movzx eax, byte [ebx+13] |
mov [ntfs_data.sectors_per_cluster], eax |
mov eax, [ebx+0x28] |
942,6 → 942,18 |
pop edi ecx eax |
ret |
unichar_toupper: |
push eax |
call uni2ansi_char |
cmp al, '_' |
jz .unk |
add esp, 4 |
call char_toupper |
jmp ansi2uni_char |
.unk: |
pop eax |
ret |
ntfs_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
1030,8 → 1042,7 |
push edi |
@@: |
lodsw |
call uni2ansi_char |
call char_toupper |
call unichar_toupper |
push eax |
mov al, [edi] |
inc edi |
1038,7 → 1049,8 |
cmp al, '/' |
jz .slash |
call char_toupper |
cmp al, [esp] |
call ansi2uni_char |
cmp ax, [esp] |
pop eax |
loopz @b |
jz .found |
1641,6 → 1653,7 |
xchg eax, [esp] |
div [_10000000] |
pop edx |
.sec: |
; edx:eax = number of seconds since January 1, 1601 |
push eax |
mov eax, edx |
1813,3 → 1826,4 |
pop edi esi |
xor eax, eax |
ret |
/kernel/branches/net/fs/part_set.inc |
---|
9,6 → 9,7 |
;************************************************************* |
;* 13.02.2010 Find all partition and check supported FS |
;* 12.07.2007 Check all 4 entry of MBR and EMBR |
;* 29.04.2006 Elimination of hangup after the |
;* expiration hd_wait_timeout - Mario79 |
26,7 → 27,7 |
;****************************************************** |
PARTITION_START dd 0x3f |
PARTITION_END dd 0 |
fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32 |
fs_type db 0 ; 1=NTFS, 2=EXT2/3, 16=FAT16, 32=FAT32 |
align 4 |
fs_dependent_data_start: |
54,7 → 55,8 |
fs_dependent_data_end: |
file_system_data_size = $ - PARTITION_START |
if file_system_data_size > 96 |
ERROR: sizeof(file system data) too big! |
ERROR: |
sizeof(file system data) too big! |
end if |
virtual at fs_dependent_data_start |
74,10 → 76,36 |
.cur_index_size dd ? |
.cur_index_buf dd ? |
if $ > fs_dependent_data_end |
ERROR: increase sizeof(fs_dependent_data)! |
ERROR: |
increase sizeof(fs_dependent_data)! |
end if |
end virtual |
virtual at fs_dependent_data_start |
; EXT2 data |
ext2_data: |
.log_block_size dd ? |
.block_size dd ? |
.count_block_in_block dd ? |
.blocks_per_group dd ? |
.inodes_per_group dd ? |
.global_desc_table dd ? |
.root_inode dd ? ; pointer to root inode in memory |
.inode_size dd ? |
.count_pointer_in_block dd ? ; block_size / 4 |
.count_pointer_in_block_square dd ? ; (block_size / 4)**2 |
.ext2_save_block dd ? ; ¡«®ª £«®¡ «ìãî 1 ¯à®æ¥¤ãàã |
.ext2_temp_block dd ? ; ¡«®ª ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà |
.ext2_save_inode dd ? ; inode £«®¡ «ìãî ¯à®æ¥¤ãàã |
.ext2_temp_inode dd ? ; inode ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà |
.sb dd ? ; superblock |
.groups_count dd ? |
if $ > fs_dependent_data_end |
ERROR: |
increase sizeof(fs_dependent_data)! |
end if |
end virtual |
;*************************************************************************** |
; End place |
; Mario79 |
105,6 → 133,7 |
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M |
db 0x07 ; NTFS |
db 0x27 ; NTFS, hidden |
db 0x83 ; Linux native file system (ext2fs) |
partition_types_end: |
118,18 → 147,16 |
endg |
; Partition chain used: |
; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4 |
;========================================================== |
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +-- |
; extended --+ extended --+ extended --+ extended --+ |
; 0 0 0 0 |
; 0 0 0 0 |
; Notes: |
; - extended partition need to be in second entry on table |
; - it will skip over removed partitions |
; MBR <--------------------- |
; | | |
; |-> PARTITION1 | |
; |-> EXTENDED PARTITION - ;not need be second partition |
; |-> PARTITION3 |
; |-> PARTITION4 |
set_FAT32_variables: |
mov [problem_partition],0 |
set_PARTITION_variables: |
set_FAT32_variables: ;deprecated |
and [problem_partition], 0 |
call reserve_hd1 |
call reserve_hd_channel |
139,12 → 166,12 |
je problem_hd |
xor ecx,ecx ; partition count |
mov edx,-1 ; flag for partition |
xor eax,eax ; read MBR |
;or edx,-1 ; flag for partition |
xor eax, eax ; address MBR |
xor ebp,ebp ; extended partition start |
new_partition: |
test ebp,ebp ; is there extended partition? |
new_mbr: |
test ebp, ebp ; is there extended partition? (MBR or EMBR) |
jnz extended_already_set ; yes |
xchg ebp,eax ; no. set it now |
157,153 → 184,164 |
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? |
jnz end_partition_chain |
push eax ; push only one time |
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition |
; jz next_partition |
jnz .next_primary_partition |
jnz test_primary_partition_0 |
cmp dword [ebx+0x1be+0xc+16],0 |
jnz next_primary_partition |
jnz test_primary_partition_1 |
cmp dword [ebx+0x1be+0xc+16+16],0 |
jnz next_primary_partition_1 |
jnz test_primary_partition_2 |
cmp dword [ebx+0x1be+0xc+16+16+16],0 |
jnz next_primary_partition_2 |
jmp next_partition |
jnz test_primary_partition_3 |
pop eax |
jmp end_partition_chain |
.next_primary_partition: |
push eax |
test_primary_partition_0: |
mov al,[ebx+0x1be+4] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition ; no. skip over |
jnz test_primary_partition_1; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition ; no |
cmp ecx, [known_part]; is it wanted partition? |
jnz test_primary_partition_1; no |
mov edx, eax ; start sector |
add edx, [ebx+0x1be+8] ; add relative start |
push edx |
add edx, [ebx+0x1be+12] ; add length |
dec edx ; PARTITION_END is inclusive |
mov [PARTITION_END], edx ; note that this can be changed |
pop eax |
;mov edx, eax ; start sector |
add eax, [ebx+0x1be+8] ; add relative start |
;mov [PARTITON_START],edx |
;push edx |
mov edx, [ebx+0x1be+12] ; length |
;add edx, eax ; add length |
;dec edx ; PARTITION_END is inclusive |
;mov [PARTITION_END], edx ; note that this can be changed |
; when file system data will be available |
mov dl, [ebx+0x1be+4] |
mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) |
pop edx |
mov cl, [ebx+0x1be+4] ; fs_type |
;mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) |
;pop edx |
jmp hd_and_partition_ok |
next_primary_partition: |
push eax |
test_primary_partition_1: |
mov al,[ebx+0x1be+4+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition_1 ; no. skip over |
jnz test_primary_partition_2 ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition_1 ; no |
cmp ecx, [known_part]; is it wanted partition? |
jnz test_primary_partition_2 ; no |
mov edx, eax |
add edx, [ebx+0x1be+8+16] |
push edx |
add edx, [ebx+0x1be+12+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16] |
mov [fs_type], dl |
pop edx |
pop eax |
add eax, [ebx+0x1be+8+16] |
mov edx, [ebx+0x1be+12+16] |
mov cl, [ebx+0x1be+4+16] |
jmp hd_and_partition_ok |
next_primary_partition_1: |
push eax |
;mov edx, eax |
;add edx, [ebx+0x1be+8+16] |
;push edx |
;add edx, [ebx+0x1be+12+16] |
;dec edx |
;mov [PARTITION_END], edx |
;mov al, [ebx+0x1be+4+16] |
;mov [fs_type], dl |
;pop edx |
test_primary_partition_2: |
mov al,[ebx+0x1be+4+16+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_primary_partition_2 ; no. skip over |
jnz test_primary_partition_3 ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_primary_partition_2 ; no |
cmp ecx, [known_part]; is it wanted partition? |
jnz test_primary_partition_3 ; no |
mov edx, eax |
add edx, [ebx+0x1be+8+16+16] |
push edx |
add edx, [ebx+0x1be+12+16+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16+16] |
mov [fs_type], dl |
pop edx |
pop eax |
add eax, [ebx+0x1be+8+16+16] |
mov edx, [ebx+0x1be+12+16+16] |
mov cl, [ebx+0x1be+4+16+16] |
jmp hd_and_partition_ok |
;mov edx, eax |
;add edx, [ebx+0x1be+8+16+16] |
;push edx |
;add edx, [ebx+0x1be+12+16+16] |
;dec edx |
;mov [PARTITION_END], edx |
;mov al, [ebx+0x1be+4+16+16] |
;mov [fs_type], dl |
;pop edx |
next_primary_partition_2: |
push eax |
test_primary_partition_3: |
mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type |
call scan_partition_types |
pop eax |
jnz next_partition ; no. skip over |
jnz test_ext_partition_0 ; no. skip over |
inc ecx |
cmp ecx,[fat32part] ; is it wanted partition? |
jnz next_partition ; no |
cmp ecx, [known_part]; is it wanted partition? |
jnz test_ext_partition_0; no |
mov edx, eax |
add edx, [ebx+0x1be+8+16+16+16] |
push edx |
add edx, [ebx+0x1be+12+16+16+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16+16+16] |
mov [fs_type], dl |
pop edx |
pop eax |
add eax, [ebx+0x1be+8+16+16+16] |
mov edx, [ebx+0x1be+12+16+16+16] |
mov cl, [ebx+0x1be+4+16+16+16] |
jmp hd_and_partition_ok |
next_partition: |
push eax |
;mov edx, eax |
;add edx, [ebx+0x1be+8+16+16+16] |
;push edx |
;add edx, [ebx+0x1be+12+16+16+16] |
;dec edx |
;mov [PARTITION_END], edx |
;mov al, [ebx+0x1be+4+16+16+16] |
;mov [fs_type], dl |
;pop edx |
test_ext_partition_0: |
pop eax ; ¯à®áâ® ¢ëª¨¤ë¢ ¥¬ ¨§ á⥪ |
mov al,[ebx+0x1be+4] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_1 |
jnz test_ext_partition_1 |
mov eax,[ebx+0x1be+8] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
jnz new_mbr ; yes. read it |
next_partition_1: |
push eax |
test_ext_partition_1: |
mov al,[ebx+0x1be+4+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_2 |
jnz test_ext_partition_2 |
mov eax,[ebx+0x1be+8+16] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
jnz new_mbr ; yes. read it |
next_partition_2: |
push eax |
test_ext_partition_2: |
mov al,[ebx+0x1be+4+16+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz next_partition_3 |
jnz test_ext_partition_3 |
mov eax,[ebx+0x1be+8+16+16] ; add relative start |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
jnz new_mbr ; yes. read it |
next_partition_3: |
push eax |
test_ext_partition_3: |
mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type |
call scan_extended_types |
pop eax |
jnz end_partition_chain ; no. end chain |
mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition |
test eax,eax ; is there extended partition? |
jnz new_partition ; yes. read it |
jnz new_mbr ; yes. read it |
end_partition_chain: |
mov [partition_count],ecx |
;mov [partition_count],ecx |
cmp edx,-1 ; found wanted partition? |
jnz hd_and_partition_ok ; yes. install it |
jmp problem_partition_or_fat |
;cmp edx,-1 ; found wanted partition? |
;jnz hd_and_partition_ok ; yes. install it |
;jmp problem_partition_or_fat |
problem_hd: |
or [problem_partition], 2 |
jmp return_from_part_set |
scan_partition_types: |
push ecx |
mov edi,partition_types |
323,25 → 361,32 |
ret |
problem_fat_dec_count: ; bootsector is missing or another problem |
dec [partition_count] ; remove it from partition_count |
; dec [partition_count] ; remove it from partition_count |
problem_partition_or_fat: |
problem_hd: |
or [problem_partition], 1 |
return_from_part_set: |
popad |
mov [fs_type],0 |
;mov [fs_type],0 |
call free_hd_channel |
mov [hd1_status],0 ; free |
mov [problem_partition],1 |
ret |
hd_and_partition_ok: |
mov eax,edx |
;eax = PARTITION_START edx=PARTITION_LENGTH cl=fs_type |
mov [fs_type], cl |
;mov eax,edx |
mov [PARTITION_START],eax |
mov edx, [PARTITION_END] |
sub edx, eax |
inc edx ; edx = length of partition |
add edx, eax |
dec edx |
mov [PARTITION_END], edx |
; mov edx, [PARTITION_END] |
; sub edx, eax |
; inc edx ; edx = length of partition § 祬 ®® ¬?? |
; mov [hd_setup],1 |
mov ebx,buffer |
call hd_read ; read boot sector of partition |
366,15 → 411,22 |
add eax, [PARTITION_START] |
call hd_read |
cmp [hd_error], 0 |
jnz problem_fat_dec_count ; ¥ áã¤ì¡ ... |
jnz problem_fat_dec_count ; no chance... |
boot_read_ok: |
; mov [hd_setup], 0 |
; if we are running on NTFS, check bootsector |
; cmp [fs_type], 7 |
; jz ntfs_setup |
call ntfs_test_bootsec |
call ntfs_test_bootsec ; test ntfs |
jnc ntfs_setup |
call ext2_test_superblock ; test ext2fs |
jnc ext2_setup |
mov eax, [PARTITION_START] ;ext2 test changes [buffer] |
call hd_read |
cmp [hd_error], 0 |
jnz problem_fat_dec_count |
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? |
jnz problem_fat_dec_count |
479,3 → 531,4 |
call free_hd_channel |
mov [hd1_status],0 ; free |
ret |
/kernel/branches/net/gui/button.inc |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
8,14 → 8,12 |
$Revision$ |
button._.MAX_BUTTONS = 4095 |
;============================================================================== |
;///// public functions /////////////////////////////////////////////////////// |
;============================================================================== |
button.MAX_BUTTONS = 4095 |
struc SYS_BUTTON |
{ |
.pslot dw ? |
25,6 → 23,7 |
.top dw ? |
.height dw ? |
.id_hi dw ? |
dw ? |
.sizeof: |
} |
virtual at 0 |
31,13 → 30,6 |
SYS_BUTTON SYS_BUTTON |
end virtual |
iglobal |
mx dw 0x0 ; keeps the x mouse's position when it was clicked |
my dw 0x0 ; keeps the y mouse's position when it was clicked |
bPressedMouseXY_B db 0x0 |
btn_down_determ db 0x0 |
endg |
align 4 |
;------------------------------------------------------------------------------ |
syscall_button: ;///// system function 8 ////////////////////////////////////// |
66,7 → 58,7 |
; do we have free button slots available? |
mov edi, [BTN_ADDR] |
mov eax, [edi] |
cmp eax, button._.MAX_BUTTONS |
cmp eax, button.MAX_BUTTONS |
jge .exit |
; does it have positive size? (otherwise it doesn't have sense) |
139,7 → 131,8 |
call button._.incecx2 |
; set button height counter |
@@: mov edx, edi |
@@: |
mov edx, edi |
.next_line: |
call button._.button_dececx |
227,6 → 220,7 |
add esi, edi |
xor ecx, ecx |
add ecx, -SYS_BUTTON.sizeof |
add esi, SYS_BUTTON.sizeof |
.next_button: |
dec ebx |
262,201 → 256,123 |
align 4 |
;------------------------------------------------------------------------------ |
check_buttons: ;/////////////////////////////////////////////////////////////// |
sys_button_activate_handler: ;///////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
cmp byte[BTN_DOWN], 0 ; mouse buttons pressed |
jnz @f |
mov [bPressedMouseXY_B], 0 |
ret |
;> eax = pack[8(process slot), 24(button id)] |
;> ebx = pack[16(button x coord), 16(button y coord)] |
;> cl = mouse button mask this system button was pressed with |
;------------------------------------------------------------------------------ |
call button._.find_button |
or eax, eax |
jz .exit |
@@: pushad |
xor esi, esi |
mov edi, [BTN_ADDR] |
mov edx, [edi] |
test edx, edx |
jne @f |
popad |
ret |
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2] |
call button._.negative_button |
;here i catch the coordinates when the mouse's button is clicked |
@@: push ax |
cmp [bPressedMouseXY_B], 0 ; FALSE |
jnz @f |
mov [bPressedMouseXY_B], 1 ; TRUE - it was already clicked |
mov ax, [MOUSE_X] |
mov [mx], ax |
mov ax, [MOUSE_Y] |
mov [my], ax |
@@: pop ax |
;and it is only refreshed after the mouse's button release |
push esi |
inc edx |
push edx |
.buttonnewcheck: |
pop edx |
pop esi |
inc esi |
cmp edx, esi |
jge .bch |
popad |
.exit: |
ret |
.bch: |
push esi |
push edx |
mov eax, esi |
shl eax, 4 |
add eax, edi |
align 4 |
;------------------------------------------------------------------------------ |
sys_button_deactivate_handler: ;/////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> eax = pack[8(process slot), 24(button id)] |
;> ebx = pack[16(button x coord), 16(button y coord)] |
;> cl = mouse button mask this system button was pressed with |
;------------------------------------------------------------------------------ |
call button._.find_button |
or eax, eax |
jz .exit |
; check that button is at top of windowing stack |
movzx ebx, [eax + SYS_BUTTON.pslot] |
movzx ecx, word[WIN_STACK + ebx * 2] |
cmp ecx, [TASK_COUNT] |
jne .buttonnewcheck |
; check that button start is inside window x/y end |
shl ebx, 5 |
test [ebx + window_data + WDATA.fl_wstate], WSTATE_MINIMIZED |
jnz .buttonnewcheck |
movzx edx, [eax + SYS_BUTTON.left] |
cmp edx, [window_data + ebx + WDATA.box.width] ;ecx |
jge .buttonnewcheck |
movzx edx, [eax + SYS_BUTTON.top] |
cmp edx, [window_data + ebx + WDATA.box.height] ;ecx |
jge .buttonnewcheck |
; check coordinates |
; mouse x >= button x ? |
add ebx, window_data |
mov ecx, [ebx + WDATA.box.left] |
movzx edx, [eax + SYS_BUTTON.left] |
add edx, ecx |
mov cx, [mx] ;mov cx,[MOUSE_X] |
cmp edx, ecx |
jg .buttonnewcheck |
movzx ebx, [eax + SYS_BUTTON.width] |
add edx, ebx |
cmp ecx, edx |
jg .buttonnewcheck |
; mouse y >= button y ? |
movzx ebx, [eax + SYS_BUTTON.pslot] |
shl ebx, 5 |
add ebx, window_data |
mov ecx, [ebx + WDATA.box.top] |
movzx edx, [eax + SYS_BUTTON.top] |
add edx, ecx |
mov cx, [my] ;mov cx,[MOUSE_Y] |
cmp edx, ecx |
jg .buttonnewcheck |
movzx ebx, [eax + SYS_BUTTON.height] |
add edx, ebx |
cmp ecx, edx |
jg .buttonnewcheck |
; mouse on button |
pop edx |
pop esi |
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2] ; button id : bits 16-31 |
mov bx, [eax + SYS_BUTTON.id_lo] ; button id : bits 00-16 |
push ebx |
mov byte[MOUSE_DOWN], 1 ; no mouse down checks |
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2] |
call button._.negative_button |
pushad |
push eax |
mov al, [BTN_DOWN] |
mov byte[btn_down_determ], al |
pop eax |
.exit: |
ret |
.cbwaitmouseup: |
call checkidle |
call [draw_pointer] |
align 4 |
;------------------------------------------------------------------------------ |
sys_button_perform_handler: ;////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> eax = pack[8(process slot), 24(button id)] |
;> ebx = pack[16(button x coord), 16(button y coord)] |
;> cl = mouse button mask this system button was pressed with |
;------------------------------------------------------------------------------ |
shl eax, 8 |
mov al, cl |
movzx ebx, byte[BTN_COUNT] |
mov [BTN_BUFF + ebx * 4], eax |
inc bl |
mov [BTN_COUNT], bl |
ret |
pushad |
call stack_handler |
popad |
;============================================================================== |
;///// private functions ////////////////////////////////////////////////////// |
;============================================================================== |
cmp byte[BTN_DOWN], 0 ; mouse buttons pressed ? |
jnz .cbwaitmouseup |
popad |
;------------------------------------------------------------------------------ |
button._.find_button: ;//////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Find system button by specified process slot, id and coordinates |
;------------------------------------------------------------------------------ |
;> eax = pack[8(process slot), 24(button id)] or 0 |
;> ebx = pack[16(button x coord), 16(button y coord)] |
;------------------------------------------------------------------------------ |
;< eax = pointer to SYS_BUTTON struct or 0 |
;------------------------------------------------------------------------------ |
push ecx edx esi edi |
call button._.negative_button |
mov byte[MOUSE_BACKGROUND], 0 ; no mouse background |
mov byte[DONT_DRAW_MOUSE], 0 ; draw mouse |
mov edx, eax |
shr edx, 24 |
and eax, 0x0ffffff |
; check coordinates |
pusha |
mov edi, [BTN_ADDR] |
mov ecx, [edi] |
imul esi, ecx, SYS_BUTTON.sizeof |
add esi, edi |
inc ecx |
add esi, SYS_BUTTON.sizeof |
; mouse x >= button x ? |
movzx ebx, [eax + SYS_BUTTON.pslot] |
shl ebx, 5 |
add ebx, window_data |
mov ecx, [ebx + WDATA.box.left] |
movzx edx, [eax + SYS_BUTTON.left] |
add edx, ecx |
mov cx, [MOUSE_X] |
cmp edx, ecx |
jg .no_on_button ;if we release the pointer out of the button area |
.next_button: |
dec ecx |
jz .not_found |
movzx ebx, [eax + SYS_BUTTON.width] |
add edx, ebx |
cmp ecx, edx |
jg .no_on_button |
add esi, -SYS_BUTTON.sizeof |
; mouse y >= button y ? |
movzx ebx, [eax + SYS_BUTTON.pslot] |
shl ebx, 5 |
add ebx, window_data |
mov ecx, [ebx + WDATA.box.top] |
movzx edx, [eax + SYS_BUTTON.top] |
add edx, ecx |
mov cx, [MOUSE_Y] |
cmp edx, ecx |
jg .no_on_button |
; does it belong to our process? |
cmp dx, [esi + SYS_BUTTON.pslot] |
jne .next_button |
movzx ebx, [eax + SYS_BUTTON.height] |
add edx, ebx |
cmp ecx, edx |
jg .no_on_button |
; does id match? |
mov edi, dword[esi + SYS_BUTTON.id_hi - 2] |
mov di, [esi + SYS_BUTTON.id_lo] |
and edi, 0x0ffffff |
cmp eax, edi |
jne .next_button |
popa |
; does coordinates match? |
mov edi, dword[esi + SYS_BUTTON.left - 2] |
mov di, [esi + SYS_BUTTON.top] |
cmp ebx, edi |
jne .next_button |
mov byte[BTN_COUNT], 1 ; no of buttons in buffer |
pop ebx |
mov [BTN_BUFF], ebx ; lets put the button id in buffer |
push ebx |
pusha |
jmp .yes_on_button |
; okay, return it |
mov eax, esi |
jmp .exit |
.no_on_button: |
mov byte[BTN_COUNT], 0 ; no of buttons in buffer |
.not_found: |
xor eax, eax |
.yes_on_button: |
mov byte[MOUSE_DOWN], 0 ; mouse down -> do not draw |
popa |
pop ebx |
popa |
.exit: |
pop edi esi edx ecx |
ret |
;============================================================================== |
;///// private functions ////////////////////////////////////////////////////// |
;============================================================================== |
;------------------------------------------------------------------------------ |
button._.dececx: ;///////////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
465,14 → 381,17 |
sub cl, 0x20 |
jnc @f |
xor cl, cl |
@@: sub ch, 0x20 |
@@: |
sub ch, 0x20 |
jnc @f |
xor ch, ch |
@@: rol ecx, 16 |
@@: |
rol ecx, 16 |
sub cl, 0x20 |
jnc @f |
xor cl, cl |
@@: rol ecx, 16 |
@@: |
rol ecx, 16 |
ret |
;------------------------------------------------------------------------------ |
483,14 → 402,17 |
add cl, 0x20 |
jnc @f |
or cl, -1 |
@@: add ch, 0x20 |
@@: |
add ch, 0x20 |
jnc @f |
or ch, -1 |
@@: rol ecx, 16 |
@@: |
rol ecx, 16 |
add cl, 0x20 |
jnc @f |
or cl, -1 |
@@: rol ecx, 16 |
@@: |
rol ecx, 16 |
ret |
;------------------------------------------------------------------------------ |
501,14 → 423,17 |
add cl, 0x14 |
jnc @f |
or cl, -1 |
@@: add ch, 0x14 |
@@: |
add ch, 0x14 |
jnc @f |
or ch, -1 |
@@: rol ecx, 16 |
@@: |
rol ecx, 16 |
add cl, 0x14 |
jnc @f |
or cl, -1 |
@@: rol ecx, 16 |
@@: |
rol ecx, 16 |
ret |
;------------------------------------------------------------------------------ |
525,17 → 450,21 |
jg @f |
mov al, 2 |
@@: sub cl, al |
@@: |
sub cl, al |
jnc @f |
xor cl, cl |
@@: sub ch, al |
@@: |
sub ch, al |
jnc @f |
xor ch, ch |
@@: rol ecx, 16 |
@@: |
rol ecx, 16 |
sub cl, al |
jnc @f |
xor cl, cl |
@@: rol ecx, 16 |
@@: |
rol ecx, 16 |
pop eax |
545,7 → 474,7 |
;------------------------------------------------------------------------------ |
button._.negative_button: ;//////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;? Invert system button border |
;------------------------------------------------------------------------------ |
; if requested, do not display button border on press. |
test ebx, 0x20000000 |
/kernel/branches/net/gui/event.inc |
---|
7,6 → 7,13 |
$Revision$ |
WINDOW_MOVE_AND_RESIZE_FLAGS = \ |
mouse.WINDOW_RESIZE_N_FLAG + \ |
mouse.WINDOW_RESIZE_W_FLAG + \ |
mouse.WINDOW_RESIZE_S_FLAG + \ |
mouse.WINDOW_RESIZE_E_FLAG + \ |
mouse.WINDOW_MOVE_FLAG |
uglobal |
align 4 |
event_start dd ? |
25,7 → 32,8 |
mov ecx,EV_SPACE ; current - in allocated space |
mov ebx,FreeEvents ; previos - íà÷àëî ñïèñêà |
push ebx ; îíî æå è êîíåö ïîòîì áóäåò |
@@: mov [ebx+EVENT.fd],eax |
@@: |
mov [ebx+EVENT.fd], eax |
mov [eax+EVENT.bk],ebx |
mov ebx,eax ; previos <- current |
add eax,EVENT.size ; new current |
33,7 → 41,8 |
pop eax ; âîò îíî êîíöîì è ñòàëî |
mov [ebx+EVENT.fd],eax |
mov [eax+EVENT.bk],ebx |
.fail: ret |
.fail: |
ret |
EVENT_WATCHED equ 0x10000000 ;áèò 28 |
EVENT_SIGNALED equ 0x20000000 ;áèò 29 |
80,7 → 89,8 |
call init_events |
popad |
jz RemoveEventTo.break ; POPF+RET |
@@: mov eax,[eax+EVENT.fd] |
@@: |
mov eax, [eax+EVENT.fd] |
mov [eax+EVENT.magic],'EVNT' |
mov [eax+EVENT.destroy],destroy_event.internal |
mov [eax+EVENT.state],ecx |
108,7 → 118,8 |
xchg ecx,[eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight |
mov [ebx+EVENT.fd],ecx ; OldLeft.fd=OldRight |
mov [ecx+EVENT.bk],ebx ; OldRight.bk=OldLeft |
.break: popfd |
.break: |
popfd |
ret |
align 4 |
206,9 → 217,11 |
jne @f |
cmp [eax+EVENT.id],ebx |
je .ret |
@@: pop eax |
@@: |
pop eax |
xor eax,eax |
.ret: ret |
.ret: |
ret |
align 4 |
247,7 → 260,8 |
mov [eax+TASKDATA.state], 5 |
call change_task |
mov eax,[esi+APPDATA.wait_param] |
@@: ret |
@@: |
ret |
align 4 |
wait_event: ;; EXPORT use |
339,7 → 353,8 |
mov eax,[ebx+APPOBJ.bk] ; âûáèðàåì ñ êîíöà, ïî ïðèíöèïó FIFO |
cmp eax,ebx ; empty ??? |
je get_event_alone.ret0 |
.ret: ret |
.ret: |
ret |
align 4 |
get_event_alone: |
357,8 → 372,10 |
test byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24 |
jnz .ret |
or byte[eax+EVENT.state+3], EVENT_WATCHED shr 24 |
.ret0: xor eax,eax ; NO event!!! |
.ret: ret |
.ret0: |
xor eax, eax; NO event!!! |
.ret: |
ret |
align 4 |
sys_sendwindowmsg: ;; f72 |
368,11 → 385,13 |
cli |
sub ecx,2 |
je .sendkey |
loop .retf |
dec ecx |
jnz .retf |
.sendbtn: |
cmp byte[BTN_COUNT],1 |
jae .result ;overflow |
inc byte[BTN_COUNT] |
shl edx, 8 |
mov [BTN_BUFF],edx |
jmp .result |
.sendkey: |
384,7 → 403,8 |
.result: |
setae byte[esp+32] ;ñ÷èòàåì, ÷òî èñõîäíî: dword[esp+32]==72 |
.retf: ;popfd |
.ret: ret |
.ret: |
ret |
align 4 |
sys_getevent: ;; f11 |
426,10 → 446,8 |
jz .no_events ; èñ÷åðïàëè âñå áèòû ìàñêè, íî íè÷åãî íå íàøëè ??? |
btr ecx,eax ; ñáðàñûâàåì ïðîâåðÿåìûé áèò ìàñêè |
; ïåðåõîäèì íà îáðàáîò÷èê ýòîãî (eax) áèòà |
cmp eax,16 |
jae .IRQ ; eax=[16..31]=retvals, events irq0..irq15 |
cmp eax,9 |
jae .loop ; eax=[9..15], ignored |
jae .loop ; eax=[9..31], ignored |
cmp eax,3 |
je .loop ; eax=3, ignored |
ja .FlagAutoReset ; eax=[4..8], retvals=eax+1 |
442,17 → 460,18 |
.no_events: |
xor eax,eax |
ret |
.IRQ: |
;TODO: ñäåëàòü òàê æå, êàê è äëÿ FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug) |
mov edx,[irq_owner+eax*4-64] ; eax==16+irq |
cmp edx,[edi+TASKDATA.pid] |
jne .loop |
mov edx,eax |
shl edx,12 |
cmp dword[IRQ_SAVE+edx-0x10000],0 ; edx==(16+irq)*0x1000 |
je .loop ; empty ??? |
ret ; retval = eax |
.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9 |
cmp eax, 5; Mouse 5+1=6 |
jne @f |
push eax |
; If the window is captured and moved by the user, then no mouse events!!! |
mov al, [mouse.active_sys_window.action] |
and al, WINDOW_MOVE_AND_RESIZE_FLAGS |
test al, al |
pop eax |
jnz .loop |
@@: |
btr [ebx+APPDATA.event_mask],eax |
jnc .loop |
.result: ; retval = eax+1 |
467,7 → 486,9 |
je .loop ; empty ??? |
cmp edx,[TASK_COUNT] |
jne .loop ; not Top ??? |
cmp dword[BTN_BUFF],0xFFFF ;-ID for Minimize-Button of Form |
mov edx, [BTN_BUFF] |
shr edx, 8 |
cmp edx, 0xFFFF ;-ID for Minimize-Button of Form |
jne .result |
mov [window_minimize],1 |
dec byte[BTN_COUNT] |
477,8 → 498,10 |
jne @f ; not Top ??? |
cmp [KEY_COUNT],al ; al==1 |
jae .result ; not empty ??? |
@@: mov edx, hotkey_buffer |
@@: cmp [edx],bh ; bh - slot for testing |
@@: |
mov edx, hotkey_buffer |
@@: |
cmp [edx], bh ; bh - slot for testing |
je .result |
add edx,8 |
cmp edx, hotkey_buffer+120*8 |
/kernel/branches/net/gui/mouse.inc |
---|
1,250 → 1,715 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Copyright (C) KolibriOS team 2010. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
include 'mousepointer.inc' |
iglobal |
;============================================================================== |
;///// public functions /////////////////////////////////////////////////////// |
;============================================================================== |
mouse.LEFT_BUTTON_FLAG = 0001b |
mouse.RIGHT_BUTTON_FLAG = 0010b |
mouse.MIDDLE_BUTTON_FLAG = 0100b |
mouse.BUTTONS_MASK = \ |
mouse.LEFT_BUTTON_FLAG or \ |
mouse.RIGHT_BUTTON_FLAG or \ |
mouse.MIDDLE_BUTTON_FLAG |
mouse.WINDOW_RESIZE_N_FLAG = 000001b |
mouse.WINDOW_RESIZE_W_FLAG = 000010b |
mouse.WINDOW_RESIZE_S_FLAG = 000100b |
mouse.WINDOW_RESIZE_E_FLAG = 001000b |
mouse.WINDOW_MOVE_FLAG = 010000b |
mouse.WINDOW_RESIZE_SW_FLAG = \ |
mouse.WINDOW_RESIZE_S_FLAG or \ |
mouse.WINDOW_RESIZE_W_FLAG |
mouse.WINDOW_RESIZE_SE_FLAG = \ |
mouse.WINDOW_RESIZE_S_FLAG or \ |
mouse.WINDOW_RESIZE_E_FLAG |
align 4 |
mousepointer: |
db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f |
db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79 |
db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63 |
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 |
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57 |
db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71 |
db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50 |
db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70 |
db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f |
db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70 |
db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e |
db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a |
db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66 |
db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e |
db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39 |
db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66 |
db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c |
db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68 |
db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d |
db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00 |
db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e |
db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e |
db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00 |
db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64 |
db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d |
db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d |
db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14 |
db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a |
db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c |
db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52 |
db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77 |
db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00 |
db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25 |
db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54 |
db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d |
db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52 |
db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80 |
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33 |
db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64 |
db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d |
db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a |
db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff |
db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35 |
db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70 |
db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77 |
db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68 |
db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41 |
db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f |
db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79 |
db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e |
db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52 |
db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77 |
db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c |
db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f |
db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56 |
db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d |
db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e |
db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76 |
db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56 |
db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b |
db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f |
db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76 |
db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66 |
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 |
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77 |
db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71 |
db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b |
db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c |
db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a |
db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f |
db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e |
db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e |
db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 |
db 0x80,0x80 |
;------------------------------------------------------------------------------ |
mouse_check_events: ;////////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Check if mouse buttons state or cursor position has changed and call |
;? appropriate handlers |
;------------------------------------------------------------------------------ |
push eax ebx |
mousepointer1: |
db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a |
db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16 |
db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e |
db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f |
db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47 |
db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23 |
db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c |
db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c |
db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c |
db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37 |
db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31 |
db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49 |
db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78 |
db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16 |
db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33 |
db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08 |
db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e |
db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00 |
db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff |
db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50 |
db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56 |
db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a |
db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05 |
db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49 |
db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d |
db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27 |
db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06 |
db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00 |
mov al, [BTN_DOWN] |
mov bl, [mouse.state.buttons] |
and al, mouse.BUTTONS_MASK |
mov cl, al |
xchg cl, [mouse.state.buttons] |
xor bl, al |
push eax ebx |
; did any mouse button changed its state? |
or bl, bl |
jz .check_position |
; yes it did, is that the first button of all pressed down? |
or cl, cl |
jnz .check_buttons_released |
; yes it is, activate window user is pointing at, if needed |
call mouse._.activate_sys_window_under_cursor |
; NOTE: this code wouldn't be necessary if we knew window did |
; already redraw itself after call above |
or eax, eax |
jz @f |
and [mouse.state.buttons], 0 |
jmp .exit |
; is there any system button under cursor? |
@@: |
call mouse._.find_sys_button_under_cursor |
or eax, eax |
jz .check_buttons_released |
; yes there is, activate it and exit |
mov [mouse.active_sys_button.pbid], eax |
mov [mouse.active_sys_button.coord], ebx |
mov cl, [mouse.state.buttons] |
mov [mouse.active_sys_button.buttons], cl |
call sys_button_activate_handler |
jmp .exit |
.check_buttons_released: |
cmp [mouse.state.buttons], 0 |
jnz .buttons_changed |
; did we press some button earlier? |
cmp [mouse.active_sys_button.pbid], 0 |
je .buttons_changed |
; yes we did, deactivate it |
xor eax, eax |
xchg eax, [mouse.active_sys_button.pbid] |
mov ebx, [mouse.active_sys_button.coord] |
mov cl, [mouse.active_sys_button.buttons] |
push eax ebx |
call sys_button_deactivate_handler |
pop edx ecx |
; is the button under cursor the one we deactivated? |
call mouse._.find_sys_button_under_cursor |
cmp eax, ecx |
jne .exit |
cmp ebx, edx |
jne .exit |
; yes it is, perform associated action |
mov cl, [mouse.active_sys_button.buttons] |
call sys_button_perform_handler |
jmp .exit |
.buttons_changed: |
test byte[esp], mouse.LEFT_BUTTON_FLAG |
jz @f |
mov eax, [esp + 4] |
call .call_left_button_handler |
@@: |
test byte[esp], mouse.RIGHT_BUTTON_FLAG |
jz @f |
mov eax, [esp + 4] |
call .call_right_button_handler |
@@: |
test byte[esp], mouse.MIDDLE_BUTTON_FLAG |
jz .check_position |
mov eax, [esp + 4] |
call .call_middle_button_handler |
.check_position: |
movzx eax, word[MOUSE_X] |
movzx ebx, word[MOUSE_Y] |
cmp eax, [mouse.state.pos.x] |
jne .position_changed |
cmp ebx, [mouse.state.pos.y] |
je .exit |
.position_changed: |
xchg eax, [mouse.state.pos.x] |
xchg ebx, [mouse.state.pos.y] |
call mouse._.move_handler |
.exit: |
add esp, 8 |
pop ebx eax |
ret |
.call_left_button_handler: |
test eax, mouse.LEFT_BUTTON_FLAG |
jnz mouse._.left_button_press_handler |
jmp mouse._.left_button_release_handler |
.call_right_button_handler: |
test eax, mouse.RIGHT_BUTTON_FLAG |
jnz mouse._.right_button_press_handler |
jmp mouse._.right_button_release_handler |
.call_middle_button_handler: |
test eax, mouse.MIDDLE_BUTTON_FLAG |
jnz mouse._.middle_button_press_handler |
jmp mouse._.middle_button_release_handler |
;============================================================================== |
;///// private functions ////////////////////////////////////////////////////// |
;============================================================================== |
uglobal |
mouse.state: |
.pos POINT |
.buttons db ? |
; NOTE: since there's no unique and lifetime-constant button identifiers, |
; we're using two dwords to identify each of them: |
; * pbid - process slot (high 8 bits) and button id (low 24 bits) pack |
; * coord - left (high 16 bits) and top (low 16 bits) coordinates pack |
align 4 |
mouse.active_sys_button: |
.pbid dd ? |
.coord dd ? |
.buttons db ? |
align 4 |
mouse.active_sys_window: |
.pslot dd ? |
.old_box BOX |
.new_box BOX |
.delta POINT |
.last_ticks dd ? |
.action db ? |
endg |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.left_button_press_handler: ;/////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when left mouse button has been pressed down |
;------------------------------------------------------------------------------ |
test [mouse.state.buttons], not mouse.LEFT_BUTTON_FLAG |
jnz .exit |
call mouse._.find_sys_window_under_cursor |
call mouse._.check_sys_window_actions |
mov [mouse.active_sys_window.action], al |
or eax, eax |
jz .exit |
xchg eax, edx |
test dl, mouse.WINDOW_MOVE_FLAG |
jz @f |
mov eax, [timer_ticks] |
mov ebx, eax |
xchg ebx, [mouse.active_sys_window.last_ticks] |
sub eax, ebx |
cmp eax, 50 |
jg @f |
mov [mouse.active_sys_window.last_ticks], 0 |
call sys_window_maximize_handler |
jmp .exit |
@@: |
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED |
jnz .exit |
mov [mouse.active_sys_window.pslot], esi |
lea eax, [edi + WDATA.box] |
mov ebx, mouse.active_sys_window.old_box |
mov ecx, sizeof.BOX |
call memmove |
mov ebx, mouse.active_sys_window.new_box |
call memmove |
test edx, mouse.WINDOW_MOVE_FLAG |
jz @f |
call .calculate_n_delta |
call .calculate_w_delta |
jmp .call_window_handler |
@@: |
test dl, mouse.WINDOW_RESIZE_W_FLAG |
jz @f |
call .calculate_w_delta |
@@: |
test dl, mouse.WINDOW_RESIZE_S_FLAG |
jz @f |
call .calculate_s_delta |
@@: |
test dl, mouse.WINDOW_RESIZE_E_FLAG |
jz .call_window_handler |
call .calculate_e_delta |
.call_window_handler: |
mov eax, mouse.active_sys_window.old_box |
call sys_window_start_moving_handler |
.exit: |
ret |
.calculate_n_delta: |
mov eax, [mouse.state.pos.y] |
sub eax, [mouse.active_sys_window.old_box.top] |
mov [mouse.active_sys_window.delta.y], eax |
ret |
.calculate_w_delta: |
mov eax, [mouse.state.pos.x] |
sub eax, [mouse.active_sys_window.old_box.left] |
mov [mouse.active_sys_window.delta.x], eax |
ret |
.calculate_s_delta: |
mov eax, [mouse.active_sys_window.old_box.top] |
add eax, [mouse.active_sys_window.old_box.height] |
sub eax, [mouse.state.pos.y] |
mov [mouse.active_sys_window.delta.y], eax |
ret |
.calculate_e_delta: |
mov eax, [mouse.active_sys_window.old_box.left] |
add eax, [mouse.active_sys_window.old_box.width] |
sub eax, [mouse.state.pos.x] |
mov [mouse.active_sys_window.delta.x], eax |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.left_button_release_handler: ;///////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when left mouse button has been released |
;------------------------------------------------------------------------------ |
xor esi, esi |
xchg esi, [mouse.active_sys_window.pslot] |
or esi, esi |
jz .exit |
mov eax, esi |
shl eax, 5 |
add eax, window_data + WDATA.box |
mov ebx, mouse.active_sys_window.old_box |
mov ecx, sizeof.BOX |
call memmove |
mov eax, mouse.active_sys_window.old_box |
mov ebx, mouse.active_sys_window.new_box |
call sys_window_end_moving_handler |
.exit: |
and [mouse.active_sys_window.action], 0 |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.right_button_press_handler: ;////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when right mouse button has been pressed down |
;------------------------------------------------------------------------------ |
test [mouse.state.buttons], not mouse.RIGHT_BUTTON_FLAG |
jnz .exit |
call mouse._.find_sys_window_under_cursor |
call mouse._.check_sys_window_actions |
test al, mouse.WINDOW_MOVE_FLAG |
jz .exit |
call sys_window_rollup_handler |
.exit: |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.right_button_release_handler: ;//////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when right mouse button has been released |
;------------------------------------------------------------------------------ |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.middle_button_press_handler: ;///////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when middle mouse button has been pressed down |
;------------------------------------------------------------------------------ |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.middle_button_release_handler: ;/////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when middle mouse button has been released |
;------------------------------------------------------------------------------ |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.move_handler: ;//////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Called when cursor has been moved |
;------------------------------------------------------------------------------ |
;> eax = old x coord |
;> ebx = old y coord |
;------------------------------------------------------------------------------ |
cmp [mouse.active_sys_button.pbid], 0 |
jnz .exit |
mov esi, [mouse.active_sys_window.pslot] |
or esi, esi |
jz .exit |
mov eax, mouse.active_sys_window.new_box |
mov ebx, mouse.active_sys_window.old_box |
mov ecx, sizeof.BOX |
call memmove |
mov dl, [mouse.active_sys_window.action] |
test dl, mouse.WINDOW_MOVE_FLAG |
jz .check_resize_w |
mov eax, [mouse.state.pos.x] |
sub eax, [mouse.active_sys_window.delta.x] |
mov [mouse.active_sys_window.new_box.left], eax |
mov eax, [mouse.state.pos.y] |
sub eax, [mouse.active_sys_window.delta.y] |
mov [mouse.active_sys_window.new_box.top], eax |
mov eax, [mouse.active_sys_window.new_box.left] |
or eax, eax |
jge @f |
xor eax, eax |
mov [mouse.active_sys_window.new_box.left], eax |
@@: |
add eax, [mouse.active_sys_window.new_box.width] |
cmp eax, [Screen_Max_X] |
jl @f |
sub eax, [Screen_Max_X] |
sub [mouse.active_sys_window.new_box.left], eax |
@@: |
mov eax, [mouse.active_sys_window.new_box.top] |
or eax, eax |
jge @f |
xor eax, eax |
mov [mouse.active_sys_window.new_box.top], eax |
@@: |
add eax, [mouse.active_sys_window.new_box.height] |
cmp eax, [Screen_Max_Y] |
jle .call_window_handler |
sub eax, [Screen_Max_Y] |
sub [mouse.active_sys_window.new_box.top], eax |
jmp .call_window_handler |
.check_resize_w: |
test dl, mouse.WINDOW_RESIZE_W_FLAG |
jz .check_resize_s |
mov eax, [mouse.state.pos.x] |
sub eax, [mouse.active_sys_window.delta.x] |
mov [mouse.active_sys_window.new_box.left], eax |
sub eax, [mouse.active_sys_window.old_box.left] |
sub [mouse.active_sys_window.new_box.width], eax |
mov eax, [mouse.active_sys_window.new_box.width] |
sub eax, 127 |
jge @f |
add [mouse.active_sys_window.new_box.left], eax |
mov [mouse.active_sys_window.new_box.width], 127 |
@@: |
mov eax, [mouse.active_sys_window.new_box.left] |
or eax, eax |
jge .check_resize_s |
add [mouse.active_sys_window.new_box.width], eax |
xor eax, eax |
mov [mouse.active_sys_window.new_box.left], eax |
.check_resize_s: |
test dl, mouse.WINDOW_RESIZE_S_FLAG |
jz .check_resize_e |
mov eax, [mouse.state.pos.y] |
add eax, [mouse.active_sys_window.delta.y] |
sub eax, [mouse.active_sys_window.old_box.top] |
mov [mouse.active_sys_window.new_box.height], eax |
push eax |
mov edi, esi |
shl edi, 5 |
add edi, window_data |
call window._.get_rolledup_height |
mov ecx, eax |
pop eax |
mov eax, [mouse.active_sys_window.new_box.height] |
cmp eax, ecx |
jge @f |
mov eax, ecx |
mov [mouse.active_sys_window.new_box.height], eax |
@@: |
add eax, [mouse.active_sys_window.new_box.top] |
cmp eax, [Screen_Max_Y] |
jle .check_resize_e |
sub eax, [Screen_Max_Y] |
neg eax |
add [mouse.active_sys_window.new_box.height], eax |
mov ecx, [Screen_Max_Y] |
cmp ecx, eax |
jge .check_resize_e |
mov [mouse.active_sys_window.new_box.height], ecx |
.check_resize_e: |
test dl, mouse.WINDOW_RESIZE_E_FLAG |
jz .call_window_handler |
mov eax, [mouse.state.pos.x] |
add eax, [mouse.active_sys_window.delta.x] |
sub eax, [mouse.active_sys_window.old_box.left] |
mov [mouse.active_sys_window.new_box.width], eax |
mov eax, [mouse.active_sys_window.new_box.width] |
cmp eax, 127 |
jge @f |
mov eax, 127 |
mov [mouse.active_sys_window.new_box.width], eax |
@@: |
add eax, [mouse.active_sys_window.new_box.left] |
cmp eax, [Screen_Max_X] |
jle .call_window_handler |
sub eax, [Screen_Max_X] |
neg eax |
add [mouse.active_sys_window.new_box.width], eax |
mov ecx, [Screen_Max_X] |
cmp ecx, eax |
jge .call_window_handler |
mov [mouse.active_sys_window.new_box.width], ecx |
.call_window_handler: |
mov eax, mouse.active_sys_window.old_box |
mov ebx, mouse.active_sys_window.new_box |
push esi |
mov esi, mouse.active_sys_window.old_box |
mov edi, mouse.active_sys_window.new_box |
mov ecx, sizeof.BOX / 4 |
repe |
cmpsd |
pop esi |
je .exit |
mov [mouse.active_sys_window.last_ticks], 0 |
call sys_window_moving_handler |
.exit: |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.find_sys_window_under_cursor: ;//////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Find system window object which is currently visible on screen and has |
;? mouse cursor within its bounds |
;------------------------------------------------------------------------------ |
;< esi = process slot |
;< edi = pointer to WDATA struct |
;------------------------------------------------------------------------------ |
mov esi, [Screen_Max_X] |
inc esi |
imul esi, [mouse.state.pos.y] |
add esi, [_WinMapAddress] |
add esi, [mouse.state.pos.x] |
movzx esi, byte[esi] |
mov edi, esi |
shl edi, 5 |
add edi, window_data |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.activate_sys_window_under_cursor: ;//////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
; activate and redraw window under cursor (if necessary) |
call mouse._.find_sys_window_under_cursor |
movzx esi, word[WIN_STACK + esi * 2] |
lea esi, [WIN_POS + esi * 2] |
jmp waredraw |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.find_sys_button_under_cursor: ;//////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Find system button object which is currently visible on screen and has |
;? mouse cursor within its bounds |
;------------------------------------------------------------------------------ |
;< eax = pack[8(process slot), 24(button id)] or 0 |
;< ebx = pack[16(button x coord), 16(button y coord)] |
;------------------------------------------------------------------------------ |
push ecx edx esi edi |
call mouse._.find_sys_window_under_cursor |
mov edx, esi |
; check if any process button contains cursor |
mov eax, [BTN_ADDR] |
mov ecx, [eax] |
imul esi, ecx, SYS_BUTTON.sizeof |
add esi, eax |
inc ecx |
add esi, SYS_BUTTON.sizeof |
.next_button: |
dec ecx |
jz .not_found |
add esi, -SYS_BUTTON.sizeof |
; does it belong to our process? |
cmp dx, [esi + SYS_BUTTON.pslot] |
jne .next_button |
; does it contain cursor coordinates? |
mov eax, [mouse.state.pos.x] |
sub eax, [edi + WDATA.box.left] |
sub ax, [esi + SYS_BUTTON.left] |
jl .next_button |
sub ax, [esi + SYS_BUTTON.width] |
jge .next_button |
mov eax, [mouse.state.pos.y] |
sub eax, [edi + WDATA.box.top] |
sub ax, [esi + SYS_BUTTON.top] |
jl .next_button |
sub ax, [esi + SYS_BUTTON.height] |
jge .next_button |
; okay, return it |
shl edx, 24 |
mov eax, dword[esi + SYS_BUTTON.id_hi - 2] |
mov ax, [esi + SYS_BUTTON.id_lo] |
and eax, 0x0ffffff |
or eax, edx |
mov ebx, dword[esi + SYS_BUTTON.left - 2] |
mov bx, [esi + SYS_BUTTON.top] |
jmp .exit |
.not_found: |
xor eax, eax |
xor ebx, ebx |
.exit: |
pop edi esi edx ecx |
ret |
align 4 |
;------------------------------------------------------------------------------ |
mouse._.check_sys_window_actions: ;//////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;< eax = action flags or 0 |
;------------------------------------------------------------------------------ |
; is window movable? |
test byte[edi + WDATA.cl_titlebar + 3], 0x01 |
jnz .no_action |
mov eax, [mouse.state.pos.x] |
mov ebx, [mouse.state.pos.y] |
sub eax, [edi + WDATA.box.left] |
sub ebx, [edi + WDATA.box.top] |
; is there a window titlebar under cursor? |
push eax |
call window._.get_titlebar_height |
cmp ebx, eax |
pop eax |
jl .move_action |
; no there isn't, can it be resized then? |
mov dl, [edi + WDATA.fl_wstyle] |
and dl, 0x0f |
; NOTE: dangerous optimization, revise if window types changed; |
; this currently implies only types 2 and 3 could be resized |
test dl, 2 |
jz .no_action |
mov ecx, [edi + WDATA.box.width] |
add ecx, -window.BORDER_SIZE |
mov edx, [edi + WDATA.box.height] |
add edx, -window.BORDER_SIZE |
; is it rolled up? |
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP |
jnz .resize_w_or_e_action |
cmp eax, window.BORDER_SIZE |
jl .resize_w_action |
cmp eax, ecx |
jg .resize_e_action |
cmp ebx, edx |
jle .no_action |
.resize_s_action: |
cmp eax, window.BORDER_SIZE + 10 |
jl .resize_sw_action |
add ecx, -10 |
cmp eax, ecx |
jge .resize_se_action |
mov eax, mouse.WINDOW_RESIZE_S_FLAG |
jmp .exit |
.resize_w_or_e_action: |
cmp eax, window.BORDER_SIZE + 10 |
jl .resize_w_action.direct |
add ecx, -10 |
cmp eax, ecx |
jg .resize_e_action.direct |
jmp .no_action |
.resize_w_action: |
add edx, -10 |
cmp ebx, edx |
jge .resize_sw_action |
.resize_w_action.direct: |
mov eax, mouse.WINDOW_RESIZE_W_FLAG |
jmp .exit |
.resize_e_action: |
add edx, -10 |
cmp ebx, edx |
jge .resize_se_action |
.resize_e_action.direct: |
mov eax, mouse.WINDOW_RESIZE_E_FLAG |
jmp .exit |
.resize_sw_action: |
mov eax, mouse.WINDOW_RESIZE_SW_FLAG |
jmp .exit |
.resize_se_action: |
mov eax, mouse.WINDOW_RESIZE_SE_FLAG |
jmp .exit |
.move_action: |
mov eax, mouse.WINDOW_MOVE_FLAG |
jmp .exit |
.no_action: |
xor eax, eax |
.exit: |
ret |
/kernel/branches/net/gui/mousepointer.inc |
---|
0,0 → 1,250 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 2288 $ |
iglobal |
align 4 |
mousepointer: |
db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f |
db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79 |
db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63 |
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 |
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57 |
db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71 |
db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50 |
db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70 |
db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f |
db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70 |
db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e |
db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a |
db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66 |
db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e |
db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39 |
db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66 |
db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c |
db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68 |
db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d |
db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00 |
db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e |
db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e |
db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00 |
db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64 |
db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d |
db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d |
db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14 |
db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a |
db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c |
db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52 |
db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77 |
db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00 |
db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25 |
db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54 |
db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d |
db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52 |
db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80 |
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33 |
db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64 |
db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d |
db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a |
db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff |
db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35 |
db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70 |
db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77 |
db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68 |
db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41 |
db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f |
db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79 |
db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e |
db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52 |
db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77 |
db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c |
db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f |
db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56 |
db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d |
db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e |
db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76 |
db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56 |
db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b |
db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f |
db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76 |
db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66 |
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 |
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77 |
db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71 |
db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b |
db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c |
db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a |
db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f |
db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e |
db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e |
db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 |
db 0x80,0x80 |
mousepointer1: |
db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a |
db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16 |
db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e |
db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f |
db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47 |
db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23 |
db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c |
db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c |
db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c |
db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37 |
db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31 |
db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49 |
db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78 |
db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16 |
db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33 |
db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08 |
db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e |
db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00 |
db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff |
db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50 |
db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56 |
db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a |
db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05 |
db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49 |
db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d |
db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27 |
db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06 |
db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00 |
endg |
/kernel/branches/net/gui/skincode.inc |
---|
68,10 → 68,10 |
struct SKIN_BUTTONS |
type dd ? |
; pos: |
; position |
left dw ? |
top dw ? |
; size: |
; size |
width dw ? |
height dw ? |
ends |
127,7 → 127,8 |
mov ebx,[ebp+SKIN_HEADER.bitmaps] |
add ebx,skin_data |
.lp1: cmp dword[ebx],0 |
.lp1: |
cmp dword[ebx], 0 |
je .end_bitmaps |
movzx eax,[ebx+SKIN_BITMAPS.kind] |
movzx ecx,[ebx+SKIN_BITMAPS.type] |
138,7 → 139,8 |
or ecx,ecx |
jnz @f |
mov edx,skin_inactive.left.data |
@@: jmp .next_bitmap |
@@: |
jmp .next_bitmap |
.not_left: |
dec eax |
jnz .not_oper |
150,7 → 152,8 |
or ecx,ecx |
jnz @f |
mov edx,skin_inactive.oper.data |
@@: jmp .next_bitmap |
@@: |
jmp .next_bitmap |
.not_oper: |
dec eax |
jnz .not_base |
160,7 → 163,8 |
jnz @f |
mov eax,[skin_inactive.left.width] |
mov edx,skin_inactive.base.data |
@@: jmp .next_bitmap |
@@: |
jmp .next_bitmap |
.not_base: |
add ebx,8 |
jmp .lp1 |
178,7 → 182,8 |
mov ebx,[ebp+SKIN_HEADER.buttons] |
add ebx,skin_data |
.lp2: cmp dword[ebx],0 |
.lp2: |
cmp dword[ebx], 0 |
je .end_buttons |
mov eax,[ebx+SKIN_BUTTONS.type] |
dec eax |
213,7 → 218,8 |
or ebx,ebx |
jz @f |
call sys_putimage.forced |
@@: ret |
@@: |
ret |
drawwindow_IV_caption: |
/kernel/branches/net/gui/window.inc |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
8,43 → 8,88 |
$Revision$ |
;============================================================================== |
;///// public functions /////////////////////////////////////////////////////// |
;============================================================================== |
macro FuncTable name, [label] |
window.BORDER_SIZE = 5 |
macro FuncTable name, table_name, [label] |
{ |
common |
align 4 |
\label name#.ftable dword |
\label name#.#table_name dword |
forward |
dd name#.#label |
common |
name#.sizeof.ftable = $ - name#.ftable |
name#.sizeof.#table_name = $ - name#.#table_name |
} |
iglobal |
FuncTable syscall_display_settings, \ |
00, 01, 02, 03, 04, 05, 06, 07, 08 |
endg |
uglobal |
common_colours rd 32 |
new_window_starting dd ? |
latest_window_touch dd ? |
latest_window_touch_delta dd ? |
old_window_pos BOX |
new_window_pos BOX |
draw_limits RECT |
bPressedMouseXY_W db ? |
do_resize db ? |
do_resize_from_corner db ? |
reposition db ? |
endg |
align 4 |
;------------------------------------------------------------------------------ |
syscall_draw_window: ;///// system function 0 ///////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
mov eax, edx |
shr eax, 24 |
and al, 0x0f |
cmp al, 5 |
jae .exit |
push eax |
inc [mouse_pause] |
call [_display.disable_mouse] |
call window._.sys_set_window |
call [_display.disable_mouse] |
pop eax |
or al, al |
jnz @f |
; type I - original style |
call drawwindow_I |
jmp window._.draw_window_caption.2 |
@@: |
dec al |
jnz @f |
; type II - only reserve area, no draw |
call sys_window_mouse |
dec [mouse_pause] |
call [draw_pointer] |
jmp .exit |
@@: |
dec al |
jnz @f |
; type III - new style |
call drawwindow_III |
jmp window._.draw_window_caption.2 |
; type IV & V - skinned window (resizable & not) |
@@: |
mov eax, [TASK_COUNT] |
movzx eax, word[WIN_POS + eax * 2] |
cmp eax, [CURRENT_TASK] |
setz al |
movzx eax, al |
push eax |
call drawwindow_IV |
jmp window._.draw_window_caption.2 |
.exit: |
ret |
align 4 |
;------------------------------------------------------------------------------ |
syscall_display_settings: ;///// system function 48 /////////////////////////// |
;------------------------------------------------------------------------------ |
;; Redraw screen: |
91,7 → 136,8 |
cmp ebx, .sizeof.ftable / 4 |
ja @f |
jmp [.ftable + ebx * 4] |
@@: ret |
@@: |
ret |
align 4 |
168,11 → 214,13 |
or eax, eax |
jge @f |
xor eax, eax |
@@: mov [screen_workarea.left], eax |
@@: |
mov [screen_workarea.left], eax |
cmp ebx, edi |
jle @f |
mov ebx, edi |
@@: mov [screen_workarea.right], ebx |
@@: |
mov [screen_workarea.right], ebx |
.check_horizontal: |
mov edi, [Screen_Max_Y] |
185,11 → 233,13 |
or eax, eax |
jge @f |
xor eax, eax |
@@: mov [screen_workarea.top], eax |
@@: |
mov [screen_workarea.top], eax |
cmp ebx, edi |
jle @f |
mov ebx, edi |
@@: mov [screen_workarea.bottom], ebx |
@@: |
mov [screen_workarea.bottom], ebx |
.check_if_redraw_needed: |
or esi, esi |
269,14 → 319,100 |
align 4 |
;------------------------------------------------------------------------------ |
syscall_move_window: ;///// system function 67 //////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
mov edi, [CURRENT_TASK] |
shl edi, 5 |
add edi, window_data |
test [edi + WDATA.fl_wdrawn], 1 |
jz .exit |
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED |
jnz .exit |
cmp ebx, -1 |
jne @f |
mov ebx, [edi + WDATA.box.left] |
@@: |
cmp ecx, -1 |
jne @f |
mov ecx, [edi + WDATA.box.top] |
@@: |
cmp edx, -1 |
jne @f |
mov edx, [edi + WDATA.box.width] |
@@: |
cmp esi, -1 |
jne @f |
mov esi, [edi + WDATA.box.height] |
@@: |
push esi edx ecx ebx |
mov eax, esp |
mov bl, [edi + WDATA.fl_wstate] |
call window._.set_window_box |
add esp, sizeof.BOX |
; NOTE: do we really need this? to be reworked |
; mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer |
; mov byte[MOUSE_BACKGROUND], 0 ; no mouse under |
; mov byte[MOUSE_DOWN], 0 ; react to mouse up/down |
; NOTE: do we really need this? to be reworked |
; call [draw_pointer] |
.exit: |
ret |
align 4 |
;------------------------------------------------------------------------------ |
syscall_window_settings: ;///// system function 71 ///////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
dec ebx ; subfunction #1 - set window caption |
jnz .exit_fail |
; NOTE: only window owner thread can set its caption, |
; so there's no parameter for PID/TID |
mov edi, [CURRENT_TASK] |
shl edi, 5 |
mov [edi * 8 + SLOT_BASE + APPDATA.wnd_caption], ecx |
or [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION |
call window._.draw_window_caption |
xor eax, eax ; eax = 0 (success) |
ret |
; .get_window_caption: |
; dec eax ; subfunction #2 - get window caption |
; jnz .exit_fail |
; not implemented yet |
.exit_fail: |
xor eax, eax |
inc eax ; eax = 1 (fail) |
ret |
align 4 |
;------------------------------------------------------------------------------ |
set_window_defaults: ;///////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
mov byte [window_data + 0x20 + WDATA.cl_titlebar + 3], 1 ; desktop is not movable |
push eax ecx |
xor eax, eax |
mov ecx, WIN_STACK |
@@: inc eax |
@@: |
inc eax |
add ecx, 2 |
; process no |
mov [ecx + 0x000], ax |
343,17 → 479,21 |
cmp eax, [esp + RECT.left] |
jae @f |
mov eax, [esp + RECT.left] |
@@: cmp ebx, [esp + RECT.top] |
@@: |
cmp ebx, [esp + RECT.top] |
jae @f |
mov ebx, [esp + RECT.top] |
@@: cmp ecx, [esp + RECT.right] |
@@: |
cmp ecx, [esp + RECT.right] |
jbe @f |
mov ecx, [esp + RECT.right] |
@@: cmp edx, [esp + RECT.bottom] |
@@: |
cmp edx, [esp + RECT.bottom] |
jbe @f |
mov edx, [esp + RECT.bottom] |
@@: push esi |
@@: |
push esi |
movzx esi, word[WIN_POS + esi * 2] |
call window._.set_screen |
pop esi |
378,7 → 518,7 |
;? <description> |
;------------------------------------------------------------------------------ |
mov ecx, [TASK_COUNT] |
mov edi, window_data + WDATA.sizeof * 2 |
mov edi, window_data + sizeof.WDATA * 2 |
call force_redraw_background |
dec ecx |
jle .exit |
397,7 → 537,8 |
sub eax, ebx |
jle @f |
mov [edi + WDATA.box.width], ebx |
@@: sub ebx, [edi + WDATA.box.width] |
@@: |
sub ebx, [edi + WDATA.box.width] |
mov [edi + WDATA.box.left], ebx |
.fix_vertical: |
410,7 → 551,8 |
sub eax, ebx |
jle @f |
mov [edi + WDATA.box.height], ebx |
@@: sub ebx, [edi + WDATA.box.height] |
@@: |
sub ebx, [edi + WDATA.box.height] |
mov [edi + WDATA.box.top], ebx |
jmp .fix_client_box |
429,9 → 571,9 |
mov [edi + WDATA.box.height], eax |
.fix_client_box: |
call set_window_clientbox |
call window._.set_window_clientbox |
add edi, WDATA.sizeof |
add edi, sizeof.WDATA |
loop .next_window |
.exit: |
439,97 → 581,25 |
align 4 |
;------------------------------------------------------------------------------ |
check_window_position: ;/////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Check if window is inside screen area |
;------------------------------------------------------------------------------ |
;> edi = pointer to WDATA |
;------------------------------------------------------------------------------ |
push eax ebx ecx edx esi |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
mov esi, [Screen_Max_X] |
cmp ecx, esi |
ja .fix_width |
.check_left: |
or eax, eax |
jl .fix_left_low |
add eax, ecx |
cmp eax, esi |
jg .fix_left_high |
.check_height: |
mov esi, [Screen_Max_Y] |
cmp edx, esi |
ja .fix_height |
.check_top: |
or ebx, ebx |
jl .fix_top_low |
add ebx, edx |
cmp ebx, esi |
jg .fix_top_high |
.exit: |
pop esi edx ecx ebx eax |
ret |
.fix_width: |
mov ecx, esi |
mov [edi + WDATA.box.width], esi |
jmp .check_left |
.fix_left_low: |
xor eax, eax |
mov [edi + WDATA.box.left], eax |
jmp .check_height |
.fix_left_high: |
mov eax, esi |
sub eax, ecx |
mov [edi + WDATA.box.left], eax |
jmp .check_height |
.fix_height: |
mov edx, esi |
mov [edi + WDATA.box.height], esi |
jmp .check_top |
.fix_top_low: |
xor ebx, ebx |
mov [edi + WDATA.box.top], ebx |
jmp .exit |
.fix_top_high: |
mov ebx, esi |
sub ebx, edx |
mov [edi + WDATA.box.top], ebx |
jmp .exit |
align 4 |
;------------------------------------------------------------------------------ |
sys_window_mouse: ;//////////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
push eax |
mov eax, [timer_ticks] |
cmp [new_window_starting], eax |
jb .exit |
mov byte[MOUSE_BACKGROUND], 0 |
mov byte[DONT_DRAW_MOUSE], 0 |
mov [new_window_starting], eax |
.exit: |
pop eax |
; NOTE: commented out since doesn't provide necessary functionality |
; anyway, to be reworked |
; push eax |
; |
; mov eax, [timer_ticks] |
; cmp [new_window_starting], eax |
; jb .exit |
; |
; mov byte[MOUSE_BACKGROUND], 0 |
; mov byte[DONT_DRAW_MOUSE], 0 |
; |
; mov [new_window_starting], eax |
; |
; .exit: |
; pop eax |
ret |
align 4 |
604,7 → 674,8 |
cmp ebx, eax |
jbe @f |
mov ebx, eax |
@@: push ebx |
@@: |
push ebx |
xor edi, edi |
623,7 → 694,8 |
jz @f |
sub ecx, 0x00040404 |
mov [esi + WDATA.cl_titlebar], ecx |
@@: and ecx, 0x00ffffff |
@@: |
and ecx, 0x00ffffff |
call [draw_line] |
inc edx |
cmp edx, [esp] |
702,7 → 774,8 |
cmp ebx, eax |
jb @f |
mov ebx, eax |
@@: push ebx |
@@: |
push ebx |
xor edi, edi |
719,10 → 792,12 |
test ecx, 0x40000000 |
jz @f |
add ecx, 0x00040404 |
@@: test ecx, 0x80000000 |
@@: |
test ecx, 0x80000000 |
jz @f |
sub ecx, 0x00040404 |
@@: mov [esi + WDATA.cl_titlebar], ecx |
@@: |
mov [esi + WDATA.cl_titlebar], ecx |
and ecx, 0x00ffffff |
call [draw_line] |
inc edx |
809,6 → 884,13 |
;------------------------------------------------------------------------------ |
;? Activate window, redrawing if necessary |
;------------------------------------------------------------------------------ |
push -1 |
mov eax, [TASK_COUNT] |
lea eax, [WIN_POS + eax * 2] |
cmp eax, esi |
pop eax |
je .exit |
; is it overlapped by another window now? |
push ecx |
call window._.check_window_draw |
841,15 → 923,20 |
; tell application to redraw itself |
mov [edi + WDATA.fl_redraw], 1 |
mov byte[MOUSE_DOWN], 0 |
ret |
xor eax, eax |
jmp .exit |
.do_not_draw: |
; no it's not, just activate the window |
call window._.window_activate |
xor eax, eax |
mov byte[MOUSE_BACKGROUND], al |
mov byte[DONT_DRAW_MOUSE], al |
.exit: |
mov byte[MOUSE_DOWN], 0 |
mov byte[MOUSE_BACKGROUND], 0 |
mov byte[DONT_DRAW_MOUSE], 0 |
inc eax |
ret |
align 4 |
924,7 → 1011,8 |
cmp eax, [TASK_COUNT] |
jz @f |
mov ebp, calculatescreen |
@@: mov eax, [edi + WDATA.box.left] |
@@: |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
940,16 → 1028,15 |
ret |
align 4 |
; TODO: remove this proc |
;------------------------------------------------------------------------------ |
checkwindows: ;//////////////////////////////////////////////////////////////// |
window_check_events: ;///////////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Check for user-initiated window operations |
;? <description> |
;------------------------------------------------------------------------------ |
pushad |
; do we have window minimize/restore request? |
cmp [window_minimize], 0 |
je .check_for_mouse_buttons_state |
je .exit |
; okay, minimize or restore top-most window and exit |
mov eax, [TASK_COUNT] |
958,443 → 1045,487 |
dec bl |
jnz @f |
call minimize_window |
jmp .check_for_mouse_buttons_state |
@@: call restore_minimized_window |
jmp .exit |
.check_for_mouse_buttons_state: |
; do we have any mouse buttons pressed? |
cmp byte[BTN_DOWN], 0 |
jne .mouse_buttons_pressed |
@@: |
call restore_minimized_window |
mov [bPressedMouseXY_W], 0 |
jmp .exit |
.exit: |
ret |
.mouse_buttons_pressed: |
; yes we do, iterate and ... |
mov esi, [TASK_COUNT] |
inc esi |
align 4 |
;------------------------------------------------------------------------------ |
sys_window_maximize_handler: ;///////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> esi = process slot |
;------------------------------------------------------------------------------ |
mov edi, esi |
shl edi, 5 |
add edi, window_data |
cmp [bPressedMouseXY_W], 1 |
ja .next_window |
inc [bPressedMouseXY_W] |
jnc .next_window |
push dword[MOUSE_X] |
pop dword[mx] |
; can window change its height? |
; only types 2 and 3 can be resized |
mov dl, [edi + WDATA.fl_wstyle] |
test dl, 2 |
jz .exit |
.next_window: |
cmp esi, 2 |
jb .exit |
; toggle normal/maximized window state |
mov bl, [edi + WDATA.fl_wstate] |
xor bl, WSTATE_MAXIMIZED |
dec esi |
; calculate and set appropriate window bounds |
test bl, WSTATE_MAXIMIZED |
jz .restore_size |
; is that window not minimized? |
movzx edi, word[WIN_POS + esi * 2] |
shl edi, 5 |
add edi, window_data |
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED |
jnz .next_window |
mov eax, [screen_workarea.left] |
mov ecx, [screen_workarea.top] |
push [screen_workarea.bottom] \ |
[screen_workarea.right] \ |
ecx \ |
eax |
sub [esp + BOX.width], eax |
sub [esp + BOX.height], ecx |
mov eax, esp |
jmp .set_box |
movzx eax, [mx] |
movzx ebx, [my] |
.restore_size: |
mov eax, esi |
shl eax, 8 |
add eax, SLOT_BASE + APPDATA.saved_box |
push [eax + BOX.height] \ |
[eax + BOX.width] \ |
[eax + BOX.top] \ |
[eax + BOX.left] |
mov eax, esp |
; is the cursor inside screen bounds of that window? |
mov ecx, [edi + WDATA.box.left] |
mov edx, [edi + WDATA.box.top] |
cmp eax, ecx |
jl .next_window |
cmp ebx, edx |
jl .next_window |
add ecx, [edi + WDATA.box.width] |
add edx, [edi + WDATA.box.height] |
cmp eax, ecx |
jge .next_window |
cmp ebx, edx |
jge .next_window |
.set_box: |
test bl, WSTATE_ROLLEDUP |
jz @f |
; is that a top-most (which means active) window? |
cmp esi, [TASK_COUNT] |
je .check_for_moving_or_resizing |
xchg eax, ecx |
call window._.get_rolledup_height |
mov [ecx + BOX.height], eax |
xchg eax, ecx |
; no it's not, did we just press mouse button down above it or was it |
; already pressed before? |
cmp [bPressedMouseXY_W], 1 |
ja .exit |
@@: |
call window._.set_window_box |
add esp, sizeof.BOX |
; okay, we just pressed the button, activate this window and exit |
lea esi, [WIN_POS + esi * 2] |
call waredraw |
jmp .exit |
.exit: |
ret |
.check_for_moving_or_resizing: |
; is that window movable? |
test byte[edi + WDATA.cl_titlebar + 3], 0x01 |
jnz .exit |
align 4 |
;------------------------------------------------------------------------------ |
sys_window_rollup_handler: ;/////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> esi = process slot |
;------------------------------------------------------------------------------ |
mov edx, esi |
shl edx, 8 |
add edx, SLOT_BASE |
; yes it is, is it rolled up? |
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP |
jnz .check_for_cursor_on_caption |
; toggle normal/rolled up window state |
mov bl, [edi + WDATA.fl_wstate] |
xor bl, WSTATE_ROLLEDUP |
; no it's not, can it be resized then? |
mov [do_resize_from_corner], 0 |
mov dl, [edi + WDATA.fl_wstyle] |
and dl, 0x0f |
cmp dl, 0x00 |
je .check_for_cursor_on_caption |
cmp dl, 0x01 |
je .check_for_cursor_on_caption |
cmp dl, 0x04 |
je .check_for_cursor_on_caption |
; calculate and set appropriate window bounds |
test bl, WSTATE_ROLLEDUP |
jz .restore_size |
; are we going to resize it? |
mov edx, [edi + WDATA.box.top] |
add edx, [edi + WDATA.box.height] |
sub edx, 6 |
cmp ebx, edx |
jl .check_for_cursor_on_caption |
call window._.get_rolledup_height |
push eax \ |
[edi + WDATA.box.width] \ |
[edi + WDATA.box.top] \ |
[edi + WDATA.box.left] |
mov eax, esp |
jmp .set_box |
; yes we do, remember that |
mov [do_resize_from_corner], 1 |
jmp .set_move_resize_flag |
.restore_size: |
test bl, WSTATE_MAXIMIZED |
jnz @f |
add esp, -sizeof.BOX |
lea eax, [edx + APPDATA.saved_box] |
jmp .set_box |
.check_for_cursor_on_caption: |
; is the cursor inside window titlebar? |
push eax |
call window._.get_titlebar_height |
add eax, [edi + WDATA.box.top] |
cmp ebx, eax |
pop eax |
jge .exit |
@@: |
mov eax, [screen_workarea.top] |
push [screen_workarea.bottom] \ |
[edi + WDATA.box.width] \ |
eax \ |
[edi + WDATA.box.left] |
sub [esp + BOX.height], eax |
mov eax, esp |
; calculate duration between two clicks |
mov ecx, [timer_ticks] |
mov edx, ecx |
sub edx, [latest_window_touch] |
mov [latest_window_touch], ecx |
mov [latest_window_touch_delta], edx |
.set_box: |
call window._.set_window_box |
add esp, sizeof.BOX |
.set_move_resize_flag: |
mov cl, [BTN_DOWN] |
mov [do_resize], cl |
ret |
mov ecx, [edi + WDATA.box.left] |
mov edx, [edi + WDATA.box.top] |
align 4 |
;------------------------------------------------------------------------------ |
sys_window_start_moving_handler: ;///////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> eax = old (original) window box |
;> esi = process slot |
;------------------------------------------------------------------------------ |
mov edi, eax |
call window._.draw_negative_box |
push ecx edx |
mov [draw_limits.left], ecx |
mov [draw_limits.top], edx |
add ecx, [edi + WDATA.box.width] |
add edx, [edi + WDATA.box.height] |
mov [draw_limits.right], ecx |
mov [draw_limits.bottom], edx |
pop edx ecx |
ret |
; calculate window-relative cursor coordinates |
sub eax, ecx |
sub ebx, edx |
align 4 |
;------------------------------------------------------------------------------ |
sys_window_end_moving_handler: ;/////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> eax = old (original) window box |
;> ebx = new (final) window box |
;> esi = process slot |
;------------------------------------------------------------------------------ |
mov edi, ebx |
call window._.end_moving__box |
push dword[MOUSE_X] |
pop dword[WIN_TEMP_XY] |
mov edi, esi |
shl edi, 5 |
add edi, window_data |
; save old window coordinates |
push eax |
mov eax, [edi + WDATA.box.left] |
mov [old_window_pos.left], eax |
mov [new_window_pos.left], eax |
mov eax, [edi + WDATA.box.top] |
mov [old_window_pos.top], eax |
mov [new_window_pos.top], eax |
mov eax, [edi + WDATA.box.width] |
mov [old_window_pos.width], eax |
mov [new_window_pos.width], eax |
mov eax, [edi + WDATA.box.height] |
mov [old_window_pos.height], eax |
mov [new_window_pos.height], eax |
pop eax |
mov eax, ebx |
mov bl, [edi + WDATA.fl_wstate] |
call window._.set_window_box |
ret |
; draw negative moving/sizing frame |
call window._.draw_window_frames |
align 4 |
;------------------------------------------------------------------------------ |
sys_window_moving_handler: ;/////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> eax = old (from previous call) window box |
;> ebx = new (current) window box |
;> esi = process_slot |
;------------------------------------------------------------------------------ |
mov edi, eax |
call window._.draw_negative_box |
mov edi, ebx |
call window._.draw_negative_box |
ret |
mov [reposition], 0 |
mov byte[MOUSE_DOWN], 1 |
;============================================================================== |
;///// private functions ////////////////////////////////////////////////////// |
;============================================================================== |
.next_mouse_state_check: |
; process OS events |
mov byte[DONT_DRAW_MOUSE], 1 |
call checkidle |
call checkVga_N13 |
mov byte[MOUSE_BACKGROUND], 0 |
call [draw_pointer] |
pushad |
call stack_handler |
popad |
iglobal |
FuncTable syscall_display_settings, ftable, \ |
00, 01, 02, 03, 04, 05, 06, 07, 08 |
; did cursor position change? |
mov esi, [WIN_TEMP_XY] |
cmp esi, [MOUSE_X] |
je .check_for_new_mouse_buttons_state |
align 4 |
window_topleft dd \ |
1, 21, \ ;type 0 |
0, 0, \ ;type 1 |
5, 20, \ ;type 2 |
5, ?, \ ;type 3 {set by skin} |
5, ? ;type 4 {set by skin} |
endg |
; yes it did, calculate window-relative cursor coordinates |
movzx ecx, word[MOUSE_X] |
movzx edx, word[MOUSE_Y] |
sub ecx, eax |
sub edx, ebx |
;uglobal |
; NOTE: commented out since doesn't provide necessary functionality anyway, |
; to be reworked |
; new_window_starting dd ? |
;endg |
align 4 |
;------------------------------------------------------------------------------ |
window._.invalidate_screen: ;////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> eax = old (original) window box |
;> ebx = new (final) window box |
;> edi = pointer to WDATA struct |
;------------------------------------------------------------------------------ |
push eax ebx |
; we're going to draw new frame, erasing the old one |
call window._.draw_window_frames |
; TODO: do we really need `draw_limits`? |
; Yes, they are used by background drawing code. |
mov ecx, [eax + BOX.left] |
mov edx, [ebx + BOX.left] |
cmp ecx, edx |
jle @f |
mov ecx, edx |
@@: |
mov [draw_limits.left], ecx |
mov ecx, [eax + BOX.left] |
add ecx, [eax + BOX.width] |
add edx, [ebx + BOX.width] |
cmp ecx, edx |
jae @f |
mov ecx, edx |
@@: |
mov [draw_limits.right], ecx |
mov ecx, [eax + BOX.top] |
mov edx, [ebx + BOX.top] |
cmp ecx, edx |
jle @f |
mov ecx, edx |
@@: |
mov [draw_limits.top], ecx |
mov ecx, [eax + BOX.top] |
add ecx, [eax + BOX.height] |
add edx, [ebx + BOX.height] |
cmp ecx, edx |
jae @f |
mov ecx, edx |
@@: |
mov [draw_limits.bottom], ecx |
; are we moving it right now? |
cmp [do_resize_from_corner], 0 |
jne .resize_window |
; recalculate screen buffer at old position |
push ebx |
mov edx, [eax + BOX.height] |
mov ecx, [eax + BOX.width] |
mov ebx, [eax + BOX.top] |
mov eax, [eax + BOX.left] |
add ecx, eax |
add edx, ebx |
call calculatescreen |
pop eax |
; yes we do, check if it's inside the screen area |
mov eax, [Screen_Max_X] |
mov ebx, [Screen_Max_Y] |
; recalculate screen buffer at new position |
mov edx, [eax + BOX.height] |
mov ecx, [eax + BOX.width] |
mov ebx, [eax + BOX.top] |
mov eax, [eax + BOX.left] |
add ecx, eax |
add edx, ebx |
call calculatescreen |
mov [new_window_pos.left], 0 |
or ecx, ecx |
jle .check_for_new_vert_cursor_pos |
mov [reposition], 1 |
sub eax, [new_window_pos.width] |
mov [new_window_pos.left], eax |
cmp ecx, eax |
jge .check_for_new_vert_cursor_pos |
mov [new_window_pos.left], ecx |
mov eax, edi |
call redrawscreen |
.check_for_new_vert_cursor_pos: |
mov [new_window_pos.top], 0 |
or edx, edx |
jle .draw_new_window_frame |
mov [reposition], 1 |
sub ebx, [new_window_pos.height] |
mov [new_window_pos.top], ebx |
cmp edx, ebx |
jge .draw_new_window_frame |
mov [new_window_pos.top], edx |
jmp .draw_new_window_frame |
; tell window to redraw itself |
mov [edi + WDATA.fl_redraw], 1 |
.resize_window: |
push eax ebx edx |
pop ebx eax |
ret |
mov edx, edi |
sub edx, window_data |
lea edx, [SLOT_BASE + edx * 8] |
align 4 |
;------------------------------------------------------------------------------ |
window._.set_window_box: ;///////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> eax = pointer to BOX struct |
;> bl = new window state flags |
;> edi = pointer to WDATA struct |
;------------------------------------------------------------------------------ |
push eax ebx esi |
movzx eax, word[MOUSE_X] |
cmp eax, [edi + WDATA.box.left] |
jb .fix_new_vert_size |
sub eax, [edi + WDATA.box.left] |
cmp eax, 32 |
jge @f |
mov eax, 32 |
@@: mov [new_window_pos.width], eax |
; don't do anything if the new box is identical to the old |
cmp bl, [edi + WDATA.fl_wstate] |
jnz @f |
mov esi, eax |
push edi |
if WDATA.box |
add edi, WDATA.box |
end if |
mov ecx, 4 |
repz cmpsd |
pop edi |
jz .exit |
@@: |
.fix_new_vert_size: |
call window._.get_rolledup_height |
mov ebx, eax |
movzx eax, word[MOUSE_Y] |
cmp eax, [edi + WDATA.box.top] |
jb .set_reposition_flag |
sub eax, [edi + WDATA.box.top] |
cmp eax, ebx |
jge @f |
add esp, -sizeof.BOX |
mov ebx, esp |
if WDATA.box |
lea esi, [edi + WDATA.box] |
else |
mov esi, edi ; optimization for WDATA.box = 0 |
end if |
xchg eax, esi |
mov ecx, sizeof.BOX |
call memmove |
xchg eax, esi |
xchg ebx, esi |
call memmove |
mov eax, ebx |
@@: mov [new_window_pos.height], eax |
mov ebx, esi |
.set_reposition_flag: |
mov [reposition], 1 |
call window._.check_window_position |
call window._.set_window_clientbox |
call window._.invalidate_screen |
pop edx ebx eax |
add esp, sizeof.BOX |
.draw_new_window_frame: |
pop ebx eax |
mov cl, [esp + 4] |
mov ch, cl |
xchg cl, [edi + WDATA.fl_wstate] |
; draw new window moving/sizing frame |
call window._.draw_window_frames |
or cl, ch |
test cl, WSTATE_MAXIMIZED |
jnz .exit |
mov esi, [MOUSE_X] |
mov [WIN_TEMP_XY], esi |
mov eax, edi |
sub eax, window_data |
shl eax, 3 |
add eax, SLOT_BASE |
.check_for_new_mouse_buttons_state: |
; did user release mouse button(s)? |
cmp byte[BTN_DOWN], 0 |
jne .next_mouse_state_check |
lea ebx, [edi + WDATA.box] |
xchg esp, ebx |
; yes he did, moving/sizing is over |
mov byte[DONT_DRAW_MOUSE], 1 |
mov cl, 0 |
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED |
jnz .check_other_actions |
pop [eax + APPDATA.saved_box.left] \ |
[eax + APPDATA.saved_box.top] \ |
[eax + APPDATA.saved_box.width] \ |
edx |
mov cl, [reposition] |
xchg esp, ebx |
; draw negative frame once again to hide it |
call window._.draw_window_frames |
test ch, WSTATE_ROLLEDUP |
jnz .exit |
; save new window bounds |
mov eax, [new_window_pos.left] |
mov [edi + WDATA.box.left], eax |
mov eax, [new_window_pos.top] |
mov [edi + WDATA.box.top], eax |
mov eax, [new_window_pos.width] |
mov [edi + WDATA.box.width], eax |
mov eax, [new_window_pos.height] |
mov [edi + WDATA.box.height], eax |
call set_window_clientbox |
mov [eax + APPDATA.saved_box.height], edx |
cmp cl, 1 |
jne .check_other_actions |
push esi edi ecx |
mov esi, edi |
mov ecx, 2 |
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP or WSTATE_MAXIMIZED |
jnz @f |
add ecx, 2 |
@@: sub edi, window_data |
shr edi, 5 |
shl edi, 8 |
add edi, SLOT_BASE + APPDATA.saved_box |
cld |
rep movsd |
pop ecx edi esi |
.exit: |
pop esi ebx eax |
ret |
.check_other_actions: |
mov [reposition], cl |
align 4 |
;------------------------------------------------------------------------------ |
window._.set_window_clientbox: ;/////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> edi = pointer to WDATA struct |
;------------------------------------------------------------------------------ |
push eax ecx edi |
pushad |
mov eax, [_skinh] |
mov [window_topleft + 8 * 3 + 4], eax |
mov [window_topleft + 8 * 4 + 4], eax |
mov dl, [edi + WDATA.fl_wstyle] |
and dl, 0x0f |
cmp dl, 0x00 |
je .check_if_window_fits_screen |
cmp dl, 0x01 |
je .check_if_window_fits_screen |
mov ecx, edi |
sub edi, window_data |
shl edi, 3 |
test [ecx + WDATA.fl_wstyle], WSTYLE_CLIENTRELATIVE |
jz .whole_window |
cmp cl, 1 |
je .no_window_sizing |
mov edx, edi |
sub edx, window_data |
shr edx, 5 |
shl edx, 8 |
add edx, SLOT_BASE |
movzx eax, [ecx + WDATA.fl_wstyle] |
and eax, 0x0F |
mov eax, [eax * 8 + window_topleft + 0] |
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax |
shl eax, 1 |
neg eax |
add eax, [ecx + WDATA.box.width] |
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax |
; did we right-click on titlebar? |
cmp [do_resize], 2 |
jne .check_maximization_request |
movzx eax, [ecx + WDATA.fl_wstyle] |
and eax, 0x0F |
push [eax * 8 + window_topleft + 0] |
mov eax, [eax * 8 + window_topleft + 4] |
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax |
neg eax |
sub eax, [esp] |
add eax, [ecx + WDATA.box.height] |
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax |
add esp, 4 |
jmp .exit |
; yes we did, toggle normal/rolled up window state |
xor [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP |
mov [reposition], 1 |
.whole_window: |
xor eax, eax |
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax |
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax |
mov eax, [ecx + WDATA.box.width] |
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax |
mov eax, [ecx + WDATA.box.height] |
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax |
; calculate and set appropriate window height |
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP |
jz @f |
call window._.get_rolledup_height |
jmp .set_new_window_height |
@@: mov eax, [edx + APPDATA.saved_box.height] |
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED |
jz .set_new_window_height |
mov eax, [screen_workarea.bottom] |
sub eax, [screen_workarea.top] |
.exit: |
pop edi ecx eax |
ret |
.set_new_window_height: |
mov [edi + WDATA.box.height], eax |
add eax, [edi + WDATA.box.top] |
cmp eax, [Screen_Max_Y] |
jbe @f |
mov eax, [Screen_Max_Y] |
sub eax, [edi + WDATA.box.height] |
mov [edi + WDATA.box.top], eax |
@@: call check_window_position |
call set_window_clientbox |
align 4 |
;------------------------------------------------------------------------------ |
window._.sys_set_window: ;///////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;< edx = pointer to WDATA struct |
;------------------------------------------------------------------------------ |
mov eax, [CURRENT_TASK] |
shl eax, 5 |
add eax, window_data |
.check_maximization_request: |
; can window change its height? |
push edx |
mov dl, [edi + WDATA.fl_wstyle] |
and dl, 0x0f |
cmp dl, 0x04 |
pop edx |
je .check_if_window_fits_screen |
; save window colors |
mov [eax + WDATA.cl_workarea], edx |
mov [eax + WDATA.cl_titlebar], esi |
mov [eax + WDATA.cl_frames], edi |
; was it really a maximize/restore request? |
cmp [do_resize], 1 |
jne .check_if_window_fits_screen |
cmp [do_resize_from_corner], 0 |
jne .check_if_window_fits_screen |
cmp [latest_window_touch_delta], 50 |
jg .check_if_window_fits_screen |
mov edi, eax |
; yes is was, toggle normal/maximized window state |
xor [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED |
mov [reposition], 1 |
; was it already defined before? |
test [edi + WDATA.fl_wdrawn], 1 |
jnz .set_client_box |
or [edi + WDATA.fl_wdrawn], 1 |
; calculate and set appropriate window bounds |
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED |
jz .restore_normal_window_size |
mov eax, [screen_workarea.left] |
mov [edi + WDATA.box.left], eax |
sub eax, [screen_workarea.right] |
neg eax |
; NOTE: commented out since doesn't provide necessary functionality |
; anyway, to be reworked |
; mov eax, [timer_ticks] ; [0xfdf0] |
; add eax, 100 |
; mov [new_window_starting], eax |
; no it wasn't, performing initial window definition |
movzx eax, bx |
mov [edi + WDATA.box.width], eax |
mov eax, [screen_workarea.top] |
mov [edi + WDATA.box.top], eax |
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP |
jnz .calculate_window_client_area |
sub eax, [screen_workarea.bottom] |
neg eax |
movzx eax, cx |
mov [edi + WDATA.box.height], eax |
jmp .calculate_window_client_area |
sar ebx, 16 |
sar ecx, 16 |
mov [edi + WDATA.box.left], ebx |
mov [edi + WDATA.box.top], ecx |
.restore_normal_window_size: |
push [edi + WDATA.box.height] |
push edi |
lea esi, [edx + APPDATA.saved_box] |
mov ecx, 4 |
cld |
rep movsd |
pop edi |
pop eax |
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP |
jz .calculate_window_client_area |
mov [edi + WDATA.box.height], eax |
call window._.check_window_position |
.calculate_window_client_area: |
call set_window_clientbox |
push ecx edi |
.check_if_window_fits_screen: |
; does window fit into screen area? |
mov eax, [edi + WDATA.box.top] |
add eax, [edi + WDATA.box.height] |
cmp eax, [Screen_Max_Y] |
jbe .no_window_sizing |
mov eax, [edi + WDATA.box.left] |
add eax, [edi + WDATA.box.width] |
cmp eax, [Screen_Max_X] |
jbe .no_window_sizing |
mov cl, [edi + WDATA.fl_wstyle] |
mov eax, [edi + WDATA.cl_frames] |
; no it doesn't, fix that |
mov eax, [Screen_Max_X] |
sub eax, [edi + WDATA.box.width] |
mov [edi + WDATA.box.left], eax |
mov eax, [Screen_Max_Y] |
sub eax, [edi + WDATA.box.height] |
mov [edi + WDATA.box.top], eax |
call set_window_clientbox |
sub edi, window_data |
shl edi, 3 |
add edi, SLOT_BASE |
.no_window_sizing: |
popad |
and cl, 0x0F |
cmp cl, 3 |
je @f |
cmp cl, 4 |
je @f |
; did somethins actually change its place? |
cmp [reposition], 0 |
je .reset_vars |
xor eax, eax |
mov byte[DONT_DRAW_MOUSE], 1 |
@@: |
mov [edi + APPDATA.wnd_caption], eax |
push eax ebx ecx edx |
mov esi, [esp] |
add edi, APPDATA.saved_box |
movsd |
movsd |
movsd |
movsd |
; recalculate screen buffer at new position |
pop edi ecx |
mov esi, [CURRENT_TASK] |
movzx esi, word[WIN_STACK + esi * 2] |
lea esi, [WIN_POS + esi * 2] |
call waredraw |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
1403,50 → 1534,98 |
add edx, ebx |
call calculatescreen |
; recalculate screen buffer at old position |
mov eax, [old_window_pos.left] |
mov ebx, [old_window_pos.top] |
mov ecx, [old_window_pos.width] |
mov edx, [old_window_pos.height] |
add ecx, eax |
add edx, ebx |
call calculatescreen |
mov byte[KEY_COUNT], 0 ; empty keyboard buffer |
mov byte[BTN_COUNT], 0 ; empty button buffer |
pop edx ecx ebx eax |
.set_client_box: |
; update window client box coordinates |
call window._.set_window_clientbox |
mov eax, edi |
call redrawscreen |
; reset window redraw flag and exit |
mov [edi + WDATA.fl_redraw], 0 |
mov edx, edi |
ret |
; tell window to redraw itself |
mov [edi + WDATA.fl_redraw], 1 |
align 4 |
;------------------------------------------------------------------------------ |
window._.check_window_position: ;////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Check if window is inside screen area |
;------------------------------------------------------------------------------ |
;> edi = pointer to WDATA |
;------------------------------------------------------------------------------ |
push eax ebx ecx edx esi |
; wait a bit for window to redraw itself |
mov ecx, 100 |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
.next_idle_cycle: |
mov byte[DONT_DRAW_MOUSE], 1 |
call checkidle |
cmp [edi + WDATA.fl_redraw], 0 |
jz .reset_vars |
loop .next_idle_cycle |
mov esi, [Screen_Max_X] |
cmp ecx, esi |
ja .fix_width_high |
.reset_vars: |
mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer |
mov byte[MOUSE_BACKGROUND], 0 ; no mouse under |
mov byte[MOUSE_DOWN], 0 ; react to mouse up/down |
.check_left: |
or eax, eax |
jl .fix_left_low |
add eax, ecx |
cmp eax, esi |
jg .fix_left_high |
.check_height: |
mov esi, [Screen_Max_Y] |
cmp edx, esi |
ja .fix_height_high |
.check_top: |
or ebx, ebx |
jl .fix_top_low |
add ebx, edx |
cmp ebx, esi |
jg .fix_top_high |
.exit: |
popad |
pop esi edx ecx ebx eax |
ret |
;============================================================================== |
;///// private functions ////////////////////////////////////////////////////// |
;============================================================================== |
.fix_width_high: |
mov ecx, esi |
mov [edi + WDATA.box.width], esi |
jmp .check_left |
.fix_left_low: |
xor eax, eax |
mov [edi + WDATA.box.left], eax |
jmp .check_height |
.fix_left_high: |
mov eax, esi |
sub eax, ecx |
mov [edi + WDATA.box.left], eax |
jmp .check_height |
.fix_height_high: |
mov edx, esi |
mov [edi + WDATA.box.height], esi |
jmp .check_top |
.fix_top_low: |
xor ebx, ebx |
mov [edi + WDATA.box.top], ebx |
jmp .exit |
.fix_top_high: |
mov ebx, esi |
sub ebx, edx |
mov [edi + WDATA.box.top], ebx |
jmp .exit |
align 4 |
;------------------------------------------------------------------------------ |
window._.get_titlebar_height: ;//////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> edi = pointer to WDATA |
;------------------------------------------------------------------------------ |
mov al, [edi + WDATA.fl_wstyle] |
1455,7 → 1634,8 |
jne @f |
mov eax, [_skinh] |
ret |
@@: mov eax, 21 |
@@: |
mov eax, 21 |
ret |
align 4 |
1462,6 → 1642,8 |
;------------------------------------------------------------------------------ |
window._.get_rolledup_height: ;//////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> |
;------------------------------------------------------------------------------ |
;> edi = pointer to WDATA |
;------------------------------------------------------------------------------ |
mov al, [edi + WDATA.fl_wstyle] |
1471,11 → 1653,13 |
mov eax, [_skinh] |
add eax, 3 |
ret |
@@: or al, al |
@@: |
or al, al |
jnz @f |
mov eax, 21 |
ret |
@@: mov eax, 21 + 2 |
@@: |
mov eax, 21 + 2 |
ret |
align 4 |
1622,7 → 1806,8 |
mov eax, esi |
mov [ebp], al |
; -- end body -- |
@@: inc ebp |
@@: |
inc ebp |
inc edx |
cmp edx, [ff_xsz] |
jb .ff_new_x |
1664,6 → 1849,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 |
1690,6 → 1878,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] |
1722,6 → 1917,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: ;////////////////////////////////////////////////// |
1732,9 → 1974,9 |
;------------------------------------------------------------------------------ |
mov cl, [edi + WDATA.fl_wstyle] |
and cl, 0x0f |
cmp cl, 0x03 |
cmp cl, 3 |
je .exit.redraw ; window type 3 |
cmp cl, 0x04 |
cmp cl, 4 |
je .exit.redraw ; window type 4 |
push eax ebx edx esi |
1743,8 → 1985,6 |
sub eax, window_data |
shr eax, 5 |
; esi = process number |
movzx eax, word[WIN_STACK + eax * 2] ; get value of the curr process |
lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400 |
1798,49 → 2038,180 |
align 4 |
;------------------------------------------------------------------------------ |
window._.draw_window_frames: ;///////////////////////////////////////////////// |
window._.draw_window_caption: ;//////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Draw negative window frames |
;? <description> |
;------------------------------------------------------------------------------ |
;> edi = pointer to WDATA |
;------------------------------------------------------------------------------ |
push eax |
cli |
inc [mouse_pause] |
call [_display.disable_mouse] |
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED |
jnz .exit |
mov eax, [new_window_pos.left] |
cmp eax, [edi + WDATA.box.left] |
jnz .draw |
mov eax, [new_window_pos.width] |
cmp eax, [edi + WDATA.box.width] |
jnz .draw |
mov eax, [new_window_pos.top] |
cmp eax, [edi + WDATA.box.top] |
jnz .draw |
mov eax, [new_window_pos.height] |
cmp eax, [edi + WDATA.box.height] |
jnz .draw |
xor [edi + WDATA.fl_wdrawn], 2 |
xor eax, eax |
mov edx, [TASK_COUNT] |
movzx edx, word[WIN_POS + edx * 2] |
cmp edx, [CURRENT_TASK] |
jne @f |
inc eax |
@@: |
mov edx, [CURRENT_TASK] |
shl edx, 5 |
add edx, window_data |
movzx ebx, [edx + WDATA.fl_wstyle] |
and bl, 0x0F |
cmp bl, 3 |
je .draw_caption_style_3 |
cmp bl, 4 |
je .draw_caption_style_3 |
.draw: |
push ebx esi |
mov eax, [new_window_pos.left - 2] |
mov ax, word[new_window_pos.left] |
add ax, word[new_window_pos.width] |
mov ebx, [new_window_pos.top - 2] |
mov bx, word[new_window_pos.top] |
add bx, word[new_window_pos.height] |
jmp .not_style_3 |
.draw_caption_style_3: |
push edx |
call drawwindow_IV_caption |
add esp, 4 |
jmp .2 |
.not_style_3: |
cmp bl, 2 |
jne .not_style_2 |
call drawwindow_III_caption |
jmp .2 |
.not_style_2: |
cmp bl, 0 |
jne .2 |
call drawwindow_I_caption |
.2: |
mov edi, [CURRENT_TASK] |
shl edi, 5 |
test [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION |
jz .exit |
mov edx, [edi * 8 + SLOT_BASE + APPDATA.wnd_caption] |
or edx, edx |
jz .exit |
movzx eax, [edi + window_data + WDATA.fl_wstyle] |
and al, 0x0F |
cmp al, 3 |
je .skinned |
cmp al, 4 |
je .skinned |
jmp .not_skinned |
.skinned: |
mov ebp, [edi + window_data + WDATA.box.left - 2] |
mov bp, word[edi + window_data + WDATA.box.top] |
movzx eax, word[edi + window_data + WDATA.box.width] |
sub ax, [_skinmargins.left] |
sub ax, [_skinmargins.right] |
push edx |
cwde |
cdq |
mov ebx, 6 |
idiv ebx |
pop edx |
or eax, eax |
js .exit |
mov esi, eax |
mov ebx, dword[_skinmargins.left - 2] |
mov bx, word[_skinh] |
sub bx, [_skinmargins.bottom] |
sub bx, [_skinmargins.top] |
sar bx, 1 |
adc bx, 0 |
add bx, [_skinmargins.top] |
add bx, -3 |
add ebx, ebp |
jmp .dodraw |
.not_skinned: |
cmp al, 1 |
je .exit |
mov ebp, [edi + window_data + WDATA.box.left - 2] |
mov bp, word[edi + window_data + WDATA.box.top] |
movzx eax, word[edi + window_data + WDATA.box.width] |
sub eax, 16 |
push edx |
cwde |
cdq |
mov ebx, 6 |
idiv ebx |
pop edx |
or eax, eax |
js .exit |
mov esi, eax |
mov ebx, 0x00080007 |
add ebx, ebp |
.dodraw: |
mov ecx, [common_colours + 16] |
or ecx, 0x80000000 |
xor edi, edi |
call dtext_asciiz_esi |
.exit: |
dec [mouse_pause] |
call [draw_pointer] |
ret |
align 4 |
;------------------------------------------------------------------------------ |
window._.draw_negative_box: ;////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? Draw negative box |
;------------------------------------------------------------------------------ |
;> 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] |
mov ebx, [edi + BOX.top - 2] |
mov bx, word[edi + BOX.top] |
add bx, word[edi + BOX.height] |
call draw_rectangle.forced |
pop esi ebx |
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 |
.exit: |
sti |
pop eax |
;------------------------------------------------------------------------------ |
window._.get_rect: ;///////////////////////////////////////////////////// |
;------------------------------------------------------------------------------ |
;? <description> void __fastcall get_window_rect(struct RECT* rc); |
;------------------------------------------------------------------------------ |
;> ecx = pointer to RECT |
;------------------------------------------------------------------------------ |
mov eax, [TASK_BASE] |
mov edx, [eax-twdw + WDATA.box.left] |
mov [ecx+RECT.left], edx |
add edx, [eax-twdw + WDATA.box.width] |
mov [ecx+RECT.right], edx |
mov edx, [eax-twdw + WDATA.box.top] |
mov [ecx+RECT.top], edx |
add edx, [eax-twdw + WDATA.box.height] |
mov [ecx+RECT.bottom], edx |
ret |
.forced: |
push eax |
cli |
jmp .draw |
/kernel/branches/net/hid/keyboard.inc |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
8,8 → 8,6 |
$Revision$ |
;// mike.dld [ |
VKEY_LSHIFT = 0000000000000001b |
VKEY_RSHIFT = 0000000000000010b |
VKEY_LCONTROL = 0000000000000100b |
51,28 → 49,32 |
dd hotkey_test4 |
hotkey_tests_num = 5 |
endg |
;--------------------------------------------------------------------- |
hotkey_test0: |
test al, al |
setz al |
ret |
;--------------------------------------------------------------------- |
hotkey_test1: |
test al, al |
setnp al |
ret |
;--------------------------------------------------------------------- |
hotkey_test2: |
cmp al, 3 |
setz al |
ret |
;--------------------------------------------------------------------- |
hotkey_test3: |
cmp al, 1 |
setz al |
ret |
;--------------------------------------------------------------------- |
hotkey_test4: |
cmp al, 2 |
setz al |
ret |
;--------------------------------------------------------------------- |
hotkey_do_test: |
push eax |
mov edx, [kb_state] |
83,6 → 85,7 |
and eax, 15 |
cmp al, hotkey_tests_num |
jae .fail |
xchg eax, edx |
and al, 3 |
call [hotkey_tests + edx*4] |
89,18 → 92,29 |
cmp al, 1 |
pop eax |
ret |
;-------------------------------------- |
.fail: |
stc |
pop eax |
ret |
;--------------------------------------------------------------------- |
align 4 |
set_keyboard_data: |
movzx eax, word[TASK_COUNT]; top window process |
movzx eax, word[WIN_POS+eax*2] |
shl eax, 8 |
mov al, [SLOT_BASE+eax+APPDATA.keyboard_mode] |
mov [keyboard_mode], al |
mov eax, ecx |
push ebx esi edi ebp |
call send_scancode |
pop ebp edi esi ebx |
ret |
;--------------------------------------------------------------------- |
align 4 |
irq1: |
; save_ring3_context |
; mov ax, os_data |
; mov ds, ax |
; mov es, ax |
movzx eax,word[TASK_COUNT] ; top window process |
movzx eax,word[WIN_POS+eax*2] |
shl eax,8 |
108,17 → 122,18 |
mov [keyboard_mode],al |
in al,0x60 |
;-------------------------------------- |
send_scancode: |
mov [keyboard_data],al |
; ch = scancode |
; cl = ext_code |
; bh = 0 - normal key |
; bh = 1 - modifier (Shift/Ctrl/Alt) |
; bh = 2 - extended code |
mov ch,al |
cmp al,0xE0 |
je @f |
cmp al,0xE1 |
jne .normal_code |
@@: |
125,100 → 140,148 |
mov bh, 2 |
mov [ext_code], al |
jmp .writekey |
;-------------------------------------- |
.normal_code: |
mov cl, 0 |
xchg cl, [ext_code] |
and al,0x7F |
mov bh, 1 |
@@: cmp al,0x2A |
@@: |
cmp al, 0x2A |
jne @f |
cmp cl,0xE0 |
je .writekey |
mov eax,VKEY_LSHIFT |
jmp .modifier |
@@: cmp al,0x36 |
;-------------------------------------- |
@@: |
cmp al, 0x36 |
jne @f |
cmp cl,0xE0 |
je .writekey |
mov eax,VKEY_RSHIFT |
jmp .modifier |
@@: cmp al,0x38 |
;-------------------------------------- |
@@: |
cmp al, 0x38 |
jne @f |
mov eax, VKEY_LALT |
test cl, cl |
jz .modifier |
mov al, VKEY_RALT |
jmp .modifier |
@@: cmp al,0x1D |
;-------------------------------------- |
@@: |
cmp al, 0x1D |
jne @f |
mov eax, VKEY_LCONTROL |
test cl, cl |
jz .modifier |
mov al, VKEY_RCONTROL |
cmp cl, 0xE0 |
jz .modifier |
mov [ext_code], cl |
jmp .writekey |
@@: cmp al,0x3A |
;-------------------------------------- |
@@: |
cmp al, 0x3A |
jne @f |
mov bl,4 |
mov eax,VKEY_CAPSLOCK |
jmp .no_key.xor |
@@: cmp al,0x45 |
;-------------------------------------- |
@@: |
cmp al, 0x45 |
jne @f |
test cl, cl |
jnz .writekey |
mov bl,2 |
mov eax,VKEY_NUMLOCK |
jmp .no_key.xor |
@@: cmp al,0x46 |
;-------------------------------------- |
@@: |
cmp al, 0x46 |
jne @f |
mov bl,1 |
mov eax,VKEY_SCRLOCK |
jmp .no_key.xor |
;-------------------------------------- |
@@: |
xor ebx, ebx |
test ch,ch |
js .writekey |
movzx eax,ch ; plain key |
mov bl,[keymap+eax] |
mov edx,[kb_state] |
test dl,VKEY_CONTROL ; ctrl alt del |
jz .noctrlaltdel |
test dl,VKEY_ALT |
jz .noctrlaltdel |
cmp ch,53h |
jne .noctrlaltdel |
mov [ctrl_alt_del],1 |
.noctrlaltdel: |
test dl,VKEY_CONTROL ; ctrl on ? |
jz @f |
sub bl,0x60 |
@@: test dl,VKEY_SHIFT ; shift on ? |
@@: |
test dl, VKEY_CAPSLOCK ; caps lock on ? |
jz .no_caps_lock |
test dl, VKEY_SHIFT ; shift on ? |
jz .keymap_shif |
jmp @f |
;-------------------------------------- |
.no_caps_lock: |
test dl, VKEY_SHIFT ; shift on ? |
jz @f |
.keymap_shif: |
mov bl,[keymap_shift+eax] |
@@: test dl,VKEY_ALT ; alt on ? |
@@: |
test dl, VKEY_ALT ; alt on ? |
jz @f |
mov bl,[keymap_alt+eax] |
@@: |
mov bh, 0 |
jmp .writekey |
;-------------------------------------- |
.modifier: |
test ch, ch |
js .modifier.up |
or [kb_state], eax |
jmp .writekey |
;-------------------------------------- |
.modifier.up: |
not eax |
and [kb_state], eax |
jmp .writekey |
;-------------------------------------- |
.no_key.xor: |
mov bh, 0 |
test ch, ch |
js .writekey |
xor [kb_state], eax |
xor [kb_lights], bl |
call set_lights |
.writekey: |
; test for system hotkeys |
movzx eax, ch |
225,6 → 288,7 |
cmp bh, 1 |
ja .nohotkey |
jb @f |
xor eax, eax |
@@: |
mov eax, [hotkey_scancodes + eax*4] |
231,12 → 295,15 |
.hotkey_loop: |
test eax, eax |
jz .nohotkey |
mov cl, 0 |
call hotkey_do_test |
jc .hotkey_cont |
mov cl, 2 |
call hotkey_do_test |
jc .hotkey_cont |
mov cl, 4 |
call hotkey_do_test |
jnc .hotkey_found |
243,6 → 310,7 |
.hotkey_cont: |
mov eax, [eax] |
jmp .hotkey_loop |
;-------------------------------------- |
.hotkey_found: |
mov eax, [eax+8] |
; put key in buffer for process in slot eax |
250,6 → 318,7 |
@@: |
cmp dword [edi], 0 |
jz .found_free |
add edi, 8 |
cmp edi, hotkey_buffer+120*8 |
jb @b |
260,6 → 329,7 |
movzx eax, ch |
cmp bh, 1 |
jnz @f |
xor eax, eax |
@@: |
mov [edi+4], ax |
266,37 → 336,40 |
mov eax, [kb_state] |
mov [edi+6], ax |
jmp .exit.irq1 |
;-------------------------------------- |
.nohotkey: |
cmp [keyboard_mode],0 ; return from keymap |
jne .scancode |
test bh, bh |
jnz .exit.irq1 |
test bl, bl |
jz .exit.irq1 |
;.........................Part1 Start.......Code by Rus, optimize by Ghost................................... |
test [kb_state], VKEY_NUMLOCK |
jz .dowrite |
cmp cl, 0xE0 |
jz .dowrite |
cmp ch, 55 |
jnz @f |
mov bl, 0x2A ;* |
jmp .dowrite |
;-------------------------------------- |
@@: |
cmp ch, 71 |
jb .dowrite |
cmp ch, 83 |
ja .dowrite |
;push eax |
movzx eax, ch |
mov bl, [numlock_map + eax - 71] |
;pop eax |
;.........................Part1 End................................................. |
jmp .dowrite |
;-------------------------------------- |
.scancode: |
mov bl, ch |
.dowrite: |
306,17 → 379,10 |
inc eax |
mov [KEY_COUNT],al |
mov [KEY_COUNT+eax],bl |
.exit.irq1: |
mov [check_idle_semaphore],5 |
; mov al,0x20 ; ready for next irq |
; out 0x20,al |
; restore_ring3_context |
; iret |
ret |
;--------------------------------------------------------------------- |
set_lights: |
mov al,0xED |
call kb_write |
323,9 → 389,7 |
mov al,[kb_lights] |
call kb_write |
ret |
;// mike.dld ] |
;..........................Part2 Start.......Code by Rus....................................... |
;--------------------------------------------------------------------- |
numlock_map: |
db 0x37 ;Num 7 |
db 0x38 ;Num 8 |
340,4 → 404,4 |
db 0x33 ;Num 3 |
db 0x30 ;Num 0 |
db 0x2E ;Num . |
;..........................Part2 End................................................ |
;--------------------------------------------------------------------- |
/kernel/branches/net/hid/mousedrv.inc |
---|
28,7 → 28,8 |
iglobal |
mouse_delay dd 10 |
mouse_speed_factor: dd 3 |
mouse_speed_factor: |
dd 3 |
mouse_timer_ticks dd 0 |
endg |
292,21 → 293,20 |
add ecx,eax |
add ecx, [_WinMapAddress] |
mov eax, [CURRENT_TASK] |
movzx ebx, byte [ecx] |
cmp eax,ebx |
cmp al, [ecx] |
je yes_mouse_disable |
movzx ebx, byte [ecx+16] |
cmp eax,ebx |
cmp al, [ecx+16] |
je yes_mouse_disable |
add ebx, 10 |
cmp ebx, [Screen_Max_Y] |
jae no_mouse_disable |
mov ebx,[Screen_Max_X] |
inc ebx |
imul ebx,10 |
add ecx,ebx |
movzx ebx, byte [ecx] |
cmp eax,ebx |
cmp al, [ecx] |
je yes_mouse_disable |
movzx ebx, byte [ecx+16] |
cmp eax,ebx |
cmp al, [ecx+16] |
je yes_mouse_disable |
jmp no_mouse_disable |
yes_mouse_disable: |
/kernel/branches/net/init.inc |
---|
139,14 → 139,10 |
dec [pg_data.kernel_tables-OS_BASE] |
mov [edx], eax |
add eax, 0x00400000 |
add edx, 4 |
mov eax, 0x400000+PG_SW |
mov ecx, [tmp_page_tabs] |
sub ecx, 0x400000 |
shr ecx, 12 ;ecx/=4096 |
jmp .map_low |
mov edi, [tmp_page_tabs] |
jmp .map_kernel_heap ; new kernel fits to the first 4Mb - nothing to do with ".map_low" |
.no_PSE: |
mov eax, PG_SW |
mov ecx, [tmp_page_tabs] |
159,6 → 155,7 |
dec ecx |
jnz @B |
.map_kernel_heap: |
mov ecx, [pg_data.kernel_tables-OS_BASE] |
shl ecx, 10 |
xor eax, eax |
170,7 → 167,6 |
mov edi, edx |
.map_kernel_tabs: |
stosd |
add eax, 0x1000 |
dec ecx |
270,7 → 266,6 |
add ebx, [pg_data.pagemap_size-OS_BASE] |
mov [page_end-OS_BASE], ebx |
mov [pg_data.pg_mutex-OS_BASE], 0 |
ret |
endp |
293,7 → 288,8 |
mov esi, edi |
xor eax, eax |
cld ; paranoia |
@@: lodsb |
@@: |
lodsb |
add ah, al |
loop @b |
jnz .pcibios_nxt2 ; control summ must be zero |
436,3 → 432,123 |
ret |
endp |
uglobal |
align 4 |
acpi_rsdp rd 1 |
acpi_rsdt rd 1 |
acpi_madt rd 1 |
acpi_dev_data rd 1 |
acpi_dev_size rd 1 |
acpi_rsdt_base rd 1 |
acpi_madt_base rd 1 |
acpi_lapic_base rd 1 |
acpi_ioapic_base rd 1 |
endg |
ACPI_HI_RSDP_WINDOW_START equ 0x000E0000 |
ACPI_HI_RSDP_WINDOW_END equ 0x00100000 |
ACPI_RSDP_CHECKSUM_LENGTH equ 20 |
ACPI_MADT_SIGN equ 0x43495041 |
acpi_locate: |
push ebx |
mov ebx, ACPI_HI_RSDP_WINDOW_START |
.check: |
cmp [ebx], dword 0x20445352 |
jne .next |
cmp [ebx+4], dword 0x20525450 |
jne .next |
mov edx, ebx |
mov ecx, ACPI_RSDP_CHECKSUM_LENGTH |
xor eax, eax |
.sum: |
add al, [edx] |
inc edx |
loop .sum |
test al, al |
jnz .next |
mov eax, ebx |
pop ebx |
ret |
.next: |
add ebx, 16 |
cmp ebx, ACPI_HI_RSDP_WINDOW_END |
jb .check |
pop ebx |
xor eax, eax |
ret |
align 4 |
rsdt_find: ;ecx= rsdt edx= SIG |
push ebx |
push esi |
lea ebx, [ecx+36] |
mov esi, [ecx+4] |
add esi, ecx |
.next: |
mov eax, [ebx] |
cmp [eax], edx |
je .done |
add ebx, 4 |
cmp ebx, esi |
jb .next |
xor eax, eax |
pop esi |
pop ebx |
ret |
.done: |
mov eax, [ebx] |
pop esi |
pop ebx |
ret |
align 4 |
check_acpi: |
call acpi_locate |
test eax, eax |
jz .done |
mov ecx, [eax+16] |
mov edx, ACPI_MADT_SIGN |
mov [acpi_rsdt_base-OS_BASE], ecx |
call rsdt_find |
test eax, eax |
jz .done |
mov [acpi_madt_base-OS_BASE], eax |
mov ecx, [eax+36] |
mov [acpi_lapic_base-OS_BASE], ecx |
lea edx, [eax+44] |
mov ecx, [eax+4] |
add ecx, eax |
.check: |
mov eax, [edx] |
cmp al, 1 |
je .ioapic |
.next: |
movzx eax, ah |
add edx, eax |
cmp edx, ecx |
jb .check |
.done: |
ret |
.ioapic: |
mov eax, [edx+4] |
mov [acpi_ioapic_base-OS_BASE], eax |
ret |
/kernel/branches/net/kernel.asm |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. |
;; PROGRAMMING: |
;; Ivan Poddubny |
;; Marat Zakiyanov (Mario79) |
19,6 → 19,17 |
;; SPraid (simba) |
;; Hidnplayr |
;; Alexey Teplov (<Lrz>) |
;; Rus |
;; Nable |
;; shurf |
;; Alver |
;; Maxis |
;; Galkov |
;; CleverMouse |
;; tsdima |
;; turbanoff |
;; Asper |
;; art_zh |
;; |
;; Data in this file was originally part of MenuetOS project which is |
;; distributed under the terms of GNU GPL. It is modified and redistributed as |
64,11 → 75,11 |
USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices |
; Enabling the next line will enable serial output console |
debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used |
;debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used |
include "proc32.inc" |
include "kglobals.inc" |
lang fix en |
include "lang.inc" |
include "const.inc" |
max_processes equ 255 |
161,17 → 172,20 |
mov al,255 ; mask all irqs |
out 0xa1,al |
out 0x21,al |
l.5: in al, 0x64 ; Enable A20 |
l.5: |
in al, 0x64 ; Enable A20 |
test al, 2 |
jnz l.5 |
mov al, 0xD1 |
out 0x64, al |
l.6: in al, 0x64 |
l.6: |
in al, 0x64 |
test al, 2 |
jnz l.6 |
mov al, 0xDF |
out 0x60, al |
l.7: in al, 0x64 |
l.7: |
in al, 0x64 |
test al, 2 |
jnz l.7 |
mov al, 0xFF |
216,29 → 230,27 |
mov fs,ax |
mov gs,ax |
mov ss,ax |
mov esp,0x3ec00 ; Set stack |
mov esp, 0x006CC00 ; Set stack |
; CLEAR 0x280000 - HEAP_BASE |
xor eax,eax |
mov edi,0x280000 |
mov ecx,(HEAP_BASE-OS_BASE-0x280000) / 4 |
mov edi, CLEAN_ZONE |
mov ecx, (HEAP_BASE-OS_BASE-CLEAN_ZONE) / 4 |
cld |
rep stosd |
mov edi,0x40000 |
mov ecx,(0x90000-0x40000)/4 |
rep stosd |
; CLEAR KERNEL UNDEFINED GLOBALS |
mov edi, endofcode-OS_BASE |
mov ecx, (uglobals_size/4)+4 |
mov ecx, 0x90000 |
sub ecx, edi |
shr ecx, 2 |
rep stosd |
; SAVE & CLEAR 0-0xffff |
xor esi, esi |
mov edi,0x2F0000 |
mov edi, (BOOT_VAR-OS_BASE) |
mov ecx,0x10000 / 4 |
rep movsd |
mov edi,0x1000 |
248,6 → 260,7 |
call test_cpu |
bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc |
call check_acpi |
call init_BIOS32 |
; MEMORY MODEL |
call mem_test |
311,6 → 324,12 |
mov eax, cr3 |
mov cr3, eax ; flush TLB |
mov ecx, pg_data.mutex |
call mutex_init |
mov ecx, disk_list_mutex |
call mutex_init |
; SAVE REAL MODE VARIABLES |
mov ax, [BOOT_VAR + 0x9031] |
mov [IDEContrRegsBaseAddr], ax |
551,11 → 570,6 |
mov [srv.fd], eax |
mov [srv.bk], eax |
mov edi, irq_tab |
xor eax, eax |
mov ecx, 16 |
rep stosd |
;Set base of graphic segment to linear address of LFB |
mov eax,[LFBAddress] ; set for gs |
mov [graph_data_l+2],ax |
585,29 → 599,34 |
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f |
call rerouteirqs |
call init_irqs |
call PIC_init |
; Initialize system V86 machine |
call init_sys_v86 |
; TIMER SET TO 1/100 S |
; Initialize system timer (IRQ0) |
call PIT_init |
mov al,0x34 ; set to 100Hz |
out 0x43,al |
mov al,0x9b ; lsb 1193180 / 1193 |
out 0x40,al |
mov al,0x2e ; msb |
out 0x40,al |
; Try to Initialize APIC |
call APIC_init |
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15) |
; they are used: when partitions are scanned, hd_read relies on timer |
; Also enable IRQ2, because in some configurations |
; IRQs from slave controller are not delivered until IRQ2 on master is enabled |
mov al, 0xFA |
out 0x21, al |
mov al, 0x3F |
out 0xA1, al |
call unmask_timer |
stdcall enable_irq, 2 ; @#$%! PIC |
stdcall enable_irq, 6 ; FDD |
stdcall enable_irq, 13 ; co-processor |
stdcall enable_irq, 14 |
stdcall enable_irq, 15 |
; Enable interrupts in IDE controller |
mov al, 0 |
mov dx, 0x3F6 |
out dx, al |
mov dl, 0x76 |
out dx, al |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'detect/disks.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
614,22 → 633,19 |
call Parser_params |
if ~ defined extended_primary_loader |
; ramdisk image should be loaded by extended primary loader if it exists |
; READ RAMDISK IMAGE FROM HD |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'boot/rdload.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
end if |
; mov [dma_hdd],1 |
; CALCULATE FAT CHAIN FOR RAMDISK |
call calculatefatchain |
; LOAD VMODE DRIVER |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'vmodeld.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
if 0 |
mov ax,[OS_BASE+0x10000+bx_from_load] |
cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba} |
649,12 → 665,23 |
mov esi,boot_fonts |
call boot_log |
; Display APIC status |
mov esi, boot_APIC_found |
cmp [irq_mode], IRQ_APIC |
je @f |
mov esi, boot_APIC_nfound |
@@: |
; PRINT AMOUNT OF MEMORY |
mov esi, boot_memdetect |
call boot_log |
movzx ecx, word [boot_y] |
or ecx, (10+29*6) shl 16 ; "Determining amount of memory" |
if lang eq ru |
or ecx, (10+30*6) shl 16 |
else |
or ecx, (10+29*6) shl 16 |
end if |
sub ecx, 10 |
mov edx, 0xFFFFFF |
mov ebx, [MEM_AMOUNT] |
693,12 → 720,6 |
call boot_log |
call reserve_irqs_ports |
; SET PORTS FOR IRQ HANDLERS |
mov esi,boot_setrports |
call boot_log |
;call setirqreadports |
; SET UP OS TASK |
mov esi,boot_setostask |
779,7 → 800,11 |
mov ebx, edx |
movzx ecx, word [boot_y] |
add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is ' |
if lang eq ru |
add ecx, (10+19*6) shl 16 - 10 ; 'Determining amount of memory' |
else |
add ecx, (10+17*6) shl 16 - 10 ; 'Determining amount of memory' |
end if |
mov edx, 0xFFFFFF |
xor edi,edi |
mov eax, 0x00040000 |
790,17 → 815,6 |
call set_variables |
; SET MOUSE |
;call detect_devices |
stdcall load_driver, szPS2MDriver |
; stdcall load_driver, szCOM_MDriver |
mov esi,boot_setmouse |
call boot_log |
call setmouse |
; STACK AND FDC |
call stack_init |
838,21 → 852,23 |
stdcall map_page,tss._io_map_1,\ |
[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP |
mov ax, [OS_BASE+0x10000+bx_from_load] |
; 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 |
885,7 → 901,7 |
and al,00000010b |
loopnz @b |
; mov al, 0xED ; svetodiody - only for testing! |
; mov al, 0xED ; Keyboard LEDs - only for testing! |
; call kb_write |
; call kb_read |
; mov al, 111b |
901,8 → 917,17 |
;// mike.dld [ |
call set_lights |
;// mike.dld ] |
stdcall attach_int_handler, 1, irq1, 0 |
; SET MOUSE |
stdcall load_driver, szPS2MDriver |
; stdcall load_driver, szCOM_MDriver |
mov esi, boot_setmouse |
call boot_log |
call setmouse |
; Setup serial output console (if enabled) |
if defined debug_com_base |
946,39 → 971,16 |
; START MULTITASKING |
; A 'All set - press ESC to start' messages if need |
if preboot_blogesc |
mov esi, boot_tasking |
call boot_log |
.bll1: in al, 0x60 ; wait for ESC key press |
.bll1: |
in al, 0x60 ; wait for ESC key press |
cmp al, 129 |
jne .bll1 |
end if |
; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled |
; UNMASK ALL IRQ'S |
mov esi,boot_allirqs |
call boot_log |
cli ;guarantee forbidance of interrupts. |
mov al,0 ; unmask all irq's |
out 0xA1,al |
out 0x21,al |
mov ecx,32 |
ready_for_irqs: |
mov al,0x20 ; ready for irqs |
out 0x20,al |
out 0xa0,al |
loop ready_for_irqs ; flush the queue |
stdcall attach_int_handler, dword 1, irq1, dword 0 |
; mov [dma_hdd],1 |
cmp [IDEContrRegsBaseAddr], 0 |
setnz [dma_hdd] |
mov [timer_ticks_enable],1 ; for cd driver |
988,7 → 990,6 |
jmp osloop |
; jmp $ ; wait here for timer to take control |
; Fly :) |
1023,9 → 1024,8 |
align 32 |
osloop: |
call [draw_pointer] |
call check_buttons |
call checkwindows |
; call check_window_move_request |
call window_check_events |
call mouse_check_events |
call checkmisc |
call checkVga_N13 |
call stack_handler |
1032,6 → 1032,7 |
call checkidle |
call check_fdd_motor_status |
call check_ATAPI_device_event |
call check_timers |
jmp osloop |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
1089,59 → 1090,32 |
reserve_irqs_ports: |
push eax |
xor eax,eax |
inc eax |
mov byte [irq_owner+4*0],al ;1 ; timer |
;mov [irq_owner+4*1], 1 ; keyboard |
mov byte [irq_owner+4*6],al ;1 ; floppy diskette |
mov byte [irq_owner+4*13],al ;1 ; math co-pros |
mov byte [irq_owner+4*14],al ;1 ; ide I |
mov byte [irq_owner+4*15],al ;1 ; ide II |
pop eax |
; RESERVE PORTS |
push 4 |
pop dword [RESERVED_PORTS] ;,edi |
mov eax, RESERVED_PORTS |
mov ecx, 1 |
push 1 |
pop dword [RESERVED_PORTS+16+0] ;,dword 1 |
and dword [RESERVED_PORTS+16+4],0 ;,dword 0x0 |
mov dword [RESERVED_PORTS+16+8],0x2d ;,dword 0x2d |
mov [eax], dword 4 |
push 1 |
pop dword [RESERVED_PORTS+32+0] ;,dword 1 |
push 0x30 |
pop dword [RESERVED_PORTS+32+4] ;,dword 0x30 |
push 0x4d |
pop dword [RESERVED_PORTS+32+8] ;,dword 0x4d |
mov [eax+16], ecx |
mov [eax+16+4], dword 0 |
mov [eax+16+4], dword 0x2D |
push 1 |
pop dword [RESERVED_PORTS+48+0] ;,dword 1 |
push 0x50 |
pop dword [RESERVED_PORTS+48+4] ;,dword 0x50 |
mov dword [RESERVED_PORTS+48+8],0xdf ;,dword 0xdf |
mov [eax+32], ecx |
mov [eax+32+4], dword 0x30 |
mov [eax+32+8], dword 0x4D |
push 1 |
pop dword [RESERVED_PORTS+64+0] ;,dword 1 |
mov [eax+48], ecx |
mov [eax+48+4], dword 0x50 |
mov [eax+28+8], dword 0xDF |
mov dword [RESERVED_PORTS+64+4],0xe5 ;,dword 0xe5 |
mov dword [RESERVED_PORTS+64+8],0xff ;,dword 0xff |
mov [eax+64], ecx |
mov [eax+64+4], dword 0xE5 |
mov [eax+64+8], dword 0xFF |
ret |
setirqreadports: |
mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte |
and dword [irq12read+4],0 ; end of port list |
; mov [irq12read+4],dword 0 ; end of port list |
;mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte |
;mov [irq04read+4],dword 0 ; end of port list |
;mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte |
;mov [irq03read+4],dword 0 ; end of port list |
ret |
iglobal |
process_number dd 0x1 |
endg |
1148,8 → 1122,9 |
set_variables: |
mov ecx,0x100 ; flush port 0x60 |
.fl60: in al,0x60 |
mov ecx, 0x16 ; flush port 0x60 |
.fl60: |
in al, 0x60 |
loop .fl60 |
push eax |
1617,15 → 1592,10 |
no_set_lba_read: |
; cmp eax,12 ; ENABLE PCI ACCESS |
dec ebx |
jnz no_set_pci_access |
jnz sys_setup_err |
mov [pci_access_enabled],ecx |
ret |
no_set_pci_access: |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'vmodeint.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
sys_setup_err: |
or [esp+32],dword -1 |
ret |
1954,7 → 1924,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 |
1979,7 → 1949,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 |
1987,8 → 1957,7 |
jmp dword [sys_system_table + ebx*4] |
@@: |
ret |
;------------------------------------------------------------------------------ |
sysfn_shutdown: ; 18.9 = system shutdown |
cmp ecx,1 |
jl exit_for_anyone |
2003,9 → 1972,10 |
exit_for_anyone: |
ret |
uglobal |
shutdown_processes: dd 0x0 |
shutdown_processes: |
dd 0x0 |
endg |
;------------------------------------------------------------------------------ |
sysfn_terminate: ; 18.2 = TERMINATE |
cmp ecx,2 |
jb noprocessterminate |
2029,7 → 1999,7 |
noatsc: |
noprocessterminate: |
ret |
;------------------------------------------------------------------------------ |
sysfn_terminate2: |
;lock application_table_status mutex |
.table_status: |
2056,7 → 2026,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 |
2077,21 → 2074,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] |
2098,7 → 2096,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 |
2113,10 → 2111,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 |
2141,18 → 2140,18 |
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,ebx |
mov edi, ecx |
mov esi,version_inf |
mov ecx,version_end-version_inf |
rep movsb |
ret |
;------------------------------------------------------------------------------ |
sysfn_waitretrace: ; 18.14 = sys wait retrace |
;wait retrace functions |
sys_wait_retrace: |
2163,7 → 2162,7 |
jz WaitRetrace_loop |
and [esp+32],dword 0 |
ret |
;------------------------------------------------------------------------------ |
align 4 |
sysfn_centermouse: ; 18.15 = mouse centered |
; removed here by <Lrz> |
2182,8 → 2181,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 |
2215,10 → 2214,12 |
; cmp ecx,4 ; set mouse pointer position |
dec ecx |
jnz .set_mouse_button |
mov [MOUSE_Y],dx ;y |
ror edx,16 |
mov [MOUSE_X],dx ;x |
cmp dx, word[Screen_Max_Y] |
ja .end |
rol edx,16 |
cmp dx, word[Screen_Max_X] |
ja .end |
mov [MOUSE_X], edx |
ret |
.set_mouse_button: |
; cmp ecx,5 ; set mouse button features |
2228,7 → 2229,7 |
mov [mouse_active],1 |
.end: |
ret |
;------------------------------------------------------------------------------ |
sysfn_getfreemem: |
mov eax, [pg_data.pages_free] |
shl eax, 2 |
2288,18 → 2289,18 |
sound_flag db 0 |
endg |
UID_NONE=0 |
UID_MENUETOS=1 ;official |
UID_KOLIBRI=2 ;russian |
iglobal |
version_inf: |
db 0,7,7,0 ; version 0.7.7.0 |
db UID_KOLIBRI |
db 0 |
dd __REV__ |
version_end: |
endg |
UID_NONE=0 |
UID_MENUETOS=1 ;official |
UID_KOLIBRI=2 ;russian |
sys_cachetodiskette: |
cmp ebx, 1 |
jne .no_floppy_a_save |
2425,8 → 2426,8 |
;draw_background_temp: |
; mov [bgrchanged],1 ;0 |
mov [background_defined], 1 |
mov byte[BACKGROUND_CHANGED], 1 |
call force_redraw_background |
mov [REDRAW_BACKGROUND], byte 2 |
nosb31: |
ret |
nosb3: |
2546,8 → 2547,8 |
ret |
force_redraw_background: |
and [draw_data+32 + RECT.left],dword 0 |
and [draw_data+32 + RECT.top],dword 0 |
and [draw_data+32 + RECT.left], 0 |
and [draw_data+32 + RECT.top], 0 |
push eax ebx |
mov eax,[Screen_Max_X] |
mov ebx,[Screen_Max_Y] |
2554,7 → 2555,7 |
mov [draw_data+32 + RECT.right],eax |
mov [draw_data+32 + RECT.bottom],ebx |
pop ebx eax |
mov byte [REDRAW_BACKGROUND], 1 |
inc byte[REDRAW_BACKGROUND] |
ret |
align 4 |
2663,11 → 2664,7 |
test eax, eax |
jz .exit |
mov eax, [BTN_BUFF] |
shl eax, 8 |
; // Alver 22.06.2008 // { |
mov al, byte [btn_down_determ] |
and al,0xFE ; delete left button bit |
; } \\ Alver \\ |
mov [BTN_COUNT], byte 0 |
mov [esp + 32], eax |
.exit: |
2759,6 → 2756,10 |
mov al, [ecx+window_data+WDATA.fl_wstate] |
stosb |
; Event mask (+71) |
mov EAX, dword [ECX+CURRENT_TASK+TASKDATA.event_mask] |
stosd |
pop esi |
pop edi |
2773,7 → 2774,8 |
sys_clock: |
cli |
; Mikhail Lisovin xx Jan 2005 |
@@: mov al, 10 |
@@: |
mov al, 10 |
out 0x70, al |
in al, 0x71 |
test al, al |
2810,7 → 2812,8 |
sys_date: |
cli |
@@: mov al, 10 |
@@: |
mov al, 10 |
out 0x70, al |
in al, 0x71 |
test al, al |
2891,488 → 2894,9 |
mov eax, [Screen_Max_Y] |
mov [edx + RECT.bottom], eax |
mov edi, [TASK_BASE] |
or [edi - twdw + WDATA.fl_wdrawn], 1 ; no new position & buttons from app |
call sys_window_mouse |
ret |
srl1: |
ret |
sys_drawwindow: |
mov eax,edx |
shr eax,16+8 |
and eax,15 |
; cmp eax,0 ; type I - original style |
jne nosyswI |
inc [mouse_pause] |
call [_display.disable_mouse] |
call sys_set_window |
call [_display.disable_mouse] |
call drawwindow_I |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswI: |
cmp al,1 ; type II - only reserve area, no draw |
jne nosyswII |
inc [mouse_pause] |
call [_display.disable_mouse] |
call sys_set_window |
call [_display.disable_mouse] |
call sys_window_mouse |
dec [mouse_pause] |
call [draw_pointer] |
ret |
nosyswII: |
cmp al,2 ; type III - new style |
jne nosyswIII |
inc [mouse_pause] |
call [_display.disable_mouse] |
call sys_set_window |
call [_display.disable_mouse] |
call drawwindow_III |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswIII: |
cmp al,3 ; type IV - skinned window |
je draw_skin_window |
cmp al,4 ; type V - skinned window not sized! {not_sized_skin_window} |
jne nosyswV |
draw_skin_window: |
inc [mouse_pause] |
call [_display.disable_mouse] |
call sys_set_window |
call [_display.disable_mouse] |
mov eax, [TASK_COUNT] |
movzx eax, word [WIN_POS + eax*2] |
cmp eax, [CURRENT_TASK] |
setz al |
movzx eax, al |
push eax |
call drawwindow_IV |
;dec [mouse_pause] |
;call [draw_pointer] |
;ret |
jmp draw_window_caption.2 |
nosyswV: |
ret |
draw_window_caption: |
inc [mouse_pause] |
call [_display.disable_mouse] |
xor eax,eax |
mov edx,[TASK_COUNT] |
movzx edx,word[WIN_POS+edx*2] |
cmp edx,[CURRENT_TASK] |
jne @f |
inc eax |
@@: mov edx,[CURRENT_TASK] |
shl edx,5 |
add edx,window_data |
movzx ebx,[edx+WDATA.fl_wstyle] |
and bl,0x0F |
cmp bl,3 |
je .draw_caption_style_3 ;{for 3 and 4 style write caption} |
cmp bl,4 |
je .draw_caption_style_3 |
jmp .not_style_3 |
.draw_caption_style_3: |
push edx |
call drawwindow_IV_caption |
add esp,4 |
jmp .2 |
.not_style_3: |
cmp bl,2 |
jne .not_style_2 |
call drawwindow_III_caption |
jmp .2 |
.not_style_2: |
cmp bl,0 |
jne .2 |
call drawwindow_I_caption |
;-------------------------------------------------------------- |
.2: ;jmp @f |
mov edi,[CURRENT_TASK] |
shl edi,5 |
test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION |
jz @f |
mov edx,[edi*8+SLOT_BASE+APPDATA.wnd_caption] |
or edx,edx |
jz @f |
movzx eax,[edi+window_data+WDATA.fl_wstyle] |
and al,0x0F |
cmp al,3 |
je .skinned |
cmp al,4 |
je .skinned |
jmp .not_skinned |
.skinned: |
mov ebp,[edi+window_data+WDATA.box.left-2] |
mov bp,word[edi+window_data+WDATA.box.top] |
movzx eax,word[edi+window_data+WDATA.box.width] |
sub ax,[_skinmargins.left] |
sub ax,[_skinmargins.right] |
push edx |
cwde |
cdq |
mov ebx,6 |
idiv ebx |
pop edx |
or eax,eax |
js @f |
mov esi,eax |
mov ebx,dword[_skinmargins.left-2] |
mov bx,word[_skinh] |
sub bx,[_skinmargins.bottom] |
sub bx,[_skinmargins.top] |
sar bx,1 |
adc bx,0 |
add bx,[_skinmargins.top] |
add bx,-3 |
add ebx,ebp |
jmp .dodraw |
.not_skinned: |
cmp al,1 |
je @f |
mov ebp,[edi+window_data+WDATA.box.left-2] |
mov bp,word[edi+window_data+WDATA.box.top] |
movzx eax,word[edi+window_data+WDATA.box.width] |
sub eax,16 |
push edx |
cwde |
cdq |
mov ebx,6 |
idiv ebx |
pop edx |
or eax,eax |
js @f |
mov esi,eax |
mov ebx,0x00080007 |
add ebx,ebp |
.dodraw: |
mov ecx,[common_colours+16];0x00FFFFFF |
or ecx, 0x80000000 |
xor edi,edi |
; // Alver 22.06.2008 // { |
; call dtext |
call dtext_asciiz_esi |
; } \\ Alver \\ |
@@: |
;-------------------------------------------------------------- |
dec [mouse_pause] |
call [draw_pointer] |
ret |
iglobal |
align 4 |
window_topleft dd \ |
1, 21,\ ;type 0 |
0, 0,\ ;type 1 |
5, 20,\ ;type 2 |
5, ?,\ ;type 3 {set by skin} |
5, ? ;type 4 {set by skin} |
endg |
set_window_clientbox: |
push eax ecx edi |
mov eax,[_skinh] |
mov [window_topleft+4*7],eax |
mov [window_topleft+4*9],eax |
mov ecx,edi |
sub edi,window_data |
shl edi,3 |
test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE |
jz @f |
movzx eax,[ecx+WDATA.fl_wstyle] |
and eax,0x0F |
mov eax,[eax*8+window_topleft+0] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax |
shl eax,1 |
neg eax |
add eax,[ecx+WDATA.box.width] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax |
movzx eax,[ecx+WDATA.fl_wstyle] |
and eax,0x0F |
push [eax*8+window_topleft+0] |
mov eax,[eax*8+window_topleft+4] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax |
neg eax |
sub eax,[esp] |
add eax,[ecx+WDATA.box.height] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax |
add esp,4 |
pop edi ecx eax |
ret |
@@: |
xor eax,eax |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax |
mov eax,[ecx+WDATA.box.width] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax |
mov eax,[ecx+WDATA.box.height] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax |
pop edi ecx eax |
ret |
sys_set_window: |
mov eax,[CURRENT_TASK] |
shl eax,5 |
add eax,window_data |
; colors |
mov [eax+WDATA.cl_workarea],edx |
mov [eax+WDATA.cl_titlebar],esi |
mov [eax+WDATA.cl_frames],edi |
mov edi, eax |
; check flag (?) |
test [edi+WDATA.fl_wdrawn],1 |
jnz newd |
mov eax,[timer_ticks] ;[0xfdf0] |
add eax,100 |
mov [new_window_starting],eax |
movsx eax,bx |
mov [edi+WDATA.box.width],eax |
movsx eax,cx |
mov [edi+WDATA.box.height],eax |
sar ebx,16 |
sar ecx,16 |
mov [edi+WDATA.box.left],ebx |
mov [edi+WDATA.box.top],ecx |
call check_window_position |
push ecx esi edi ; save for window fullscreen/resize |
;mov esi,edi |
mov cl, [edi+WDATA.fl_wstyle] |
mov eax, [edi+WDATA.cl_frames] |
sub edi,window_data |
shl edi,3 |
add edi,SLOT_BASE |
and cl,0x0F |
mov [edi+APPDATA.wnd_caption],0 |
cmp cl,3 |
je set_APPDATA_wnd_caption |
cmp cl,4 ; {SPraid.simba} |
je set_APPDATA_wnd_caption |
jmp @f |
set_APPDATA_wnd_caption: |
mov [edi+APPDATA.wnd_caption],eax |
@@: mov esi,[esp+0] |
add edi, APPDATA.saved_box |
movsd |
movsd |
movsd |
movsd |
pop edi esi ecx |
mov esi, [CURRENT_TASK] |
movzx esi, word [WIN_STACK+esi*2] |
lea esi, [WIN_POS+esi*2] |
call waredraw |
;;; mov ebx, 1 |
;;; call delay_hs |
mov eax, [edi+WDATA.box.left] |
mov ebx, [edi+WDATA.box.top] |
mov ecx, [edi+WDATA.box.width] |
mov edx, [edi+WDATA.box.height] |
add ecx, eax |
add edx, ebx |
call calculatescreen |
mov [KEY_COUNT],byte 0 ; empty keyboard buffer |
mov [BTN_COUNT],byte 0 ; empty button buffer |
newd: |
call set_window_clientbox |
mov [edi+WDATA.fl_redraw],byte 0 ; no redraw |
mov edx,edi |
ret |
syscall_windowsettings: |
.set_window_caption: |
dec ebx ; subfunction #1 - set window caption |
jnz .exit_fail |
; NOTE: only window owner thread can set its caption, |
; so there's no parameter for PID/TID |
mov edi,[CURRENT_TASK] |
shl edi,5 |
; have to check if caption is within application memory limit |
; check is trivial, and if application resizes its memory, |
; caption still can become over bounds |
; diamond, 31.10.2006: check removed because with new memory manager |
; there can be valid data after APPDATA.mem_size bound |
; mov ecx,[edi*8+SLOT_BASE+APPDATA.mem_size] |
; add ecx,255 ; max caption length |
; cmp ebx,ecx |
; ja .exit_fail |
mov [edi*8+SLOT_BASE+APPDATA.wnd_caption],ecx |
or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION |
call draw_window_caption |
xor eax,eax ; eax = 0 (success) |
ret |
; .get_window_caption: |
; dec eax ; subfunction #2 - get window caption |
; jnz .exit_fail |
; not implemented yet |
.exit_fail: |
xor eax,eax |
inc eax ; eax = 1 (fail) |
ret |
sys_window_move: |
mov edi,[CURRENT_TASK] |
shl edi,5 |
add edi,window_data |
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED |
jnz .window_move_return |
push dword [edi + WDATA.box.left] ; save old coordinates |
push dword [edi + WDATA.box.top] |
push dword [edi + WDATA.box.width] |
push dword [edi + WDATA.box.height] |
cmp eax,-1 ; set new position and size |
je .no_x_reposition |
mov [edi + WDATA.box.left], eax |
.no_x_reposition: |
cmp ebx,-1 |
je .no_y_reposition |
mov [edi + WDATA.box.top], ebx |
.no_y_reposition: |
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP |
jnz .no_y_resizing |
cmp ecx,-1 |
je .no_x_resizing |
mov [edi + WDATA.box.width], ecx |
.no_x_resizing: |
cmp edx,-1 |
je .no_y_resizing |
mov [edi + WDATA.box.height], edx |
.no_y_resizing: |
call check_window_position |
call set_window_clientbox |
pushad ; save for window fullscreen/resize |
mov esi,edi |
sub edi,window_data |
shr edi,5 |
shl edi,8 |
add edi, SLOT_BASE + APPDATA.saved_box |
mov ecx,4 |
cld |
rep movsd |
popad |
pushad ; calculcate screen at new position |
mov eax, [edi + WDATA.box.left] |
mov ebx, [edi + WDATA.box.top] |
mov ecx, [edi + WDATA.box.width] |
mov edx, [edi + WDATA.box.height] |
add ecx,eax |
add edx,ebx |
call calculatescreen |
popad |
pop edx ; calculcate screen at old position |
pop ecx |
pop ebx |
pop eax |
add ecx,eax |
add edx,ebx |
mov [draw_limits.left],eax ; save for drawlimits |
mov [draw_limits.top],ebx |
mov [draw_limits.right],ecx |
mov [draw_limits.bottom],edx |
call calculatescreen |
mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw |
mov eax,edi ; redraw screen at old position |
xor esi,esi |
call redrawscreen |
mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse under |
mov [MOUSE_DOWN],byte 0 ; react to mouse up/down |
call [draw_pointer] |
mov [window_move_pr],0 |
.window_move_return: |
ret |
uglobal |
window_move_pr dd 0x0 |
window_move_eax dd 0x0 |
window_move_ebx dd 0x0 |
window_move_ecx dd 0x0 |
window_move_edx dd 0x0 |
endg |
;ok - 100% work |
;nt - not tested |
;--------------------------------------------------------------------------------------------- |
3550,12 → 3074,8 |
loop set_mouse_event |
mouse_not_active: |
cmp [REDRAW_BACKGROUND],byte 0 ; background update ? |
jz nobackgr |
cmp [background_defined], 0 |
jz nobackgr |
cmp [REDRAW_BACKGROUND], byte 2 |
jnz no_set_bgr_event |
cmp byte[BACKGROUND_CHANGED], 0 |
jz no_set_bgr_event |
xor edi, edi |
mov ecx, [TASK_COUNT] |
set_bgr_event: |
3562,7 → 3082,12 |
add edi, 256 |
or [edi+SLOT_BASE+APPDATA.event_mask], 16 |
loop set_bgr_event |
mov byte[BACKGROUND_CHANGED], 0 |
no_set_bgr_event: |
cmp byte[REDRAW_BACKGROUND], 0 ; background update ? |
jz nobackgr |
cmp [background_defined], 0 |
jz nobackgr |
; mov [draw_data+32 + RECT.left],dword 0 |
; mov [draw_data+32 + RECT.top],dword 0 |
; mov eax,[Screen_Max_X] |
3569,8 → 3094,16 |
; mov ebx,[Screen_Max_Y] |
; mov [draw_data+32 + RECT.right],eax |
; mov [draw_data+32 + RECT.bottom],ebx |
@@: |
call drawbackground |
mov [REDRAW_BACKGROUND],byte 0 |
xor eax, eax |
xchg al, [REDRAW_BACKGROUND] |
test al, al ; got new update request? |
jnz @b |
mov [draw_data+32 + RECT.left], eax |
mov [draw_data+32 + RECT.top], eax |
mov [draw_data+32 + RECT.right], eax |
mov [draw_data+32 + RECT.bottom], eax |
mov [MOUSE_BACKGROUND],byte 0 |
nobackgr: |
3684,34 → 3217,39 |
bgli: |
cmp ecx,1 |
cmp dword[esp], 1 |
jnz .az |
mov al,[REDRAW_BACKGROUND] |
cmp al,2 |
jz newdw8 |
test al,al |
; cmp byte[BACKGROUND_CHANGED], 0 |
; jnz newdw8 |
cmp byte[REDRAW_BACKGROUND], 0 |
jz .az |
mov dl, 0 |
lea eax,[edi+draw_data-window_data] |
mov ebx,[draw_limits.left] |
cmp ebx,[eax+RECT.left] |
jae @f |
mov [eax+RECT.left],ebx |
mov dl, 1 |
@@: |
mov ebx,[draw_limits.top] |
cmp ebx,[eax+RECT.top] |
jae @f |
mov [eax+RECT.top],ebx |
mov dl, 1 |
@@: |
mov ebx,[draw_limits.right] |
cmp ebx,[eax+RECT.right] |
jbe @f |
mov [eax+RECT.right],ebx |
mov dl, 1 |
@@: |
mov ebx,[draw_limits.bottom] |
cmp ebx,[eax+RECT.bottom] |
jbe @f |
mov [eax+RECT.bottom],ebx |
mov dl, 1 |
@@: |
add byte[REDRAW_BACKGROUND], dl |
jmp newdw8 |
.az: |
3731,7 → 3269,7 |
cmp dword [esp],1 |
jne nobgrd |
mov byte [REDRAW_BACKGROUND], 1 |
inc byte[REDRAW_BACKGROUND] |
newdw8: |
nobgrd: |
3761,6 → 3299,7 |
rep stosd |
mov byte [REDRAW_BACKGROUND], 0 ; do not draw background! |
mov byte[BACKGROUND_CHANGED], 0 |
ret |
3787,7 → 3326,8 |
mov ah,al |
cld |
cnt1: in al,0x61 |
cnt1: |
in al, 0x61 |
and al,0x10 |
cmp al,ah |
jz cnt1 |
3914,103 → 3454,6 |
align 4 |
sys_programirq: |
mov eax, [TASK_BASE] |
add ebx, [eax + TASKDATA.mem_start] |
cmp ecx, 16 |
jae .not_owner |
mov edi, [eax + TASKDATA.pid] |
cmp edi, [irq_owner + 4 * ecx] |
je .spril1 |
.not_owner: |
xor ecx, ecx |
inc ecx |
jmp .end |
.spril1: |
shl ecx, 6 |
mov esi, ebx |
lea edi, [irq00read + ecx] |
push 16 |
pop ecx |
cld |
rep movsd |
.end: |
mov [esp+32], ecx |
ret |
align 4 |
get_irq_data: |
movzx esi, bh ; save number of subfunction, if bh = 1, return data size, otherwise, read data |
xor bh, bh |
cmp ebx, 16 |
jae .not_owner |
mov edx, [4 * ebx + irq_owner] ; check for irq owner |
mov eax,[TASK_BASE] |
cmp edx,[eax+TASKDATA.pid] |
je gidril1 |
.not_owner: |
xor edx, edx |
dec edx |
jmp gid1 |
gidril1: |
shl ebx, 12 |
lea eax, [ebx + IRQ_SAVE] ; calculate address of the beginning of buffer + 0x0 - data size |
mov edx, [eax] ; + 0x4 - data offset |
dec esi |
jz gid1 |
test edx, edx ; check if buffer is empty |
jz gid1 |
mov ebx, [eax + 0x4] |
mov edi, ecx |
mov ecx, 4000 ; buffer size, used frequently |
cmp ebx, ecx ; check for the end of buffer, if end of buffer, begin cycle again |
jb @f |
xor ebx, ebx |
@@: |
lea esi, [ebx + edx] ; calculate data size and offset |
cld |
cmp esi, ecx ; if greater than the buffer size, begin cycle again |
jbe @f |
sub ecx, ebx |
sub edx, ecx |
lea esi, [eax + ebx + 0x10] |
rep movsb |
xor ebx, ebx |
@@: |
lea esi, [eax + ebx + 0x10] |
mov ecx, edx |
add ebx, edx |
rep movsb |
mov edx, [eax] |
mov [eax], ecx ; set data size to zero |
mov [eax + 0x4], ebx ; set data offset |
gid1: |
mov [esp+32], edx ; eax |
ret |
set_io_access_rights: |
push edi eax |
mov edi, tss._io_map_0 |
4022,13 → 3465,13 |
; shl ebx,cl |
test ebp,ebp |
; cmp ebp,0 ; enable access - ebp = 0 |
jnz siar1 |
jnz .siar1 |
; not ebx |
; and [edi],byte bl |
btr [edi], eax |
pop eax edi |
ret |
siar1: |
.siar1: |
bts [edi], eax |
; or [edi],byte bl ; disable access - ebp = 1 |
pop eax edi |
4183,66 → 3626,7 |
ret |
reserve_free_irq: |
xor esi, esi |
inc esi |
cmp ecx, 16 |
jae ril1 |
push ecx |
lea ecx, [irq_owner + 4 * ecx] |
mov edx, [ecx] |
mov eax, [TASK_BASE] |
mov edi, [eax + TASKDATA.pid] |
pop eax |
dec ebx |
jnz reserve_irq |
cmp edx, edi |
jne ril1 |
dec esi |
mov [ecx], esi |
jmp ril1 |
reserve_irq: |
cmp dword [ecx], 0 |
jne ril1 |
mov ebx, [f_irqs + 4 * eax] |
stdcall attach_int_handler, eax, ebx, dword 0 |
mov [ecx], edi |
dec esi |
ril1: |
mov [esp+32], esi ; return in eax |
ret |
iglobal |
f_irqs: |
dd 0x0 |
dd 0x0 |
dd p_irq2 |
dd p_irq3 |
dd p_irq4 |
dd p_irq5 |
dd p_irq6 |
dd p_irq7 |
dd p_irq8 |
dd p_irq9 |
dd p_irq10 |
dd p_irq11 |
dd 0x0 |
dd 0x0 |
dd p_irq14 |
dd p_irq15 |
endg |
align 4 |
drawbackground: |
inc [mouse_pause] |
cmp [SCR_MODE],word 0x12 |
4309,13 → 3693,7 |
dec [mouse_pause] |
pop ebp esi ebp |
jmp [draw_pointer] |
syscall_putimage_palette: |
mov edi, esi |
mov esi, edx |
mov edx, ecx |
mov ecx, ebx |
mov ebx, eax |
align 4 |
sys_putimage_palette: |
; ebx = pointer to image |
; ecx = [xsize]*65536 + [ysize] |
4740,64 → 4118,6 |
ret |
end if |
rerouteirqs: |
cli |
mov al,0x11 ; icw4, edge triggered |
out 0x20,al |
call pic_delay |
out 0xA0,al |
call pic_delay |
mov al,0x20 ; generate 0x20 + |
out 0x21,al |
call pic_delay |
mov al,0x28 ; generate 0x28 + |
out 0xA1,al |
call pic_delay |
mov al,0x04 ; slave at irq2 |
out 0x21,al |
call pic_delay |
mov al,0x02 ; at irq9 |
out 0xA1,al |
call pic_delay |
mov al,0x01 ; 8086 mode |
out 0x21,al |
call pic_delay |
out 0xA1,al |
call pic_delay |
mov al,255 ; mask all irq's |
out 0xA1,al |
call pic_delay |
out 0x21,al |
call pic_delay |
mov ecx,0x1000 |
cld |
picl1: call pic_delay |
loop picl1 |
mov al,255 ; mask all irq's |
out 0xA1,al |
call pic_delay |
out 0x21,al |
call pic_delay |
cli |
ret |
pic_delay: |
jmp pdl1 |
pdl1: ret |
sys_msg_board_str: |
pushad |
4856,7 → 4176,8 |
ret |
uglobal |
msg_board_data: times 4096 db 0 |
msg_board_data: |
times 4096 db 0 |
msg_board_count dd 0x0 |
endg |
4912,36 → 4233,47 |
.smbl2: |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; 66 sys function. ;; |
;; in eax=66,ebx in [0..5],ecx,edx ;; |
;; out eax ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
align 4 |
f66call: |
dd sys_process_def.1 ; 1 = set keyboard mode |
dd sys_process_def.2 ; 2 = get keyboard mode |
dd sys_process_def.3 ; 3 = get keyboard ctrl, alt, shift |
dd sys_process_def.4 |
dd sys_process_def.5 |
endg |
sys_process_def: |
dec ebx |
cmp ebx, 5 |
jae .not_support ;if >=6 then or eax,-1 |
mov edi, [CURRENT_TASK] |
jmp dword [f66call+ebx*4] |
dec eax ; 1 = set keyboard mode |
jne no_set_keyboard_setup |
.not_support: |
or eax, -1 |
ret |
.1: |
shl edi,8 |
mov [edi+SLOT_BASE + APPDATA.keyboard_mode],bl |
mov [edi+SLOT_BASE + APPDATA.keyboard_mode], cl |
ret |
no_set_keyboard_setup: |
dec eax ; 2 = get keyboard mode |
jne no_get_keyboard_setup |
.2: ; 2 = get keyboard mode |
shl edi,8 |
movzx eax, byte [SLOT_BASE+edi + APPDATA.keyboard_mode] |
mov [esp+36],eax |
mov [esp+32], eax |
ret |
no_get_keyboard_setup: |
dec eax ; 3 = get keyboard ctrl, alt, shift |
jne no_get_keyboard_cas |
; xor eax,eax |
; movzx eax,byte [shift] |
; movzx ebx,byte [ctrl] |
4950,20 → 4282,14 |
; movzx ebx,byte [alt] |
; shl ebx,3 |
; add eax,ebx |
.3: ;3 = get keyboard ctrl, alt, shift |
;// mike.dld [ |
mov eax, [kb_state] |
;// mike.dld ] |
mov [esp+36],eax |
mov [esp+32], eax |
ret |
no_get_keyboard_cas: |
dec eax |
jnz no_add_keyboard_hotkey |
.4: |
mov eax, hotkey_list |
@@: |
cmp dword [eax+8], 0 |
4971,29 → 4297,25 |
add eax, 16 |
cmp eax, hotkey_list+16*256 |
jb @b |
mov dword [esp+36], 1 |
mov dword [esp+32], 1 |
ret |
.found_free: |
mov [eax+8], edi |
mov [eax+4], ecx |
movzx ebx, bl |
lea ebx, [hotkey_scancodes+ebx*4] |
mov ecx, [ebx] |
mov [eax], ecx |
mov [ebx], eax |
mov [eax+12], ebx |
mov [eax+4], edx |
movzx ecx, cl |
lea ecx, [hotkey_scancodes+ecx*4] |
mov edx, [ecx] |
mov [eax], edx |
mov [ecx], eax |
mov [eax+12], ecx |
jecxz @f |
mov [ecx+12], eax |
mov [edx+12], eax |
@@: |
and dword [esp+36], 0 |
and dword [esp+32], 0 |
ret |
no_add_keyboard_hotkey: |
dec eax |
jnz no_del_keyboard_hotkey |
movzx ebx, bl |
.5: |
movzx ebx, cl |
lea ebx, [hotkey_scancodes+ebx*4] |
mov eax, [ebx] |
.scan: |
5001,13 → 4323,13 |
jz .notfound |
cmp [eax+8], edi |
jnz .next |
cmp [eax+4], ecx |
cmp [eax+4], edx |
jz .found |
.next: |
mov eax, [eax] |
jmp .scan |
.notfound: |
mov dword [esp+36], 1 |
mov dword [esp+32], 1 |
ret |
.found: |
mov ecx, [eax] |
5023,54 → 4345,52 |
mov [eax+8], edx |
mov [eax+12], edx |
mov [eax], edx |
mov [esp+36], edx |
mov [esp+32], edx |
ret |
no_del_keyboard_hotkey: |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; 61 sys function. ;; |
;; in eax=61,ebx in [1..3] ;; |
;; out eax ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
align 4 |
f61call: |
dd sys_gs.1 ; resolution |
dd sys_gs.2 ; bits per pixel |
dd sys_gs.3 ; bytes per scanline |
endg |
align 4 |
sys_gs: ; direct screen access |
dec ebx |
cmp ebx, 2 |
ja .not_support |
jmp dword [f61call+ebx*4] |
.not_support: |
or [esp+32], dword -1 |
ret |
cmp eax,1 ; resolution |
jne no_gs1 |
.1: ; resolution |
mov eax,[Screen_Max_X] |
shl eax,16 |
mov ax,[Screen_Max_Y] |
add eax,0x00010001 |
mov [esp+36],eax |
mov [esp+32], eax |
ret |
no_gs1: |
cmp eax,2 ; bits per pixel |
jne no_gs2 |
.2: ; bits per pixel |
movzx eax,byte [ScreenBPP] |
mov [esp+36],eax |
mov [esp+32], eax |
ret |
no_gs2: |
cmp eax,3 ; bytes per scanline |
jne no_gs3 |
.3: ; bytes per scanline |
mov eax,[BytesPerScanLine] |
mov [esp+36],eax |
mov [esp+32], eax |
ret |
no_gs3: |
or [esp+36],dword -1 |
ret |
align 4 ; PCI functions |
sys_pci: |
call pci_api |
mov [esp+36],eax |
ret |
align 4 ; system functions |
syscall_setpixel: ; SetPixel |
5335,26 → 4655,9 |
mov ecx, edx |
jmp [draw_line] |
align 4 |
syscall_getirqowner: ; GetIrqOwner |
cmp ebx,16 |
jae .err |
cmp [irq_rights + 4 * ebx], dword 2 |
je .err |
mov eax,[4 * ebx + irq_owner] |
mov [esp+32],eax |
ret |
.err: |
or dword [esp+32], -1 |
ret |
align 4 |
syscall_reserveportarea: ; ReservePortArea and FreePortArea |
call r_f_port_area |
5362,7 → 4665,6 |
ret |
align 4 |
syscall_threads: ; CreateThreads |
; eax=1 create thread |
; |
5528,6 → 4830,7 |
yes_shutdown_param: |
cli |
if ~ defined extended_primary_loader |
mov eax, kernel_file ; load kernel.mnt to 0x7000:0 |
push 12 |
pop esi |
5540,8 → 4843,9 |
mov edi,OS_BASE+0x40000 |
mov ecx,1000 |
rep movsb |
end if |
mov esi,OS_BASE+0x2F0000 ; restore 0x0 - 0xffff |
mov esi, BOOT_VAR ; restore 0x0 - 0xffff |
mov edi, OS_BASE |
mov ecx,0x10000/4 |
cld |
5549,9 → 4853,7 |
call restorefatchain |
mov al, 0xFF |
out 0x21, al |
out 0xA1, al |
call IRQ_mask_all |
if 0 |
mov word [OS_BASE+0x467+0],pr_mode_exit |
/kernel/branches/net/kernel32.inc |
---|
15,59 → 15,32 |
$Revision$ |
struct POINT |
x dd ? |
y dd ? |
ends |
;struc db [a] { common . db a |
; if ~used . |
; display 'not used db: ',`.,13,10 |
; end if } |
;struc dw [a] { common . dw a |
; if ~used . |
; display 'not used dw: ',`.,13,10 |
; end if } |
;struc dd [a] { common . dd a |
; if ~used . |
; display 'not used dd: ',`.,13,10 |
; end if } |
;struc dp [a] { common . dp a |
; if ~used . |
; display 'not used dp: ',`.,13,10 |
; end if } |
;struc dq [a] { common . dq a |
; if ~used . |
; display 'not used dq: ',`.,13,10 |
; end if } |
;struc dt [a] { common . dt a |
; if ~used . |
; display 'not used dt: ',`.,13,10 |
; end if } |
struct RECT |
left dd ? |
top dd ? |
right dd ? |
bottom dd ? |
ends |
struc RECT { |
.left dd ? |
.top dd ? |
.right dd ? |
.bottom dd ? |
} |
virtual at 0 |
RECT RECT |
end virtual |
struct BOX |
left dd ? |
top dd ? |
width dd ? |
height dd ? |
ends |
struc BOX { |
.left dd ? |
.top dd ? |
.width dd ? |
.height dd ? |
} |
virtual at 0 |
BOX BOX |
end virtual |
struct DISPMODE |
width dw ? |
height dw ? |
bpp dw ? |
freq dw ? |
ends |
struc DISPMODE { |
.width rw 1 |
.height rw 1 |
.bpp rw 1 |
.freq rw 1 |
} |
; constants definition |
WSTATE_NORMAL = 00000000b |
WSTATE_MAXIMIZED = 00000001b |
80,24 → 53,20 |
WSTYLE_HASCAPTION = 00010000b |
WSTYLE_CLIENTRELATIVE = 00100000b |
struc TASKDATA |
{ |
.event_mask dd ? |
.pid dd ? |
struct TASKDATA |
event_mask dd ? |
pid dd ? |
dw ? |
.state db ? |
state db ? |
db ? |
dw ? |
.wnd_number db ? |
wnd_number db ? |
db ? |
.mem_start dd ? |
.counter_sum dd ? |
.counter_add dd ? |
.cpu_usage dd ? |
} |
virtual at 0 |
TASKDATA TASKDATA |
end virtual |
mem_start dd ? |
counter_sum dd ? |
counter_add dd ? |
cpu_usage dd ? |
ends |
TSTATE_RUNNING = 0 |
TSTATE_RUN_SUSPENDED = 1 |
108,82 → 77,87 |
TSTATE_FREE = 9 |
; structures definition |
struc WDATA { |
.box BOX |
.cl_workarea dd ? |
.cl_titlebar dd ? |
.cl_frames dd ? |
.reserved db ? |
.fl_wstate db ? |
.fl_wdrawn db ? |
.fl_redraw db ? |
.sizeof: |
} |
virtual at 0 |
WDATA WDATA |
end virtual |
struct WDATA |
box BOX |
cl_workarea dd ? |
cl_titlebar dd ? |
cl_frames dd ? |
reserved db ? |
fl_wstate db ? |
fl_wdrawn db ? |
fl_redraw db ? |
ends |
label WDATA.fl_wstyle byte at WDATA.cl_workarea + 3 |
struc APPDATA |
{ |
.app_name db 11 dup(?) |
db 5 dup(?) |
struct DBG_REGS |
dr0 dd ? |
dr1 dd ? |
dr2 dd ? |
dr3 dd ? |
dr7 dd ? |
ends |
.fpu_state dd ? ;+16 |
.ev_count_ dd ? ;unused ;+20 |
.exc_handler dd ? ;+24 |
.except_mask dd ? ;+28 |
.pl0_stack dd ? ;unused ;+32 |
.heap_base dd ? ;+36 |
.heap_top dd ? ;+40 |
.cursor dd ? ;+44 |
.fd_ev dd ? ;+48 |
.bk_ev dd ? ;+52 |
.fd_obj dd ? ;+56 |
.bk_obj dd ? ;+60 |
.saved_esp dd ? ;+64 |
.io_map rd 2 ;+68 |
.dbg_state dd ? ;+76 |
.cur_dir dd ? ;+80 |
.wait_timeout dd ? ;+84 |
.saved_esp0 dd ? ;+88 |
.wait_begin dd ? ;+92 +++ |
.wait_test dd ? ;+96 +++ |
.wait_param dd ? ;+100 +++ |
.tls_base dd ? ;+104 |
.dlls_list_ptr dd ? ;+108 |
db 16 dup(?) ;+112 |
struct APPDATA |
app_name rb 11 |
rb 5 |
.wnd_shape dd ? ;+128 |
.wnd_shape_scale dd ? ;+132 |
fpu_state dd ? ;+16 |
ev_count_ dd ? ;unused ;+20 |
exc_handler dd ? ;+24 |
except_mask dd ? ;+28 |
pl0_stack dd ? ;+32 |
heap_base dd ? ;+36 |
heap_top dd ? ;+40 |
cursor dd ? ;+44 |
fd_ev dd ? ;+48 |
bk_ev dd ? ;+52 |
fd_obj dd ? ;+56 |
bk_obj dd ? ;+60 |
saved_esp dd ? ;+64 |
io_map rd 2 ;+68 |
dbg_state dd ? ;+76 |
cur_dir dd ? ;+80 |
wait_timeout dd ? ;+84 |
saved_esp0 dd ? ;+88 |
wait_begin dd ? ;+92 +++ |
wait_test dd ? ;+96 +++ |
wait_param dd ? ;+100 +++ |
tls_base dd ? ;+104 |
dlls_list_ptr dd ? ;+108 |
rb 16 ;+112 |
wnd_shape dd ? ;+128 |
wnd_shape_scale dd ? ;+132 |
dd ? ;+136 |
.mem_size dd ? ;+140 |
.saved_box BOX |
.ipc_start dd ? |
.ipc_size dd ? |
.event_mask dd ? |
.debugger_slot dd ? |
mem_size dd ? ;+140 |
saved_box BOX |
ipc_start dd ? |
ipc_size dd ? |
event_mask dd ? |
debugger_slot dd ? |
dd ? |
.keyboard_mode db ? |
db 3 dup(?) |
.dir_table dd ? |
.dbg_event_mem dd ? |
.dbg_regs: |
.dbg_regs.dr0 dd ? |
.dbg_regs.dr1 dd ? |
.dbg_regs.dr2 dd ? |
.dbg_regs.dr3 dd ? |
.dbg_regs.dr7 dd ? |
.wnd_caption dd ? |
.wnd_clientbox BOX |
} |
virtual at 0 |
APPDATA APPDATA |
end virtual |
keyboard_mode db ? |
rb 3 |
dir_table dd ? |
dbg_event_mem dd ? |
dbg_regs DBG_REGS |
wnd_caption dd ? |
wnd_clientbox BOX |
ends |
;// mike.dld, 2006-29-01 ] |
struct MUTEX |
lhead LHEAD |
count dd ? |
ends |
; Core functions |
include "core/sync.inc" ; macros for synhronization objects |
include "core/sys32.inc" ; process management |
199,6 → 173,9 |
include "core/exports.inc" |
include "core/string.inc" |
include "core/v86.inc" ; virtual-8086 manager |
include "core/irq.inc" ; irq handling functions |
include "core/apic.inc" ; Interrupt Controller functions |
include "core/timers.inc" |
; GUI stuff |
include "gui/window.inc" |
210,6 → 187,8 |
; file system |
include "blkdev/disk.inc" ; support for plug-n-play disks |
include "blkdev/disk_cache.inc" ; caching for plug-n-play disks |
include "fs/fs.inc" ; syscall |
include "fs/fat32.inc" ; read / write for fat32 filesystem |
include "fs/ntfs.inc" ; read / write for ntfs filesystem |
217,6 → 196,7 |
include "blkdev/rd.inc" ; ramdisk read /write |
include "fs/fs_lfn.inc" ; syscall, version 2 |
include "fs/iso9660.inc" ; read for iso9660 filesystem CD |
include "fs/ext2.inc" ; read / write for ext2 filesystem |
; sound |
226,6 → 206,7 |
include "video/vesa12.inc" ; Vesa 1.2 functions |
include "video/vesa20.inc" ; Vesa 2.0 functions |
include "video/blitter.inc" ; |
include "video/vga.inc" ; VGA 16 color functions |
include "video/cursors.inc" ; cursors functions |
/kernel/branches/net/macros.inc |
---|
11,6 → 11,9 |
$Revision$ |
;// mike.dld, 2006-29-01 [ |
; macros definition |
macro diff16 title,l1,l2 |
{ |
80,45 → 83,31 |
mov op1,op2 |
} |
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5 |
cmove fix cmovz |
macro cmovz reg1, reg2 { |
local .jumpaddr |
jnz .jumpaddr |
mov reg1, reg2 |
.jumpaddr: |
macro __list_add new, prev, next |
{ |
mov [next+LHEAD.prev], new |
mov [new+LHEAD.next], next |
mov [new+LHEAD.prev], prev |
mov [prev+LHEAD.next], new |
} |
cmovne fix cmovnz |
macro cmovnz reg1, reg2 { |
local .jumpaddr |
jz .jumpaddr |
mov reg1, reg2 |
.jumpaddr: |
macro list_add new, head |
{ |
mov eax, [head+LHEAD.next] |
__list_add new, head, eax |
} |
macro cmovg reg1, reg2 { |
local .jumpaddr |
jle .jumpaddr |
mov reg1, reg2 |
.jumpaddr: |
macro list_add_tail new, head |
{ |
mov eax, [head+LHEAD.prev] |
__list_add new, eax, head |
} |
macro cmovl reg1, reg2 { |
local .jumpaddr |
jge .jumpaddr |
mov reg1, reg2 |
.jumpaddr: |
macro list_del entry |
{ |
mov edx, [entry+list_fd] |
mov ecx, [entry+list_bk] |
mov [edx+list_bk], ecx |
mov [ecx+list_fd], edx |
} |
end if |
/kernel/branches/net/memmap.inc |
---|
62,33 → 62,36 |
; 3c dword cpu usage in cpu timer tics |
; |
; |
; 5000 -> 68FF free |
; 6900 -> 6EFF saved picture under mouse pointer |
; 5000 -> 68FF free (6k6) |
; 6900 -> 6EFF saved picture under mouse pointer (1k5) |
; |
; 6F00 -> 6FFF free |
; 6F00 -> 6FFF free (256) |
; |
; 7000 -> 7FFF used CD driver |
; |
; 8000 -> A3FF used FLOPPY driver |
; |
; A400 -> B0FF free |
; A400 -> B0FF free (3k3), unused ACTIVE_PROC_STACK |
; B100 -> B307 IDT for int_0x00..int_0x40 |
; B308 -> BFFF free |
; B308 -> BFFF free (3k3) |
; C000 -> C3FF window stack C000 no of windows - all in words |
; C402 -> C7FF window position in stack |
; D000 -> D1FF FDC controller |
; D200 -> D3FF FDC controller for Fat12 |
; D400 -> DFFF free |
; D400 -> DFFF free (3k) |
; E000 byte multitasking started |
; E020 dword putpixel address |
; E024 dword getpixel address |
; E030 dword Vesa 1.2 pm bank switch address |
; E034 -> F1FF free (4k5) |
; F200 dword mousepicture -pointer |
; F204 dword mouse appearance counter |
; F208 -> F2FF free (248) |
; F300 dword x & y temp for windowmove |
; F304 -> F3FF free (252) |
; F400 byte no of keys in buffer |
; F401 byte 'buffer' |
; F402 -> F4FF reserved for keys |
96,8 → 99,13 |
; F501 dword 'buffer' |
; F502 -> F5FF reserved for buttons |
; F600 dword tsc / second |
; F604 byte mouse port: 1 ps2, 2 com1, 3 com2 |
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y |
; F604 byte (unused?) mouse port: 1 ps2, 2 com1, 3 com2 |
; F605 -> FAFF free (1k2) |
; FB00 -> FB0F mouse memory 00 chunk count, that includes: |
; FB08 word -- mouse H-scroll |
; FB0A word -- mouse x |
; FB0C word -- mouse y |
; FB0E word -- mouse V-scroll |
; FB10 -> FB17 mouse color mem |
; FB21 x move |
; FB22 y move |
109,18 → 117,21 |
; FBF1 byte bits per pixel |
; FC00 -> FCFE com1/ps2 buffer |
; FCFF com1/ps2 buffer count starting from FC00 |
; FD00 -> FDFF free (256) |
; FE00 dword screen x size |
; FE04 dword screen y size |
; FE08 dword screen y multiplier |
; FE0C dword screen mode |
; FE10 -> FE7F free (112) |
; FE80 dword address of LFB in physical |
; FE84 dword address of applications memory start in physical |
; FE84 dword address of applications memory start in physical ? |
; FE88 dword address of button list |
; FE8C dword memory to use |
; FE90 -> FEFF free (112) |
; FF00 byte 1 = system shutdown request |
; FF01 dword free |
; FFF0 byte 1 = redraw background request from app |
; FFF1 byte 1 = diskette int occur |
; FF01 byte task activation request? |
; FFF0 byte >0 if redraw background request from app |
; FFF1 byte >0 if background changed |
; FFF2 write and read bank in screen |
; FFF4 byte 0 if first mouse draw & do not return picture under |
; FFF5 byte 1 do not draw pointer |
177,20 → 188,22 |
; BC dword address of debug event memory |
; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7 |
; |
; 0x80090000 -> 9FFFF tmp |
; 0x80090000 -> 9FFFF tmp (64k) - unused? |
; 0x800A0000 -> AFFFF screen access area |
; 0x800B0000 -> FFFFF bios rest in peace -area |
; 0x80100000 -> 27FFFF diskette image |
; 0x80280000 -> 281FFF ramdisk fat |
; 0x80282000 -> 283FFF floppy fat |
; 0x800B0000 -> FFFFF bios rest in peace -area (320k) ? |
; 0x80100000 -> 27FFFF diskette image (1m5) |
; 0x80280000 -> 281FFF ramdisk fat (8k) |
; 0x80282000 -> 283FFF floppy fat (8k) |
; |
; 0x80284000 -> 28BFFF HDD DMA AREA |
; 0x8028C000 -> 297FFF free (48 Kb) |
; 0x80284000 -> 28BFFF HDD DMA AREA (32k) |
; 0x8028C000 -> 297FFF free (48k) |
; |
; 0x80298000 -> 29ffff auxiliary table for background smoothing code |
; 0x80298000 -> 29ffff auxiliary table for background smoothing code (32k) |
; |
; 0x802A0000 -> 2B00ff wav device data |
; 0x802C0000 -> 2C3fff button info |
; 0x802A0000 -> 2B00ff wav device buffer (64k) |
; 0x802A0000 -> 2B00ff wav device status (256) |
; 0x802B0100 -> 2Bffff free (63k8) |
; 0x802C0000 -> 2C3fff button info (8k) |
; |
; 0000 word number of buttons |
; first button entry at 0x10 |
202,9 → 215,9 |
; +000A word y size |
; +000C word button id number : bits 16-31 |
; |
; 0x802C4000 -> 2CFFFF free (48Kb) |
; 0x802C4000 -> 2CFFFF free (48k) |
; |
; 0x802D0000 -> 2DFFFF reserved port area |
; 0x802D0000 -> 2DFFFF reserved port area (64k) |
; |
; 0000 dword no of port areas reserved |
; 0010 dword process id |
212,34 → 225,37 |
; dword end port |
; dword 0 |
; |
; 0x802E0000 -> 2EFFFF irq data area |
; 0x802F0000 -> 2FFFFF low memory save |
; 0x802E0000 -> 2EFFFF irq data area (64k) |
; 0x802F0000 -> 2FFFFF low memory save (64k) |
; |
; 0x80300000 -> 31FFFF tcp memory 128 Kb |
; 0x80320000 -> 327FFF tcp memory 32 Kb |
; 0x80300000 -> 31FFFF tcp memory (128k) |
; 0x80320000 -> 327FFF tcp memory (32k) |
; |
; 0x80328000 -> 32FFFF !vrr driver 32 Kb |
; 0x80328000 -> 32FFFF !vrr driver (32k) |
; 0x80330000 -> 377FFF skin data |
; 0x80330000 -> 377FFF skin data (32k) |
; 0x80338000 -> 33AFFF draw data - 256 entries |
; 0x80338000 -> 338FFF draw data - 256 entries (4k) |
; 00 dword draw limit - x start |
; 04 dword draw limit - y start |
; 08 dword draw limit - x end |
; 0C dword draw limit - y end |
; 0x80339000 -> 3BFFF3 free (12k) |
; 0x8033BFF4 -> 33BFFF background info |
; 0x8033C000 page map (length b = memsize shr 15) |
; 0x8033C000 + b start of static pagetables |
; 0x8033C000 -> 47BFFF display info |
; 0x803FFFFF <- no direct address translation beyond this point |
; ============================================================= |
; 0x8047CF80 -> 47CFFF TSS 128 bytes |
; 0x8047D000 -> 47EFFF IO map for (8192*8)=65536 ports |
; 0x805FF000 -> 5FFF80 TSS |
; 0x80600000 -> 601FFF i/o maps |
; 0x8047F000 -> 48FFFF page map max 128 Kb |
; |
; 0x80800000 -> kernel heap |
; 0x81FFFFFF heap min limit |
; 0x80FFFFFF heap min limit |
; 0xFDBFFFFF heap max limit |
; 0xF0000000 -> 0xF1FFFFFF PCI-express extended config space |
; 0xFDC00000 -> 0xFDFFFFFF page tables 4Mb |
; 0xFE000000 -> 0xFFFFFFFF LFB 32Mb |
; 0xFE000000 -> 0xFE7FFFFF application available LFB 8Mb |
/kernel/branches/net/network/stack.inc |
---|
150,6 → 150,13 |
} |
wait_mutex: ; stub |
inc dword [ebx] |
ret |
include "queue.inc" |
include "ethernet.inc" |
/kernel/branches/net/sound/playnote.inc |
---|
21,7 → 21,7 |
align 4 |
sound_interface: |
cmp eax, edi ; this is subfunction #55 ? |
cmp eax, ebx ; this is subfunction #55 ? |
jne retFunc55 ; if no then return. |
cmp byte [sound_flag],0 |
31,12 → 31,12 |
or al, al ; player is busy ? |
jnz retFunc55 ; return counter delay Note |
mov [memAdrNote],edx |
mov [memAdrNote], esi;edx |
call get_pid |
mov [pidProcessNote],eax |
xor eax, eax ; Ok! EAX = 0 |
retFunc55: |
mov [esp+36], eax ; return value EAX for application |
mov [esp+32], eax ; return value EAX for application |
ret |
iglobal |
/kernel/branches/net/unpacker.inc |
---|
21,7 → 21,7 |
push eax |
add esi, 12 |
and al, not 0xC0 |
dec eax |
dec al |
jz .lzma |
.failed: |
pop eax |
219,7 → 219,8 |
cmp bl, 10 |
jb @f |
mov al, 6 |
@@: sub bl, al |
@@: |
sub bl, al |
jmp .main_loop |
.1: |
lea eax, [.IsRep*4 + ebx*4] |
/kernel/branches/net/video/blitter.inc |
---|
0,0 → 1,444 |
struc BLITTER |
{ |
.dc.xmin rd 1 ; 0 |
.dc.ymin rd 1 ; 4 |
.dc.xmax rd 1 ; 8 |
.dc.ymax rd 1 ; 12 |
.sc: |
.sc.xmin rd 1 ; 16 |
.sc.ymin rd 1 ; 20 |
.sc.xmax rd 1 ; 24 |
.sc.ymax rd 1 ; 28 |
.dst_x rd 1 ; 32 |
.dst_y rd 1 ; 36 |
.src_x rd 1 ; 40 |
.src_y rd 1 ; 44 |
.w rd 1 ; 48 |
.h rd 1 ; 52 |
.bitmap rd 1 ; 56 |
.stride rd 1 ; 60 |
} |
virtual at 0 |
BLITTER BLITTER |
end virtual |
align 4 |
__L1OutCode: |
push ebx |
mov ebx, 8 |
cmp edx, [eax] |
jl .L2 |
xor ebx, ebx |
cmp edx, [eax+8] |
setg bl |
sal ebx, 2 |
.L2: |
cmp ecx, [eax+4] |
jge .L3 |
or ebx, 1 |
jmp .L4 |
.L3: |
cmp ecx, [eax+12] |
jle .L4 |
or ebx, 2 |
.L4: |
mov eax, ebx |
pop ebx |
ret |
align 4 |
block_clip: |
push ebp |
push edi |
push esi |
push ebx |
sub esp, 4 |
mov ebx, eax |
mov [esp], edx |
mov ebp, ecx |
mov ecx, [ecx] |
mov edx, [edx] |
call __L1OutCode |
mov esi, eax |
mov edx, [esp+28] |
mov ecx, [edx] |
.L21: |
mov eax, [esp+24] |
mov edx, [eax] |
mov eax, ebx |
call __L1OutCode |
mov edi, eax |
.L20: |
mov eax, edi |
and eax, esi |
jne .L9 |
cmp esi, edi |
je .L9 |
test esi, esi |
jne .L10 |
test edi, 1 |
je .L11 |
mov eax, [ebx+4] |
jmp .L25 |
.L11: |
test edi, 2 |
je .L13 |
mov eax, [ebx+12] |
.L25: |
mov edx, [esp+28] |
jmp .L22 |
.L13: |
test edi, 4 |
je .L14 |
mov eax, [ebx+8] |
jmp .L26 |
.L14: |
and edi, 8 |
je .L12 |
mov eax, [ebx] |
.L26: |
mov edx, [esp+24] |
.L22: |
mov [edx], eax |
.L12: |
mov eax, [esp+28] |
mov ecx, [eax] |
jmp .L21 |
.L10: |
test esi, 1 |
je .L16 |
mov eax, [ebx+4] |
jmp .L23 |
.L16: |
test esi, 2 |
je .L18 |
mov eax, [ebx+12] |
.L23: |
mov [ebp+0], eax |
jmp .L17 |
.L18: |
test esi, 4 |
je .L19 |
mov eax, [ebx+8] |
jmp .L24 |
.L19: |
and esi, 8 |
je .L17 |
mov eax, [ebx] |
.L24: |
mov edx, [esp] |
mov [edx], eax |
.L17: |
mov ecx, [ebp+0] |
mov eax, [esp] |
mov edx, [eax] |
mov eax, ebx |
call __L1OutCode |
mov esi, eax |
jmp .L20 |
.L9: |
add esp, 4 |
pop ebx |
pop esi |
pop edi |
pop ebp |
ret |
align 4 |
blit_clip: |
.sx0 equ 36 |
.sy0 equ 32 |
.sx1 equ 28 |
.sy1 equ 24 |
.dx0 equ 20 |
.dy0 equ 16 |
.dx1 equ 12 |
.dy1 equ 8 |
push edi |
push esi |
push ebx |
sub esp, 40 |
mov ebx, ecx |
mov edx, [ecx+BLITTER.src_x] |
mov [esp+.sx0], edx |
mov eax, [ecx+BLITTER.src_y] |
mov [esp+.sy0], eax |
add edx, [ecx+BLITTER.w] |
dec edx |
mov [esp+.sx1], edx |
add eax, [ecx+BLITTER.h] |
dec eax |
mov [esp+.sy1], eax |
lea ecx, [esp+.sy0] |
lea edx, [esp+.sx0] |
lea eax, [ebx+BLITTER.sc] |
lea esi, [esp+.sy1] |
mov [esp+4], esi |
lea esi, [esp+.sx1] |
mov [esp], esi |
call block_clip |
mov esi, 1 |
test eax, eax |
jne .L28 |
mov edi, [esp+.sx0] |
mov edx, [ebx+BLITTER.dst_x] |
add edx, edi |
sub edx, [ebx+BLITTER.src_x] |
mov [esp+.dx0], edx |
mov ecx, [esp+.sy0] |
mov eax, [ebx+BLITTER.dst_y] |
add eax, ecx |
sub eax, [ebx+BLITTER.src_y] |
mov [esp+.dy0], eax |
sub edx, edi |
add edx, [esp+.sx1] |
mov [esp+.dx1], edx |
sub eax, ecx |
add eax, [esp+.sy1] |
mov [esp+.dy1], eax |
lea ecx, [esp+.dy0] |
lea edx, [esp+.dx0] |
lea eax, [esp+.dy1] |
mov [esp+4], eax |
lea eax, [esp+.dx1] |
mov [esp], eax |
mov eax, ebx |
call block_clip |
test eax, eax |
jne .L28 |
mov edx, [esp+.dx0] |
mov eax, [esp+.dx1] |
inc eax |
sub eax, edx |
mov [ebx+BLITTER.w], eax |
mov eax, [esp+.dy0] |
mov ecx, [esp+.dy1] |
inc ecx |
sub ecx, eax |
mov [ebx+BLITTER.h], ecx |
mov ecx, [ebx+BLITTER.src_x] |
add ecx, edx |
sub ecx, [ebx+BLITTER.dst_x] |
mov [ebx+BLITTER.src_x], ecx |
mov ecx, [ebx+BLITTER.src_y] |
add ecx, eax |
sub ecx, [ebx+BLITTER.dst_y] |
mov [ebx+BLITTER.src_y], ecx |
mov [ebx+BLITTER.dst_x], edx |
mov [ebx+BLITTER.dst_y], eax |
xor esi, esi |
.L28: |
mov eax, esi |
add esp, 40 |
pop ebx |
pop esi |
pop edi |
purge .sx0 |
purge .sy0 |
purge .sx1 |
purge .sy1 |
purge .dx0 |
purge .dy0 |
purge .dx1 |
purge .dy1 |
ret |
align 4 |
blit_32: |
push ebp |
push edi |
push esi |
push ebx |
sub esp, 72 |
mov eax, [TASK_BASE] |
mov ebx, [eax-twdw + WDATA.box.width] |
mov edx, [eax-twdw + WDATA.box.height] |
xor eax, eax |
mov [esp+BLITTER.dc.xmin], eax |
mov [esp+BLITTER.dc.ymin], eax |
mov [esp+BLITTER.dc.xmax], ebx |
mov [esp+BLITTER.dc.ymax], edx |
mov [esp+BLITTER.sc.xmin], eax |
mov [esp+BLITTER.sc.ymin], eax |
mov eax, [ecx+24] |
dec eax |
mov [esp+BLITTER.sc.xmax], eax |
mov eax, [ecx+28] |
dec eax |
mov [esp+BLITTER.sc.ymax], eax |
mov eax, [ecx] |
mov [esp+BLITTER.dst_x], eax |
mov eax, [ecx+4] |
mov [esp+BLITTER.dst_y], eax |
mov eax, [ecx+16] |
mov [esp+BLITTER.src_x], eax |
mov eax, [ecx+20] |
mov [esp+BLITTER.src_y], eax |
mov eax, [ecx+8] |
mov [esp+BLITTER.w], eax |
mov eax, [ecx+12] |
mov [esp+BLITTER.h], eax |
mov eax, [ecx+32] |
mov [esp+56], eax |
mov eax, [ecx+36] |
mov [esp+60], eax |
mov ecx, esp |
call blit_clip |
test eax, eax |
jne .L57 |
inc [mouse_pause] |
call [_display.disable_mouse] |
mov eax, [TASK_BASE] |
mov ebx, [esp+BLITTER.dst_x] |
mov ebp, [esp+BLITTER.dst_y] |
add ebx, [eax-twdw + WDATA.box.left] |
add ebp, [eax-twdw + WDATA.box.top] |
mov edi, ebp |
imul edi, [_display.pitch] |
imul ebp, [_display.width] |
add ebp, ebx |
add ebp, [_WinMapAddress] |
mov eax, [esp+BLITTER.src_y] |
imul eax, [esp+BLITTER.stride] |
mov esi, [esp+BLITTER.src_x] |
lea esi, [eax+esi*4] |
add esi, [esp+BLITTER.bitmap] |
mov ecx, [esp+BLITTER.h] |
mov edx, [esp+BLITTER.w] |
test ecx, ecx ;FIXME check clipping |
jz .L57 |
test edx, edx |
jz .L57 |
cmp [_display.bpp], 32 |
jne .core_24 |
lea edi, [edi+ebx*4] |
mov ebx, [CURRENT_TASK] |
align 4 |
.outer32: |
xor ecx, ecx |
align 4 |
.inner32: |
cmp [ebp+ecx], bl |
jne @F |
mov eax, [esi+ecx*4] |
mov [LFB_BASE+edi+ecx*4], eax |
@@: |
inc ecx |
dec edx |
jnz .inner32 |
add esi, [esp+BLITTER.stride] |
add edi, [_display.pitch] |
add ebp, [_display.width] |
mov edx, [esp+BLITTER.w] |
dec [esp+BLITTER.h] |
jnz .outer32 |
.done: |
dec [mouse_pause] |
call [draw_pointer] |
.L57: |
add esp, 72 |
pop ebx |
pop esi |
pop edi |
pop ebp |
ret |
.core_24: |
lea ebx, [ebx+ebx*2] |
lea edi, [LFB_BASE+edi+ebx] |
mov ebx, [CURRENT_TASK] |
align 4 |
.outer24: |
mov [esp+64], edi |
xor ecx, ecx |
align 4 |
.inner24: |
cmp [ebp+ecx], bl |
jne @F |
mov eax, [esi+ecx*4] |
lea edi, [edi+ecx*2] |
mov [edi+ecx], ax |
shr eax, 16 |
mov [edi+ecx+2], al |
@@: |
mov edi, [esp+64] |
inc ecx |
dec edx |
jnz .inner24 |
add esi, [esp+BLITTER.stride] |
add edi, [_display.pitch] |
add ebp, [_display.width] |
mov edx, [esp+BLITTER.w] |
dec [esp+BLITTER.h] |
jnz .outer24 |
jmp .done |
/kernel/branches/net/video/cursors.inc |
---|
332,19 → 332,13 |
stdcall init_cursor, eax, esi |
mov eax, [.hcursor] |
lea eax, [eax+CURSOR.list_next] |
mov ecx, [.hcursor] |
lea ecx, [ecx+CURSOR.list_next] |
lea edx, [_display.cr_list.next] |
pushfd |
cli |
mov ecx, [edx] |
mov [eax], ecx |
mov [eax+4], edx |
mov [ecx+4], eax |
mov [edx], eax |
list_add ecx, edx ;list_add_tail(new, head) |
popfd |
mov eax, [.hcursor] |
458,8 → 452,16 |
push eax |
stdcall kernel_free, [eax+CURSOR.base] |
mov eax, [esp] |
lea eax, [eax+CURSOR.list_next] |
pushfd |
cli |
list_del eax |
popfd |
pop eax |
call destroy_kernel_object |
ret |
792,14 → 794,6 |
ret |
align 4 |
def_arrow: |
file 'arrow.cur' |
/kernel/branches/net/video/vesa20.inc |
---|
445,6 → 445,14 |
cdq ; extend eax sing to edx |
shl eax, 16 ; using 16bit fix-point maths |
idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1) |
;-------------------------------------- |
; correction for the remainder of the division |
shl edx, 1 |
cmp ebp, edx |
jb @f |
inc eax |
@@: |
;-------------------------------------- |
mov edx, ebp ; edx = counter (number of pixels to draw) |
mov ebp, 1 *65536 ; <<16 ; ebp = dy = 1.0 |
mov esi, eax ; esi = dx |
466,6 → 474,14 |
cdq ; extend eax sing to edx |
shl eax, 16 ; using 16bit fix-point maths |
idiv esi ; eax = ((y2-y1)*65536)/(x2-x1) |
;-------------------------------------- |
; correction for the remainder of the division |
shl edx, 1 |
cmp esi, edx |
jb @f |
inc eax |
@@: |
;-------------------------------------- |
mov edx, esi ; edx = counter (number of pixels to draw) |
mov esi, 1 *65536 ;<< 16 ; esi = dx = 1.0 |
mov ebp, eax ; ebp = dy |
474,10 → 490,25 |
mov ebx, [dl_y1] |
shl eax, 16 |
shl ebx, 16 |
;----------------------------------------------------------------------------- |
align 4 |
.draw: |
push eax ebx |
;-------------------------------------- |
; correction for the remainder of the division |
test ah, 0x80 |
jz @f |
add eax, 1 shl 16 |
@@: |
;-------------------------------------- |
shr eax, 16 |
;-------------------------------------- |
; correction for the remainder of the division |
test bh, 0x80 |
jz @f |
add ebx, 1 shl 16 |
@@: |
;-------------------------------------- |
shr ebx, 16 |
call [putpixel] |
pop ebx eax |