Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 2381 → Rev 2382

/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