Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5201 → Rev 5200

/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc
17,7 → 17,7
hdid dd ?
hdpos dd ?
ends
;-----------------------------------------------------------------------------
 
iglobal
align 4
ide_callbacks:
35,34 → 35,18
hd1_data HD_DATA ?, 0x10, 2
hd2_data HD_DATA ?, 0, 3
hd3_data HD_DATA ?, 0x10, 4
hd4_data HD_DATA ?, 0, 5
hd5_data HD_DATA ?, 0x10, 6
hd6_data HD_DATA ?, 0, 7
hd7_data HD_DATA ?, 0x10, 8
hd8_data HD_DATA ?, 0, 9
hd9_data HD_DATA ?, 0x10, 10
hd10_data HD_DATA ?, 0, 11
hd11_data HD_DATA ?, 0x10, 12
 
ide_mutex_table:
dd ide_channel1_mutex
dd ide_channel2_mutex
dd ide_channel3_mutex
dd ide_channel4_mutex
dd ide_channel5_mutex
dd ide_channel6_mutex
hd_address_table:
dd 0x1f0, 0x00, 0x1f0, 0x10
dd 0x170, 0x00, 0x170, 0x10
endg
;-----------------------------------------------------------------------------
 
uglobal
ide_mutex MUTEX
ide_channel1_mutex MUTEX
ide_channel2_mutex MUTEX
ide_channel3_mutex MUTEX
ide_channel4_mutex MUTEX
ide_channel5_mutex MUTEX
ide_channel6_mutex MUTEX
endg
;-----------------------------------------------------------------------------
 
proc ide_read stdcall uses edi, \
hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data
83,13 → 67,15
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
 
mov ecx, [hd_data]
mov ecx, [ecx+HD_DATA.hdpos]
dec ecx
shr ecx, 1
shl ecx, 2
mov ecx, [ecx + ide_mutex_table]
mov ecx, ide_channel2_mutex
mov eax, [hd_data]
push ecx
mov ecx, [hd_address_table]
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0
pop ecx
jne .IDE_Channel_2
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov [channel_lock], ecx
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
97,7 → 83,6
; Worker procedures use global variables and edi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
 
and [hd_error], 0
mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase]
113,65 → 98,55
; DMA read is permitted if [allow_dma_access]=1 or 2
cmp [allow_dma_access], 2
ja .nodma
cmp [dma_hdd], 1
jnz .nodma
;--------------------------------------
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jnz @f
 
push eax ecx
mov ecx, [hdpos]
dec ecx
shr ecx, 2
imul ecx, sizeof.IDE_DATA
add ecx, IDE_controller_1
mov [IDE_controller_pointer], ecx
test [DRIVE_DATA+1], byte 10100000b
jnz .nodma
 
mov eax, [hdpos]
dec eax
and eax, 11b
shr eax, 1
add eax, ecx
cmp [eax+IDE_DATA.dma_hdd_channel_1], 1
pop ecx eax
jmp .dma
@@:
test [DRIVE_DATA+1], byte 1010b
jnz .nodma
 
.dma:
;--------------------------------------
call hd_read_dma
jmp @f
;--------------------------------------
.nodma:
call hd_read_pio
;--------------------------------------
@@:
cmp [hd_error], 0
jnz .fail
 
mov ecx, [numsectors]
inc dword [ecx] ; one more sector is read
dec [sectors_todo]
jz .done
 
inc eax
jnz .sectors_loop
;--------------------------------------
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, [channel_lock]
call mutex_unlock
 
mov ecx, ide_mutex
call mutex_unlock
 
or eax, -1
ret
;--------------------------------------
.done:
mov ecx, [channel_lock]
call mutex_unlock
 
mov ecx, ide_mutex
call mutex_unlock
 
xor eax, eax
ret
endp
;-----------------------------------------------------------------------------
 
proc ide_write stdcall uses esi edi, \
hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data
192,13 → 167,15
; 2. Acquire the global lock.
mov ecx, ide_mutex
call mutex_lock
 
mov ecx, [hd_data]
mov ecx, [ecx+HD_DATA.hdpos]
dec ecx
shr ecx, 1
shl ecx, 2
mov ecx, [ecx + ide_mutex_table]
mov ecx, ide_channel2_mutex
mov eax, [hd_data]
push ecx
mov ecx, [hd_address_table]
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0
pop ecx
jne .IDE_Channel_2
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov [channel_lock], ecx
call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures.
206,7 → 183,6
; Worker procedures use global variables and esi for [buffer].
cmp dword [startsector+4], 0
jnz .fail
 
and [hd_error], 0
mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase]
224,79 → 200,66
mov ecx, 16
cmp ecx, [sectors_todo]
jbe @f
 
mov ecx, [sectors_todo]
;--------------------------------------
@@:
mov [cache_chain_size], cl
; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2
jae .nodma
cmp [dma_hdd], 1
jnz .nodma
;--------------------------------------
push eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jnz @f
 
push eax ecx
mov ecx, [hdpos]
dec ecx
shr ecx, 2
imul ecx, sizeof.IDE_DATA
add ecx, IDE_controller_1
mov [IDE_controller_pointer], ecx
test [DRIVE_DATA+1], byte 10100000b
jnz .nodma
 
mov eax, [hdpos]
dec eax
and eax, 11b
shr eax, 1
add eax, ecx
cmp [eax+IDE_DATA.dma_hdd_channel_1], 1
pop ecx eax
jmp .dma
@@:
test [DRIVE_DATA+1], byte 1010b
jnz .nodma
 
.dma:
;--------------------------------------
call cache_write_dma
jmp .common
;--------------------------------------
.nodma:
mov [cache_chain_size], 1
call cache_write_pio
;--------------------------------------
.common:
cmp [hd_error], 0
jnz .fail
 
movzx ecx, [cache_chain_size]
mov eax, [numsectors]
add [eax], ecx
sub [sectors_todo], ecx
jz .done
 
add [edi], ecx
jc .fail
 
shl ecx, 9
add esi, ecx
jmp .sectors_loop
;--------------------------------------
; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status.
.fail:
mov ecx, [channel_lock]
call mutex_unlock
 
mov ecx, ide_mutex
call mutex_unlock
 
or eax, -1
ret
;--------------------------------------
.done:
mov ecx, [channel_lock]
call mutex_unlock
 
mov ecx, ide_mutex
call mutex_unlock
 
xor eax, eax
ret
endp
;-----------------------------------------------------------------------------
 
; This is a stub.
proc ide_querymedia stdcall, hd_data, mediainfo
mov eax, [mediainfo]
307,6 → 270,7
xor eax, eax
ret
endp
 
;-----------------------------------------------------------------------------
align 4
; input: eax = sector, edi -> buffer
313,6 → 277,7
; output: edi = edi + 512
hd_read_pio:
push eax edx
 
; Select the desired drive
mov edx, [hdbase]
add edx, 6 ;адрес регистра головок
321,9 → 286,9
out dx, al; номер головки/номер диска
call wait_for_hd_idle
 
cmp [hd_error], 0
jne hd_read_error
; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4]
cmp eax, 0x10000000
407,6 → 372,7
 
pushfd
cli
 
mov ecx, 256
mov edx, [hdbase]
cld
427,7 → 393,6
out dx, al ; номер головки/номер диска
 
call wait_for_hd_idle
 
cmp [hd_error], 0
jne hd_write_error
 
585,7 → 550,6
align 4
wfhil1:
call check_hd_wait_timeout
 
cmp [hd_error], 0
jne @f
 
592,7 → 556,7
in al, dx
test al, 128
jnz wfhil1
;--------------------------------------
 
@@:
pop edx eax
ret
609,7 → 573,6
align 4
hdwait_sbuf: ; wait for sector buffer to be ready
call check_hd_wait_timeout
 
cmp [hd_error], 0
jne @f
 
624,10 → 587,9
 
test al, 1 ; previous command ended up with an error
jz buf_wait_ok
;--------------------------------------
@@:
mov [hd_error], 1
;--------------------------------------
 
buf_wait_ok:
pop edx eax
ret
644,17 → 606,22
align 4
.wait:
call change_task
 
cmp [IDE_common_irq_param], 0
jz .done
 
call check_hd_wait_timeout
 
cmp [hd_error], 0
jz .wait
 
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
popfd
;--------------------------------------
align 4
.done:
pop edx
pop eax
669,17 → 636,23
align 4
.wait:
call change_task
 
cmp [IDE_common_irq_param], 0
jz .done
 
call check_hd_wait_timeout
 
cmp [hd_error], 0
jz .wait
 
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
popfd
;--------------------------------------
align 4
.done:
pop edx
pop eax
687,8 → 660,7
;-----------------------------------------------------------------------------
iglobal
align 4
; note that IDE descriptor table must be 4-byte aligned
; and do not cross 4K boundary
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
IDE_descriptor_table:
dd IDE_DMA
dw 0x2000
701,14 → 673,19
;-----------------------------------------------------------------------------
uglobal
; all uglobals are zeroed at boot
dma_process dd 0
dma_slot_ptr dd 0
cache_chain_pos dd 0
cache_chain_ptr dd 0
cache_chain_size db 0
cache_chain_started db 0
dma_task_switched db 0
dma_hdd db 0
allow_dma_access db 0
endg
;-----------------------------------------------------------------------------
align 4
IDE_irq_14_handler:
; DEBUGF 1, 'K : IDE_irq_14_handler %x\n', [IDE_common_irq_param]:2
cmp [IDE_common_irq_param], irq14_num
jne .exit
 
716,8 → 693,7
cli
pushad
mov [IDE_common_irq_param], 0
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
mov dx, [IDEContrRegsBaseAddr]
; test whether it is our interrupt?
add edx, 2
in al, dx
739,10 → 715,12
mov al, 1
ret
;--------------------------------------
align 4
@@:
popad
popfd
;--------------------------------------
align 4
.exit:
mov al, 0
ret
749,7 → 727,6
;-----------------------------------------------------------------------------
align 4
IDE_irq_15_handler:
; DEBUGF 1, 'K : IDE_irq_15_handler %x\n', [IDE_common_irq_param]:2
cmp [IDE_common_irq_param], irq15_num
jne .exit
 
757,8 → 734,7
cli
pushad
mov [IDE_common_irq_param], 0
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
; test whether it is our interrupt?
add edx, 2
781,10 → 757,12
mov al, 1
ret
;--------------------------------------
align 4
@@:
popad
popfd
;--------------------------------------
align 4
.exit:
mov al, 0
ret
791,16 → 769,14
;-----------------------------------------------------------------------------
align 4
IDE_common_irq_handler:
; DEBUGF 1, 'K : IDE_common_irq_handler %x\n', [IDE_common_irq_param]:2
pushfd
cli
cmp [IDE_common_irq_param], 0
je .exit
 
pushfd
cli
pushad
xor ebx, ebx
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
mov dx, [IDEContrRegsBaseAddr]
mov eax, IDE_common_irq_param
cmp [eax], irq14_num
mov [eax], bl
808,6 → 784,7
 
add dx, 8
;--------------------------------------
align 4
@@:
; test whether it is our interrupt?
add edx, 2
830,11 → 807,13
mov al, 1
ret
;--------------------------------------
align 4
@@:
popad
popfd
;--------------------------------------
align 4
.exit:
popfd
mov al, 0
ret
;-----------------------------------------------------------------------------
845,31 → 824,26
mov edx, [dma_hdpos]
cmp edx, [hdpos]
jne .notread
 
mov edx, [dma_cur_sector]
cmp eax, edx
jb .notread
 
add edx, 15
cmp [esp+4], edx
ja .notread
 
mov eax, [esp+4]
sub eax, [dma_cur_sector]
shl eax, 9
add eax, (OS_BASE+IDE_DMA)
 
push ecx esi
mov esi, eax
 
mov ecx, 512/4
cld
rep movsd
pop esi ecx
 
pop edx
pop eax
ret
;--------------------------------------
.notread:
; set data for PRD Table
mov eax, IDE_descriptor_table
877,18 → 851,13
mov word [eax+4], 0x2000
sub eax, OS_BASE
; select controller Primary or Secondary
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
 
mov dx, [IDEContrRegsBaseAddr]
push eax
mov eax, [hdpos]
dec eax
test eax, 10b
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jz @f
 
add edx, 8
;--------------------------------------
@@:
push edx
; Bus Master IDE PRD Table Address
912,9 → 881,9
out dx, al ; номер головки/номер диска
 
call wait_for_hd_idle
 
cmp [hd_error], 0
jnz hd_read_error
 
; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4]
; -10h because the PreCache hits the boundary between lba28 and lba48
992,55 → 961,47
;--------------------------------------
.continue:
; select controller Primary or Secondary
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
 
mov eax, [hdpos]
dec eax
test eax, 10b
mov dx, [IDEContrRegsBaseAddr]
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jz @f
 
add dx, 8
;--------------------------------------
@@:
; set write to memory and Start Bus Master
mov al, 9
out dx, al
 
mov eax, [hdpos]
dec eax
test eax, 10b
mov eax, [CURRENT_TASK]
mov [dma_process], eax
 
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
 
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1
 
mov [IDE_common_irq_param], irq14_num
jmp @f
;--------------------------------------
.ide1:
mov [IDE_common_irq_param], irq15_num
;--------------------------------------
@@:
popfd
; wait for interrupt
mov eax, [hdpos]
dec eax
test eax, 10b
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .wait_ide1
 
call wait_for_sector_dma_ide0
jmp @f
;--------------------------------------
.wait_ide1:
call wait_for_sector_dma_ide1
;--------------------------------------
@@:
cmp [hd_error], 0
jnz hd_read_error
 
mov eax, [hdpos]
mov [dma_hdpos], eax
pop edx
pop eax
 
mov [dma_cur_sector], eax
jmp hd_read_dma
;-----------------------------------------------------------------------------
1050,7 → 1011,6
; set data for PRD Table
mov eax, IDE_descriptor_table
mov edx, eax
 
pusha
mov edi, (OS_BASE+IDE_DMA)
mov dword [edx], IDE_DMA
1061,21 → 1021,15
cld
rep movsd
popa
 
sub eax, OS_BASE
; select controller Primary or Secondary
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
 
mov dx, [IDEContrRegsBaseAddr]
push eax
mov eax, [hdpos]
dec eax
test eax, 10b
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
pop eax
jz @f
 
add edx, 8
;--------------------------------------
@@:
push edx
; Bus Master IDE PRD Table Address
1099,9 → 1053,9
out dx, al ; номер головки/номер диска
 
call wait_for_hd_idle
 
cmp [hd_error], 0
jnz hd_write_error_dma
 
; ATA with 28 or 48 bit for sector number?
mov esi, [cache_chain_ptr]
mov eax, [esi]
1180,49 → 1134,38
;--------------------------------------
.continue:
; select controller Primary or Secondary
mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
 
mov eax, [hdpos]
dec eax
test eax, 10b
mov dx, [IDEContrRegsBaseAddr]
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jz @f
 
add dx, 8
;--------------------------------------
@@:
; set write to device and Start Bus Master
mov al, 1
out dx, al
 
mov eax, [hdpos]
dec eax
test eax, 10b
mov eax, [CURRENT_TASK]
mov [dma_process], eax
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1
 
mov [IDE_common_irq_param], irq14_num
jmp @f
;--------------------------------------
.ide1:
mov [IDE_common_irq_param], irq15_num
;--------------------------------------
@@:
popfd
; wait for interrupt
mov [dma_cur_sector], not 0x40
 
mov eax, [hdpos]
dec eax
test eax, 10b
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .wait_ide1
 
call wait_for_sector_dma_ide0
 
jmp @f
;--------------------------------------
.wait_ide1:
call wait_for_sector_dma_ide1
;--------------------------------------
@@:
cmp [hd_error], 0
jnz hd_write_error_dma
1229,44 → 1172,14
pop esi
ret
;-----------------------------------------------------------------------------
proc clear_pci_ide_interrupts
mov esi, pcidev_list
;--------------------------------------
uglobal
align 4
.loop:
mov esi, [esi+PCIDEV.fd]
cmp esi, pcidev_list
jz .done
 
; cmp [esi+PCIDEV.class], 0x01018F
mov eax, [esi+PCIDEV.class]
shr eax, 4
cmp eax, 0x01018
jnz .loop
 
mov ah, [esi+PCIDEV.bus]
mov al, 2
mov bh, [esi+PCIDEV.devfn]
mov bl, 0x20
call pci_read_reg
 
and eax, 0FFFCh
mov edx, eax
add edx, 2
in al, dx
DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al
out dx, al
in al, dx
DEBUGF 1,'-> %x; ',al
add edx, 8
in al, dx
DEBUGF 1,'port[%x] = %x ',dx,al
out dx, al
in al, dx
DEBUGF 1,'-> %x\n',al
jmp .loop
;--------------------------------------
.done:
ret
endp
IDE_Interrupt dw ?
IDEContrRegsBaseAddr dw ?
IDEContrProgrammingInterface dw ?
IDE_BAR0_val dw ?
IDE_BAR1_val dw ?
IDE_BAR2_val dw ?
IDE_BAR3_val dw ?
endg
;-----------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/blkdev/disk.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16,7 → 16,6
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
DISK_STATUS_NO_MEMORY = 4 ; insufficient memory for driver operation
; Driver flags. Represent bits in DISK.DriverFlags.
DISK_NO_INSERT_NOTIFICATION = 1
; Media flags. Represent bits in DISKMEDIAINFO.Flags.
102,6 → 101,8
; 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
108,7 → 109,6
data dd ?
sad_size dd ?
search_start dd ?
sector_size_log dd ?
ends
 
; This structure represents a disk device and its media for the kernel.
169,8 → 169,6
; Pointer to array of .NumPartitions pointers to PARTITION structures.
cache_size dd ?
; inherited from cache_ideX_size
CacheLock MUTEX
; Lock to protect both caches.
SysCache DISKCACHE
AppCache DISKCACHE
; Two caches for the disk.
272,13 → 270,13
endg
 
iglobal
; The function 'disk_scan_partitions' needs three sector-sized buffers for
; 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. Also, the heap is used when sector size is other than 512.
; 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
639,18 → 637,21
; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list.
and [esi+DISK.NumPartitions], 0
and [esi+DISK.Partitions], 0
; 2. Acquire the buffer for MBR and bootsector tests. See the comment before
; 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 eax, [esi+DISK.MediaInfo.SectorSize]
cmp eax, 512
jnz @f
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
@@:
lea eax, [eax*3]
stdcall kernel_alloc, eax
stdcall kernel_alloc, 512*3
test eax, eax
jz .nothing
xchg eax, ebx
657,7 → 658,7
.buffer_acquired:
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no
; more than MAX_NUM_PARTITION times.
; 3. Prepare things for the loop.
; 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.
666,10 → 667,6
push MAX_NUM_PARTITIONS ; the counter of max MBRs to process
xor ebp, ebp ; start from sector zero
push ebp ; no extended partition yet
; 4. MBR is 512 bytes long. If sector size is less than 512 bytes,
; assume no MBR, no partitions and go to 10.
cmp [esi+DISK.MediaInfo.SectorSize], 512
jb .notmbr
.new_mbr:
; 5. Read the current sector.
; Note that 'read' callback operates with 64-bit sector numbers, so we must
988,7 → 985,7
; a three-sectors-sized buffer. This function saves ebx in the stack
; immediately before ebp.
mov ebx, [ebp-4] ; get buffer
add ebx, [esi+DISK.MediaInfo.SectorSize] ; advance over MBR data to bootsector data
add ebx, 512 ; advance over MBR data to bootsector data
add ebp, 8 ; ebp points to part of PARTITION structure
xor eax, eax ; first sector of the partition
call fs_read32_sys
999,7 → 996,7
; ebp -> first three fields of PARTITION structure, .start, .length, .disk;
; [esp] = error code after bootsector read: 0 = ok, otherwise = failed,
; ebx points to the buffer for bootsector,
; ebx+[esi+DISK.MediaInfo.SectorSize] points to sector-sized buffer that can be used for anything.
; ebx+512 points to 512-bytes buffer that can be used for anything.
call fat_create_partition
test eax, eax
jnz .success
/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc
379,16 → 379,10
mov al, 8
call FDCDataOutput
call FDCDataInput
push eax
; DEBUGF 1,' %x',al
call FDCDataInput
; DEBUGF 1,' %x',al
; DEBUGF 1,'\n'
pop eax
test al, 0xC0
jz @f
mov [FDC_Status], FDC_DiskNotFound
@@:
.fail:
call save_timer_fdd_motor
popa
/kernel/branches/Kolibri-acpi/blkdev/rd.inc
22,6 → 22,11
.size = $ - ramdisk_functions
endg
 
; See memmap.inc.
; Currently size of memory allocated for the ramdisk is fixed.
; This should be revisited when/if memory map would become more dynamic.
RAMDISK_CAPACITY = 2880 ; in sectors
 
iglobal
align 4
ramdisk_actual_size dd RAMDISK_CAPACITY
/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7,515 → 7,6
 
$Revision: 3742 $
 
; Read/write functions try to do large operations,
; it is significantly faster than several small operations.
; This requires large buffers.
; We can't use input/output buffers directly - they can be controlled
; by user-mode application, so they can be modified between the operation
; and copying to/from cache, giving invalid data in cache.
; It is unclear how to use cache directly, currently cache items are
; allocated/freed sector-wise, so items for sequential sectors can be
; scattered over all the cache.
; So read/write functions allocate a temporary buffer which is
; 1) not greater than half of free memory and
; 2) not greater than the following constant.
CACHE_MAX_ALLOC_SIZE = 4 shl 20
 
; Legacy interface for filesystems fs_{read,write}32_{sys,app}
; gives only one sector for FS. However, per-sector reading is inefficient,
; so internally fs_read32_{sys,app} reads to the cache several sequential
; sectors, hoping that they will be useful.
; Total number of sectors is given by the following constant.
CACHE_LEGACY_READ_SIZE = 16
 
; This structure describes one item in the cache.
struct CACHE_ITEM
SectorLo dd ? ; low 32 bits of sector
SectorHi dd ? ; high 32 bits of sector
Status dd ? ; one of CACHE_ITEM_*
ends
 
; Possible values for CACHE_ITEM_*
CACHE_ITEM_EMPTY = 0
CACHE_ITEM_COPY = 1
CACHE_ITEM_MODIFIED = 2
 
; Read several sequential sectors using cache #1.
; in: edx:eax = start sector, relative to start of partition
; in: ecx = number of sectors to read
; in: ebx -> buffer
; in: ebp -> PARTITION
; out: eax = error code, 0 = ok
; out: ecx = number of sectors that were read
fs_read64_sys:
; Save ebx, set ebx to SysCache and let the common part do its work.
push ebx ebx
mov ebx, [ebp+PARTITION.Disk]
add ebx, DISK.SysCache
jmp fs_read64_common
 
; Read several sequential sectors using cache #2.
; in: edx:eax = start sector, relative to start of partition
; in: ecx = number of sectors to read
; in: edi -> buffer
; in: ebp -> PARTITION
; out: eax = error code, 0 = ok
; out: ecx = number of sectors that were read
fs_read64_app:
; Save ebx, set ebx to AppCache and let the common part do its work.
push ebx ebx
mov ebx, [ebp+PARTITION.Disk]
add ebx, DISK.AppCache
 
; Common part of fs_read64_{app,sys}:
; read several sequential sectors using the given cache.
fs_read64_common:
; 1. Setup stack frame.
push esi edi ; save used registers to be stdcall
push 0 ; initialize .error_code
push ebx edx eax ecx ecx ; initialize stack variables
virtual at esp
.local_vars:
.num_sectors_orig dd ?
; Number of sectors that should be read. Used to generate output value of ecx.
.num_sectors dd ?
; Number of sectors that remain to be read. Decreases from .num_sectors_orig to 0.
.sector_lo dd ? ; low 32 bits of the current sector
.sector_hi dd ? ; high 32 bits of the current sector
.cache dd ? ; pointer to DISKCACHE
.error_code dd ? ; current status
.local_vars_size = $ - .local_vars
.saved_regs rd 2
.buffer dd ? ; filled by fs_read64_{sys,app}
end virtual
; 2. Validate parameters against partition length:
; immediately return error if edx:eax are beyond partition end,
; decrease .num_sectors and .num_sectors_orig, if needed,
; so that the entire operation fits in the partition limits.
mov eax, dword [ebp+PARTITION.Length]
mov edx, dword [ebp+PARTITION.Length+4]
sub eax, [.sector_lo]
sbb edx, [.sector_hi]
jb .end_of_media
jnz .no_end_of_media
cmp ecx, eax
jbe .no_end_of_media
; If .num_sectors got decreased, set status to DISK_STATUS_END_OF_MEDIA;
; if all subsequent operations would be successful, this would become the final
; status, otherwise this would be rewritten by failed operation.
mov [.num_sectors], eax
mov [.num_sectors_orig], eax
mov [.error_code], DISK_STATUS_END_OF_MEDIA
.no_end_of_media:
; 3. If number of sectors to read is zero, either because zero-sectors operation
; was requested or because it got decreased to zero due to partition limits,
; just return the current status.
cmp [.num_sectors], 0
jz .return
; 4. Shift sector from partition-relative to absolute.
mov eax, dword [ebp+PARTITION.FirstSector]
mov edx, dword [ebp+PARTITION.FirstSector+4]
add [.sector_lo], eax
adc [.sector_hi], edx
; 5. If the cache is disabled, pass the request directly to the driver.
cmp [ebx+DISKCACHE.pointer], 0
jz .nocache
; 6. Look for sectors in the cache, sequentially from the beginning.
; Stop at the first sector that is not in the cache
; or when all sectors were read from the cache.
; 6a. Acquire the lock.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_lock
.lookup_in_cache_loop:
; 6b. For each sector, call the lookup function without adding to the cache.
mov eax, [.sector_lo]
mov edx, [.sector_hi]
call cache_lookup_read
; 6c. If it has failed, the sector is not in cache;
; release the lock and go to 7.
jc .not_found_in_cache
; The sector is found in cache.
; 6d. Copy data for the caller, advance [.buffer].
mov esi, edi
mov edi, [.buffer]
mov eax, 1
shl eax, cl
mov ecx, eax
shr ecx, 2
rep movsd
mov [.buffer], edi
; 6e. Advance the sector.
add [.sector_lo], 1
adc [.sector_hi], 0
; 6f. Decrement number of sectors left.
; If all sectors were read, release the lock and return.
dec [.num_sectors]
jnz .lookup_in_cache_loop
; Release the lock acquired at 6a.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_unlock
.return:
mov eax, [.error_code]
mov ecx, [.num_sectors_orig]
sub ecx, [.num_sectors]
.nothing:
add esp, .local_vars_size
pop edi esi ebx ebx ; restore used registers to be stdcall
ret
.not_found_in_cache:
; Release the lock acquired at 6a.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_unlock
; The current sector is not present in the cache.
; Ask the driver to read all requested not-yet-read sectors,
; put results in the cache.
; Also, see the comment before the definition of CACHE_MAX_ALLOC_SIZE.
; 7. Allocate buffer for operations.
; Normally, create buffer that is sufficient for all remaining data.
; However, for extra-large requests make an upper limit:
; do not use more than half of the free memory
; or more than CACHE_MAX_ALLOC_SIZE bytes.
mov ecx, [ebx+DISKCACHE.sector_size_log]
mov ebx, [pg_data.pages_free]
shr ebx, 1
jz .nomemory
cmp ebx, CACHE_MAX_ALLOC_SIZE shr 12
jbe @f
mov ebx, CACHE_MAX_ALLOC_SIZE shr 12
@@:
shl ebx, 12
shr ebx, cl
jz .nomemory
cmp ebx, [.num_sectors]
jbe @f
mov ebx, [.num_sectors]
@@:
mov eax, ebx
shl eax, cl
stdcall kernel_alloc, eax
; If failed, return the appropriate error code.
test eax, eax
jz .nomemory
mov esi, eax
; Split the request to chunks that fit in the allocated buffer.
.read_loop:
; 8. Get iteration size: either size of allocated buffer in sectors
; or number of sectors left, select what is smaller.
cmp ebx, [.num_sectors]
jbe @f
mov ebx, [.num_sectors]
@@:
; 9. Create second portion of local variables.
; Note that variables here and above are esp-relative;
; it means that all addresses should be corrected when esp is changing.
push ebx esi esi
push ebx
; In particular, num_sectors is now [.num_sectors+.local_vars2_size].
virtual at esp
.local_vars2:
.current_num_sectors dd ? ; number of sectors that were read
.current_buffer dd ?
; pointer inside .allocated_buffer that points
; to the beginning of not-processed data
.allocated_buffer dd ? ; saved in safe place
.iteration_size dd ? ; saved in safe place
.local_vars2_size = $ - .local_vars2
end virtual
; 10. Call the driver, reading the next chunk.
push esp ; numsectors
push [.sector_hi+.local_vars2_size+4] ; startsector
push [.sector_lo+.local_vars2_size+8] ; startsector
push esi ; buffer
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.read
call disk_call_driver
; If failed, save error code.
test eax, eax
jz @f
mov [.error_code+.local_vars2_size], eax
@@:
; 11. Copy data for the caller, advance .buffer.
cmp [.current_num_sectors], 0
jz .copy_done
mov ebx, [.cache+.local_vars2_size]
mov eax, [.current_num_sectors]
mov ecx, [ebx+DISKCACHE.sector_size_log]
shl eax, cl
mov esi, [.allocated_buffer]
mov edi, [.buffer+.local_vars2_size]
mov ecx, eax
shr ecx, 2
rep movsd
mov [.buffer+.local_vars2_size], edi
; 12. Copy data to the cache.
; 12a. Acquire the lock.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_lock
; 12b. Prepare for the loop: create a local variable that
; stores number of sectors to be copied.
push [.current_num_sectors]
.store_to_cache:
; 12c. For each sector, call the lookup function with adding to the cache, if not yet.
mov eax, [.sector_lo+.local_vars2_size+4]
mov edx, [.sector_hi+.local_vars2_size+4]
call cache_lookup_write
test eax, eax
jnz .cache_error
; 12d. If the sector was already present in the cache as modified,
; data that were read at step 10 for this sector are obsolete,
; so rewrite data for the caller from the cache.
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
jnz .not_modified
mov esi, edi
mov edi, [.buffer+.local_vars2_size+4]
mov eax, [esp]
shl eax, cl
sub edi, eax
mov eax, 1
shl eax, cl
mov ecx, eax
shr ecx, 2
rep movsd
add [.current_buffer+4], eax
jmp .sector_done
.not_modified:
; 12e. For each not-modified sector,
; copy data, mark the item as not-modified copy of the disk,
; advance .current_buffer and .sector_hi:.sector_lo to the next sector.
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
mov eax, 1
shl eax, cl
mov esi, [.current_buffer+4]
mov ecx, eax
shr ecx, 2
rep movsd
mov [.current_buffer+4], esi
.sector_done:
add [.sector_lo+.local_vars2_size+4], 1
adc [.sector_hi+.local_vars2_size+4], 0
; 12f. Continue the loop 12c-12e until all sectors are read.
dec dword [esp]
jnz .store_to_cache
.cache_error:
; 12g. Restore after the loop: pop the local variable.
pop ecx
; 12h. Release the lock.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_unlock
.copy_done:
; 13. Remove portion of local variables created at step 9.
pop ecx
pop esi esi ebx
; 14. Continue iterations while number of sectors read by the driver
; is equal to number of sectors requested and there are additional sectors.
cmp ecx, ebx
jnz @f
sub [.num_sectors], ebx
jnz .read_loop
@@:
; 15. Free the buffer allocated at step 7 and return.
stdcall kernel_free, esi
jmp .return
 
; Special branches:
.nomemory:
; memory allocation failed at step 7: return the corresponding error
mov [.error_code], DISK_STATUS_NO_MEMORY
jmp .return
.nocache:
; step 5, after correcting number of sectors to fit in partition limits
; and advancing partition-relative sector to absolute,
; sees that cache is disabled: pass corrected request to the driver
lea eax, [.num_sectors]
push eax ; numsectors
push [.sector_hi+4] ; startsector
push [.sector_lo+8] ; startsector
push [.buffer+12] ; buffer
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.read
call disk_call_driver
test eax, eax
jnz @f
mov eax, [.error_code]
@@:
mov ecx, [.num_sectors]
jmp .nothing
.end_of_media:
; requested sector is beyond the partition end: return the corresponding error
mov [.error_code], DISK_STATUS_END_OF_MEDIA
jmp .return
 
; Write several sequential sectors using cache #1.
; in: edx:eax = start sector
; in: ecx = number of sectors to write
; in: ebx -> buffer
; in: ebp -> PARTITION
; out: eax = error code, 0 = ok
; out: ecx = number of sectors that were written
fs_write64_sys:
; Save ebx, set ebx to SysCache and let the common part do its work.
push ebx
mov ebx, [ebp+PARTITION.Disk]
add ebx, DISK.SysCache
jmp fs_write64_common
 
; Write several sequential sectors using cache #2.
; in: edx:eax = start sector
; in: ecx = number of sectors to write
; in: ebx -> buffer
; in: ebp -> PARTITION
; out: eax = error code, 0 = ok
; out: ecx = number of sectors that were written
fs_write64_app:
; Save ebx, set ebx to AppCache and let the common part do its work.
push ebx
mov ebx, [ebp+PARTITION.Disk]
add ebx, DISK.AppCache
 
; Common part of fs_write64_{app,sys}:
; write several sequential sectors using the given cache.
fs_write64_common:
; 1. Setup stack frame.
push esi edi ; save used registers to be stdcall
push 0 ; initialize .error_code
push edx eax ecx ecx ; initialize stack variables
push [.buffer-4] ; copy [.buffer] to [.cur_buffer]
; -4 is due to esp-relative addressing
virtual at esp
.local_vars:
.cur_buffer dd ? ; pointer to data that are currently copying
.num_sectors_orig dd ?
; Number of sectors that should be written. Used to generate output value of ecx.
.num_sectors dd ?
; Number of sectors that remain to be written.
.sector_lo dd ? ; low 32 bits of the current sector
.sector_hi dd ? ; high 32 bits of the current sector
.error_code dd ? ; current status
.local_vars_size = $ - .local_vars
.saved_regs rd 2
.buffer dd ? ; filled by fs_write64_{sys,app}
end virtual
; 2. Validate parameters against partition length:
; immediately return error if edx:eax are beyond partition end,
; decrease .num_sectors and .num_sectors_orig, if needed,
; so that the entire operation fits in the partition limits.
mov eax, dword [ebp+PARTITION.Length]
mov edx, dword [ebp+PARTITION.Length+4]
sub eax, [.sector_lo]
sbb edx, [.sector_hi]
jb .end_of_media
jnz .no_end_of_media
cmp ecx, eax
jbe .no_end_of_media
; If .num_sectors got decreased, set status to DISK_STATUS_END_OF_MEDIA;
; if all subsequent operations would be successful, this would become the final
; status, otherwise this would be rewritten by failed operation.
mov [.num_sectors], eax
mov [.num_sectors_orig], eax
mov [.error_code], DISK_STATUS_END_OF_MEDIA
.no_end_of_media:
; 3. If number of sectors to write is zero, either because zero-sectors operation
; was requested or because it got decreased to zero due to partition limits,
; just return the current status.
cmp [.num_sectors], 0
jz .return
; 4. Shift sector from partition-relative to absolute.
mov eax, dword [ebp+PARTITION.FirstSector]
mov edx, dword [ebp+PARTITION.FirstSector+4]
add [.sector_lo], eax
adc [.sector_hi], edx
; 5. If the cache is disabled, pass the request directly to the driver.
cmp [ebx+DISKCACHE.pointer], 0
jz .nocache
; 6. Store sectors in the cache, sequentially from the beginning.
; 6a. Acquire the lock.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_lock
.lookup_in_cache_loop:
; 6b. For each sector, call the lookup function with adding to the cache, if not yet.
mov eax, [.sector_lo]
mov edx, [.sector_hi]
call cache_lookup_write
test eax, eax
jnz .cache_error
; 6c. For each sector, copy data, mark the item as modified and not saved,
; advance .current_buffer to the next sector.
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
mov eax, 1
shl eax, cl
mov esi, [.cur_buffer]
mov ecx, eax
shr ecx, 2
rep movsd
mov [.cur_buffer], esi
; 6d. Remove the sector from the other cache.
; Normally it should not be there, but prefetching could put to the app cache
; data that normally should belong to the sys cache and vice versa.
; Note: this requires that both caches must be protected by the same lock.
mov eax, [.sector_lo]
mov edx, [.sector_hi]
push ebx
sub ebx, [ebp+PARTITION.Disk]
xor ebx, DISK.SysCache xor DISK.AppCache
add ebx, [ebp+PARTITION.Disk]
call cache_lookup_read
jc @f
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY
@@:
pop ebx
; 6e. Advance .sector_hi:.sector_lo to the next sector.
add [.sector_lo], 1
adc [.sector_hi], 0
; 6f. Continue the loop at 6b-6e until all sectors are processed.
dec [.num_sectors]
jnz .lookup_in_cache_loop
.unlock_return:
; 6g. Release the lock and return.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_unlock
.return:
mov eax, [.error_code]
mov ecx, [.num_sectors_orig]
sub ecx, [.num_sectors]
.nothing:
add esp, .local_vars_size
pop edi esi ebx
ret
 
; Special branches:
.cache_error:
; error at flushing the cache while adding sector to the cache:
; return the error from the lookup function
mov [.error_code], eax
jmp .unlock_return
.end_of_media:
; requested sector is beyond the partition end: return the corresponding error
mov eax, DISK_STATUS_END_OF_MEDIA
xor ecx, ecx
jmp .nothing
.nocache:
; step 5, after correcting number of sectors to fit in partition limits
; and advancing partition-relative sector to absolute,
; sees that cache is disabled: pass corrected request to the driver
lea eax, [.num_sectors]
push eax ; numsectors
push [.sector_hi+4] ; startsector
push [.sector_lo+8] ; startsector
push [.buffer+12] ; buffer
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.write
call disk_call_driver
mov ecx, [.num_sectors]
jmp .nothing
 
; Legacy. Use fs_read64_sys instead.
; 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'.
523,13 → 14,12
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_read32_sys:
; Save ebx, set ebx to SysCache and let the common part do its work.
push ebx
mov ebx, [ebp+PARTITION.Disk]
add ebx, DISK.SysCache
; 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
 
; Legacy. Use fs_read64_app instead.
; 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'.
537,10 → 27,10
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_read32_app:
; Save ebx, set ebx to AppCache and let the common part do its work.
push ebx
mov ebx, [ebp+PARTITION.Disk]
add ebx, DISK.AppCache
; 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:
551,224 → 41,119
cmp dword [ebp+PARTITION.Length], eax
ja @f
mov eax, DISK_STATUS_END_OF_MEDIA
pop ebx
pop ecx
ret
@@:
; 2. Get the absolute sector on the disk.
push ecx edx esi edi
push edx esi
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 [ebx+DISKCACHE.pointer], 0
cmp [ecx+DISKCACHE.pointer], 0
jnz .scancache
push 1
push esp ; numsectors
push edx ; startsector
push eax ; startsector
pushd [esp+32]; buffer
push ebx ; buffer
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.read
call disk_call_driver
pop ecx
pop edi esi edx ecx
pop ebx
pop esi edx
pop ecx
ret
.scancache:
push ebx edx eax
; 4. Scan the cache.
push edi ecx ; scan cache
push edx eax
virtual at esp
.local_vars:
.sector_lo dd ?
.sector_hi dd ?
.cache dd ?
.local_vars_size = $ - .local_vars
.saved_regs rd 4
.buffer dd ?
end virtual
; 4. Scan for the requested sector in the cache.
; If found, copy the data and return.
; 4a. Acquire the lock.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
; 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
; 4b. Call the lookup function without adding to the cache.
mov eax, [.sector_lo]
mov edx, [.sector_hi]
call cache_lookup_read
; If not found, go to 5.
jc .not_found_in_cache
.found_in_cache:
; 4c. Copy the data.
mov esi, edi
mov edi, [.buffer]
mov eax, 1
shl eax, cl
mov ecx, eax
shr ecx, 2
rep movsd
; 4d. Release the lock and return success.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_unlock
.return:
xor eax, eax
.return_eax:
add esp, .local_vars_size
pop edi esi edx ecx
pop ebx
ret
.not_found_in_cache:
; 5. Decide whether we need to prefetch further sectors.
; If so, advance to 6. If not, go to 13.
; Assume that devices < 3MB are floppies which are slow
; (ramdisk does not have a cache, so we don't even get here for ramdisk).
; This is a dirty hack, but the entire function is somewhat hacky. Use fs_read64*.
mov ecx, [ebp+PARTITION.Disk]
cmp dword [ecx+DISK.MediaInfo.Capacity+4], 0
jnz @f
cmp dword [ecx+DISK.MediaInfo.Capacity], 3 shl (20-9)
jb .floppy
@@:
; We want to prefetch CACHE_LEGACY_READ_SIZE sectors.
; 6. Release the lock acquired at step 4a.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_unlock
; 7. Allocate buffer for CACHE_LEGACY_READ_SIZE sectors.
mov eax, CACHE_LEGACY_READ_SIZE
mov ecx, [ebx+DISKCACHE.sector_size_log]
shl eax, cl
stdcall kernel_alloc, eax
; If failed, return the corresponding error code.
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
jz .nomemory
; 8. Create second portion of local variables.
push eax eax
push CACHE_LEGACY_READ_SIZE
virtual at esp
.local_vars2:
.num_sectors dd ? ; number of sectors left
.current_buffer dd ? ; pointer to data that are currently copying
.allocated_buffer dd ? ; saved at safe place
.local_vars2_size = $ - .local_vars2
end virtual
; 9. Call the driver to read CACHE_LEGACY_READ_SIZE sectors.
push esp ; numsectors
push [.sector_hi+.local_vars2_size+4] ; startsector
push [.sector_lo+.local_vars2_size+8] ; startsector
push eax ; buffer
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.read
call disk_call_driver
; Note: we're ok if at least one sector is read,
; read error somewhere after that just limits data to be put in cache.
cmp [.num_sectors], 0
jz .read_error
; 10. Copy data for the caller.
mov esi, [.allocated_buffer]
mov edi, [.buffer+.local_vars2_size]
mov ecx, [ebx+DISKCACHE.sector_size_log]
mov eax, 1
shl eax, cl
mov ecx, eax
shr ecx, 2
rep movsd
; 11. Store all sectors that were successfully read to the cache.
; 11a. Acquire the lock.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_lock
.store_to_cache:
; 11b. For each sector, call the lookup function with adding to the cache, if not yet.
mov eax, [.sector_lo+.local_vars2_size]
mov edx, [.sector_hi+.local_vars2_size]
call cache_lookup_write
test eax, eax
jnz .cache_error
; 11c. Ignore sectors marked as modified: for them the cache is more recent that disk data.
mov eax, 1
shl eax, cl
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
jnz .not_modified
add [.current_buffer], eax
jmp .sector_done
.not_modified:
; 11d. For each sector, copy data, mark the item as not-modified copy of the disk,
; advance .current_buffer and .sector_hi:.sector_lo to the next sector.
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
mov esi, [.current_buffer]
mov ecx, eax
shr ecx, 2
rep movsd
mov [.current_buffer], esi
.sector_done:
add [.sector_lo+.local_vars2_size], 1
adc [.sector_hi+.local_vars2_size], 0
; 11e. Continue the loop at 11b-11d until all sectors are processed.
dec [.num_sectors]
jnz .store_to_cache
.cache_error:
; 11f. Release the lock.
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
call mutex_unlock
.copy_done:
; 12. Remove portion of local variables created at step 8,
; free the buffer allocated at step 7 and return.
pop ecx ecx
stdcall kernel_free
jmp .return
.read_error:
; If no sectors were read, free the buffer allocated at step 7
; and pass the error to the caller.
push eax
stdcall kernel_free, [.allocated_buffer+4]
pop eax
add esp, .local_vars2_size
jmp .return_eax
.nomemory:
mov eax, DISK_STATUS_NO_MEMORY
jmp .return_eax
.floppy:
; We don't want to prefetch anything, just read one sector.
; We are still holding the lock acquired at step 4a.
; 13. Call the lookup function adding sector to the cache.
call cache_lookup_write
test eax, eax
jnz .floppy_cache_error
push esi
jnz .read_done
 
; 14. Call the driver to read one sector.
push 1
push esp
push edx
push [.sector_lo+16]
push edi
push [.sector_lo+12]
mov ecx, [.cache+16]
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 .floppy_read_error
; 15. Get the slot and pointer to the cache item,
; change the status to not-modified copy of the disk
; and go to 4c.
pop esi
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
mov ecx, [ebx+DISKCACHE.sector_size_log]
jmp .found_in_cache
jnz .read_done
 
; On error at steps 13-14, release the lock
; and pass the error to the caller.
.floppy_read_error:
pop ecx
.floppy_cache_error:
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.CacheLock
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
jmp .return_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
777,13 → 162,11
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_write32_sys:
; Just call the advanced function.
push ecx edx
xor edx, edx
mov ecx, 1
call fs_write64_sys
pop edx ecx
ret
; 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
792,93 → 175,144
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_write32_app:
; Just call the advanced function.
push ecx edx
; 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 esi
; 2. Get the absolute sector on the disk.
xor edx, edx
mov ecx, 1
call fs_write64_app
pop edx ecx
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 esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.write
call disk_call_driver
pop ecx
pop esi edx
pop ecx
ret
.scancache:
; 4. Scan the cache.
push 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
 
; Lookup for the given sector in the given cache.
; If the sector is not present, return error.
; The caller must acquire the cache lock.
; in: edx:eax = sector
; in: ebx -> DISKCACHE structure
; out: CF set if sector is not in cache
; out: ecx = sector_size_log
; out: esi -> sector:status
; out: edi -> sector data
proc cache_lookup_read
mov esi, [ebx+DISKCACHE.pointer]
add esi, sizeof.CACHE_ITEM
; 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
 
.hdreadcache:
.hdwritecache:
cmp dword [esi+8], 0 ; if cache slot is empty
je .not_in_cache_write
 
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY
je .nohdcache
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
 
cmp [esi+CACHE_ITEM.SectorLo], eax
jne .nohdcache
cmp [esi+CACHE_ITEM.SectorHi], edx
jne .nohdcache
mov ecx, [ebx+DISKCACHE.sector_size_log]
shl edi, cl
add edi, [ebx+DISKCACHE.data]
clc
ret
.not_in_cache_write:
 
.nohdcache:
add esi, 12
inc edi
dec ecx
jnz .hdwritecache
 
add esi, sizeof.CACHE_ITEM
inc edi
cmp edi, [ebx+DISKCACHE.sad_size]
jbe .hdreadcache
stc
; 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+8], 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
endp
 
; Lookup for the given sector in the given cache.
; If the sector is not present, allocate space for it,
; possibly flushing data.
; in: edx:eax = sector
; in: ebx -> DISKCACHE structure
; in: ebp -> PARTITION structure
; out: eax = error code
; out: esi -> sector:status
; out: edi -> sector data
proc cache_lookup_write
call cache_lookup_read
jnc .return0
push edx eax
; 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 : ecx = cache slot
; output : edi = cache slot
;-----------------------------------------------------------
; Note: the code is essentially inherited, so probably
; no analysis of efficiency were done.
; However, it works.
.search_again:
mov eax, [ebx+DISKCACHE.sad_size]
mov ecx, [ebx+DISKCACHE.search_start]
shr eax, 3
lea esi, [ecx*sizeof.CACHE_ITEM/4]
shl esi, 2
add esi, [ebx+DISKCACHE.pointer]
mov ecx, [esi+DISKCACHE.sad_size]
mov edi, [esi+DISKCACHE.search_start]
shr ecx, 3
.search_for_empty:
inc ecx
add esi, sizeof.CACHE_ITEM
cmp ecx, [ebx+DISKCACHE.sad_size]
inc edi
cmp edi, [esi+DISKCACHE.sad_size]
jbe .inside_cache
mov ecx, 1
mov esi, [ebx+DISKCACHE.pointer]
add esi, sizeof.CACHE_ITEM
mov edi, 1
.inside_cache:
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
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 eax
dec ecx
jnz .search_for_empty
stdcall write_cache64, [ebp+PARTITION.Disk] ; no empty slots found, write all
test eax, eax
885,338 → 319,125
jne .found_slot_access_denied
jmp .search_again ; and start again
.found_slot:
mov [ebx+DISKCACHE.search_start], ecx
popd [esi+CACHE_ITEM.SectorLo]
popd [esi+CACHE_ITEM.SectorHi]
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY
mov edi, ecx
mov ecx, [ebx+DISKCACHE.sector_size_log]
shl edi, cl
add edi, [ebx+DISKCACHE.data]
.return0:
mov [esi+DISKCACHE.search_start], edi
xor eax, eax ; success
ret
.found_slot_access_denied:
add esp, 8
ret
endp
 
; Flush the given cache.
; The caller must acquire the cache lock.
; in: ebx -> DISKCACHE
; in: first argument in stdcall convention -> PARTITION
proc write_cache64
; 1. Setup stack frame.
push esi edi ; save used registers to be stdcall
sub esp, .local_vars_size ; reserve space for local vars
virtual at esp
.local_vars:
.cache_end dd ? ; item past the end of the cache
.size_left dd ? ; items left to scan
.current_ptr dd ? ; pointer to the current item
;
; Write operations are coalesced in chains,
; one chain describes a sequential interval of sectors,
; they can be sequential or scattered in the cache.
.sequential dd ?
; boolean variable, 1 if the current chain is sequential in the cache,
; 0 if additional buffer is needed to perform the operation
.chain_start_pos dd ? ; data of chain start item
.chain_start_ptr dd ? ; pointer to chain start item
.chain_size dd ? ; chain size (thanks, C.O.)
.iteration_size dd ?
; If the chain size is too large, split the operation to several iterations.
; This is size in sectors for one iterations.
.iteration_buffer dd ? ; temporary buffer for non-sequential chains
.local_vars_size = $ - .local_vars
rd 2 ; saved registers
dd ? ; return address
.disk dd ? ; first argument
end virtual
; 1. If there is no cache for this disk, nothing to do, just return zero.
cmp [ebx+DISKCACHE.pointer], 0
jz .return0
; 2. Prepare for the loop: initialize current pointer and .size_left,
; calculate .cache_end.
mov ecx, [ebx+DISKCACHE.sad_size]
mov [.size_left], ecx
lea ecx, [ecx*sizeof.CACHE_ITEM/4]
shl ecx, 2
mov esi, [ebx+DISKCACHE.pointer]
add esi, sizeof.CACHE_ITEM
add ecx, esi
mov [.cache_end], ecx
; 3. Main loop: go over all items, go to 5 for every modified item.
.look:
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
jz .begin_write
.look_next:
add esi, sizeof.CACHE_ITEM
dec [.size_left]
jnz .look
; 4. Return success.
.return0:
xor eax, eax
.return:
add esp, .local_vars_size
pop edi esi ; restore used registers to be stdcall
ret 4 ; return popping one argument
.begin_write:
; We have found a modified item.
; 5. Prepare for chain finding: save the current item, initialize chain variables.
mov [.current_ptr], esi
; Initialize chain as sequential zero-length starting at the current item.
mov [.chain_start_ptr], esi
mov eax, [ebx+DISKCACHE.sad_size]
sub eax, [.size_left]
inc eax
mov ecx, [ebx+DISKCACHE.sector_size_log]
shl eax, cl
add eax, [ebx+DISKCACHE.data]
mov [.chain_start_pos], eax
mov [.chain_size], 0
mov [.sequential], 1
; 6. Expand the chain backward.
; Note: the main loop in step 2 looks for items sequentially,
; so the previous item is not modified. If the previous sector
; is present in the cache, it automatically makes the chain scattered.
; 6a. Calculate sector number: one before the sector for the current item.
mov eax, [esi+CACHE_ITEM.SectorLo]
mov edx, [esi+CACHE_ITEM.SectorHi]
sub eax, 1
sbb edx, 0
.find_chain_start:
; 6b. For each sector where the previous item does not expand the chain,
; call the lookup function without adding to the cache.
call cache_lookup_read
; 6c. If the sector is not found in cache or is not modified, stop expanding
; and advance to step 7.
jc .found_chain_start
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
jnz .found_chain_start
; 6d. We have found a new block that expands the chain backwards.
; It makes the chain non-sequential.
; Normally, sectors come in sequential blocks, so try to look at previous items
; before returning to 6b; if there is a sequential block indeed, this saves some
; time instead of many full-fledged lookups.
mov [.sequential], 0
mov [.chain_start_pos], edi
.look_backward:
; 6e. For each sector, update chain start pos/ptr, decrement sector number,
; look at the previous item.
mov [.chain_start_ptr], esi
inc [.chain_size]
sub eax, 1
sbb edx, 0
sub esi, sizeof.CACHE_ITEM
; If the previous item exists...
cmp esi, [ebx+DISKCACHE.pointer]
jbe .find_chain_start
; ...describes the correct sector...
cmp [esi+CACHE_ITEM.SectorLo], eax
jnz .find_chain_start
cmp [esi+CACHE_ITEM.SectorHi], edx
jnz .find_chain_start
; ...and is modified...
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
jnz .found_chain_start
; ...expand the chain one sector backwards and continue the loop at 6e.
; Otherwise, advance to step 7 if the previous item describes the correct sector
; but is not modified, and return to step 6b otherwise.
; This function is intended to replace the old 'write_cache' function.
proc write_cache64 uses ecx edx esi edi, disk:dword
locals
cache_chain_started dd 0
cache_chain_size dd ?
cache_chain_pos dd ?
cache_chain_ptr dd ?
endl
saved_esi_pos = 16+12 ; size of local variables + size of registers before esi
; 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
shl edi, cl
sub [.chain_start_pos], edi
jmp .look_backward
.found_chain_start:
; 7. Expand the chain forward.
; 7a. Prepare for the loop at 7b:
; set esi = pointer to current item, edx:eax = current sector.
mov esi, [.current_ptr]
mov eax, [esi+CACHE_ITEM.SectorLo]
mov edx, [esi+CACHE_ITEM.SectorHi]
.look_forward:
; 7b. First, look at the next item. If it describes the next sector:
; if it is modified, expand the chain with that sector and continue this step,
; if it is not modified, the chain is completed, so advance to step 8.
inc [.chain_size]
.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
add esi, sizeof.CACHE_ITEM
cmp esi, [.cache_end]
jae .find_chain_end
cmp [esi+CACHE_ITEM.SectorLo], eax
jnz .find_chain_end
cmp [esi+CACHE_ITEM.SectorHi], edx
jnz .find_chain_end
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
jnz .found_chain_end
jmp .look_forward
.find_chain_end:
; 7c. Otherwise, call the lookup function.
call cache_lookup_read
; 7d. If the next sector is present in the cache and is modified,
; mark the chain as non-sequential and continue to step 7b.
jc .found_chain_end
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
jnz .found_chain_end
mov [.sequential], 0
jmp .look_forward
.found_chain_end:
; 8. Decide whether the chain is sequential or scattered.
; Advance to step 9 for sequential chains, go to step 10 for scattered chains.
cmp [.sequential], 0
jz .write_non_sequential
.write_sequential:
; 9. Write a sequential chain to disk.
; 9a. Pass the entire chain to the driver.
mov eax, [.chain_start_ptr]
lea ecx, [.chain_size]
push ecx ; numsectors
pushd [eax+CACHE_ITEM.SectorHi] ; startsector
pushd [eax+CACHE_ITEM.SectorLo] ; startsector
push [.chain_start_pos+12] ; buffer
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.write
call disk_call_driver
; 9b. If failed, pass the error code to the driver.
test eax, eax
jnz .return
; 9c. If succeeded, mark all sectors in the chain as not-modified,
; advance current item and number of items left to skip the chain.
mov esi, [.current_ptr]
mov eax, [.chain_size]
sub [.size_left], eax
cmp eax, [esi+12]
jnz @f
cmp edx, [esi+12+4]
@@:
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
add esi, sizeof.CACHE_ITEM
dec eax
jnz @b
; 9d. Continue the main loop at step 2 if there are more sectors.
; Return success otherwise.
cmp [.size_left], 0
jnz .look
jmp .return0
.write_non_sequential:
; Write a non-sequential chain to the disk.
; 10. Allocate a temporary buffer.
; Use [.chain_size] sectors, but
; not greater than CACHE_MAX_ALLOC_SIZE bytes
; and not greater than half of free memory.
mov eax, [pg_data.pages_free]
shr eax, 1
jz .nomemory
cmp eax, CACHE_MAX_ALLOC_SIZE shr 12
jbe @f
mov eax, CACHE_MAX_ALLOC_SIZE shr 12
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
@@:
shl eax, 12
shr eax, cl
jz .nomemory
cmp eax, [.chain_size]
jbe @f
mov eax, [.chain_size]
@@:
mov [.iteration_size], eax
shl eax, cl
stdcall kernel_alloc, eax
inc [cache_chain_size]
cmp [cache_chain_size], 16
jnz .continue
jmp .write_chain
.nonext:
call .flush_cache_chain
test eax, eax
jz .nomemory
mov [.iteration_buffer], eax
.write_non_sequential_iteration:
; 11. Split the chain so that each iteration fits in the allocated buffer.
; Iteration size is the minimum of chain size and allocated size.
mov eax, [.chain_size]
cmp eax, [.iteration_size]
jae @f
mov [.iteration_size], 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, [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
@@:
; 12. Prepare arguments for the driver.
mov esi, [.chain_start_ptr]
mov edi, [.iteration_buffer]
push [.iteration_size]
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-saved_esi_pos]
shl edi, 9
add edi, [ecx+DISKCACHE.data]
mov ecx, [cache_chain_size]
push ecx
push esp ; numsectors
push [esi+CACHE_ITEM.SectorHi] ; startsector
push [esi+CACHE_ITEM.SectorLo] ; startsector
mov eax, [cache_chain_ptr]
pushd [eax+4]
pushd [eax] ; startsector
push edi ; buffer
; 13. Copy data from the cache to the temporary buffer,
; advancing chain_start pos/ptr and marking sectors as not-modified.
; 13a. Prepare for the loop: push number of sectors to process.
push [.iteration_size+20] ; temporary variable
.copy_loop:
; 13b. For each sector, copy the data.
; Note that edi is advanced automatically.
mov esi, [.chain_start_pos+24]
mov ecx, [ebx+DISKCACHE.sector_size_log]
mov eax, 1
shl eax, cl
mov ecx, eax
shr ecx, 2
rep movsd
mov ecx, eax ; keep for 13e
; 13c. Mark the item as not-modified.
mov esi, [.chain_start_ptr+24]
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
; 13d. Check whether the next sector continues the chain.
; If so, advance to 13e. Otherwise, go to 13f.
mov eax, [esi+CACHE_ITEM.SectorLo]
mov edx, [esi+CACHE_ITEM.SectorHi]
add esi, sizeof.CACHE_ITEM
add eax, 1
adc edx, 0
cmp esi, [.cache_end+24]
jae .no_forward
cmp [esi+CACHE_ITEM.SectorLo], eax
jnz .no_forward
cmp [esi+CACHE_ITEM.SectorHi], edx
jnz .no_forward
; 13e. Increment position/pointer to the chain and
; continue the loop.
add [.chain_start_pos+24], ecx
mov [.chain_start_ptr+24], esi
dec dword [esp]
jnz .copy_loop
jmp .copy_done
.no_forward:
; 13f. Call the lookup function without adding to the cache.
; Update position/pointer with returned value.
; Note: for the last sector in the chain, edi/esi may contain
; garbage; we are not going to use them in this case.
push edi
call cache_lookup_read
mov [.chain_start_pos+28], edi
mov [.chain_start_ptr+28], esi
pop edi
dec dword [esp]
jnz .copy_loop
.copy_done:
; 13g. Restore the stack after 13a.
pop ecx
; 14. Call the driver.
mov esi, [ebp+PARTITION.Disk]
mov esi, [ebp]
mov esi, [esi+PARTITION.Disk]
mov al, DISKFUNC.write
call disk_call_driver
pop ecx ; numsectors
; 15. If the driver has returned an error, free the buffer allocated at step 10
; and pass the error to the caller.
; Otherwise, remove the processed part from the chain and continue iterations
; starting in step 11 if there are more data to process.
test eax, eax
jnz .nonsequential_error
sub [.chain_size], ecx
jnz .write_non_sequential_iteration
; 16. The chain is written. Free the temporary buffer
; and continue the loop at step 2.
stdcall kernel_free, [.iteration_buffer]
mov esi, [.current_ptr]
jmp .look_next
.nonsequential_error:
push eax
stdcall kernel_free, [.iteration_buffer+4]
pop eax
jmp .return
.nomemory:
mov eax, DISK_STATUS_NO_MEMORY
jmp .return
pop ecx
mov [esp+28], eax
popa
retn
endp
 
; This internal function is called from disk_add to initialize the caching for
1231,32 → 452,13
; is most useful example of a non-trivial adjustment.
; esi = pointer to DISK structure
disk_init_cache:
; 1. Verify sector size. The code requires it to be a power of 2 not less than 4.
; In the name of sanity check that sector size is not too small or too large.
bsf ecx, [esi+DISK.MediaInfo.SectorSize]
jz .invalid_sector_size
mov eax, 1
shl eax, cl
cmp eax, [esi+DISK.MediaInfo.SectorSize]
jnz .invalid_sector_size
cmp ecx, 6
jb .invalid_sector_size
cmp ecx, 14
jbe .normal_sector_size
.invalid_sector_size:
DEBUGF 1,'K : sector size %x is invalid\n',[esi+DISK.MediaInfo.SectorSize]
xor eax, eax
ret
.normal_sector_size:
mov [esi+DISK.SysCache.sector_size_log], ecx
mov [esi+DISK.AppCache.sector_size_log], ecx
; 2. Calculate the suggested cache size.
; 2a. Get the size of free physical memory in pages.
; 1. Calculate the suggested cache size.
; 1a. Get the size of free physical memory in pages.
mov eax, [pg_data.pages_free]
; 2b. Use the value to calculate the size.
; 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
; 2c. Force lower and upper limits.
; 1c. Force lower and upper limits.
cmp eax, 1024*1024
jb @f
mov eax, 1024*1024
1265,7 → 467,7
ja @f
mov eax, 128*1024
@@:
; 2d. Give a chance to the driver to adjust the size.
; 1d. Give a chance to the driver to adjust the size.
push eax
mov al, DISKFUNC.adjust_cache_size
call disk_call_driver
1273,19 → 475,21
mov [esi+DISK.cache_size], eax
test eax, eax
jz .nocache
; 3. Allocate memory for the cache.
; 3a. Call the allocator.
; 2. Allocate memory for the cache.
; 2a. Call the allocator.
stdcall kernel_alloc, eax
test eax, eax
jnz @f
; 3b. If it failed, say a message and return with eax = 0.
; 2b. If it failed, say a message and return with eax = 0.
dbgstr 'no memory for disk cache'
jmp .nothing
@@:
; 4. Fill two DISKCACHE structures.
; 3. Fill two DISKCACHE structures.
mov [esi+DISK.SysCache.pointer], eax
lea ecx, [esi+DISK.CacheLock]
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
1299,7 → 503,9
mov [esi+DISK.AppCache.pointer], edx
 
mov eax, [esi+DISK.SysCache.data_size]
call calculate_cache_slots
push ebx
call calculate_for_hd64
pop ebx
add eax, [esi+DISK.SysCache.pointer]
mov [esi+DISK.SysCache.data], eax
mov [esi+DISK.SysCache.sad_size], ecx
1312,7 → 518,9
pop edi
 
mov eax, [esi+DISK.AppCache.data_size]
call calculate_cache_slots
push ebx
call calculate_for_hd64
pop ebx
add eax, [esi+DISK.AppCache.pointer]
mov [esi+DISK.AppCache.data], eax
mov [esi+DISK.AppCache.sad_size], ecx
1324,9 → 532,9
rep stosd
pop edi
 
; 5. Return with nonzero al.
; 4. Return with nonzero al.
mov al, 1
; 6. Return.
; 5. Return.
.nothing:
ret
; No caching is required for this driver. Zero cache pointers and return with
1337,16 → 545,18
mov al, 1
ret
 
calculate_cache_slots:
calculate_for_hd64:
push eax
mov ecx, [esi+DISK.MediaInfo.SectorSize]
add ecx, sizeof.CACHE_ITEM
xor edx, edx
div ecx
mov ecx, eax
imul eax, [esi+DISK.MediaInfo.SectorSize]
sub [esp], eax
mov ebx, eax
shr eax, 9
lea eax, [eax*3]
shl eax, 2
sub ebx, eax
shr ebx, 9
mov ecx, ebx
shl ebx, 9
pop eax
sub eax, ebx
dec ecx
ret
 
1367,21 → 577,12
; esi = pointer to DISK
disk_sync:
; The algorithm is straightforward.
cmp [esi+DISK.SysCache.pointer], 0
jz .nothing
lea ecx, [esi+DISK.CacheLock]
call mutex_lock
push ebx
push esi
push esi ; for second write_cache64
push esi ; for first write_cache64
lea ebx, [esi+DISK.SysCache]
add esi, DISK.SysCache
call write_cache64
add ebx, DISK.AppCache - DISK.SysCache
add esi, DISK.AppCache - DISK.SysCache
call write_cache64
pop ebx
lea ecx, [esi+DISK.CacheLock]
call mutex_unlock
.nothing:
mov al, DISKFUNC.flush
call disk_call_driver
pop esi
ret
/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc
7,7 → 7,7
 
$Revision$
 
;-----------------------------------------------------------------------------
 
;**********************************************************
; Непосредственная работа с устройством СD (ATAPI)
;**********************************************************
37,17 → 37,16
xor edi, edi
add esi, 8
inc edi
;--------------------------------------
align 4
.hdreadcache:
; cmp dword [esi+4],0 ; empty
; je .nohdcache
cmp [esi], eax ; correct sector
je .yeshdcache
 
.nohdcache:
add esi, 8
inc edi
dec ecx
jnz .hdreadcache
 
call find_empty_slot_CD_cache ; ret in edi
 
push edi
67,7 → 66,7
call cd_calculate_cache_1
lea esi, [edi*8+esi]
mov [esi], eax ; sector number
;--------------------------------------
; mov dword [esi+4],1 ; hd read - mark as same as in hd
.yeshdcache:
mov esi, edi
shl esi, 11 ;9
79,18 → 78,16
mov ecx, 512 ;/4
cld
rep movsd ; move data
;--------------------------------------
.exit:
popad
ret
;-----------------------------------------------------------------------------
 
ReadCDWRetr_1:
pushad
 
; Цикл, пока команда не выполнена успешно или не
; исчерпано количество попыток
mov ecx, MaxRetr
;--------------------------------------
align 4
mov ECX, MaxRetr
@@NextRetr:
; Подать команду
;*************************************************
106,6 → 103,9
;*************************************************
;ReadCD:
push ecx
; pusha
; Задать размер сектора
; mov [CDBlockSize],2048 ;2352
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать пакетную команду для считывания
113,67 → 113,79
; Задать код команды Read CD
mov [PacketCommand], byte 0x28 ;0xBE
; Задать адрес сектора
mov ax, word [CDSectorAddress+2]
xchg al, ah
mov word [PacketCommand+2], ax
mov ax, word [CDSectorAddress]
xchg al, ah
mov word [PacketCommand+4], ax
mov AX, word [CDSectorAddress+2]
xchg AL, AH
mov word [PacketCommand+2], AX
mov AX, word [CDSectorAddress]
xchg AL, AH
mov word [PacketCommand+4], AX
; mov eax,[CDSectorAddress]
; mov [PacketCommand+2],eax
; Задать количество считываемых секторов
mov [PacketCommand+8], byte 1
; Задать считывание данных в полном объеме
; mov [PacketCommand+9],byte 0xF8
; Подать команду
call SendPacketDatCommand
pop ecx
; ret
 
; cmp [DevErrorCode],0
test eax, eax
jz @@End_4
 
or ecx, ecx ;{SPraid.simba} (for cd load)
jz @@End_4
 
dec ecx
 
cmp [timer_ticks_enable], 0
jne @f
 
mov eax, NoTickWaitTime
;--------------------------------------
align 4
.wait:
dec eax
; test eax,eax
jz @@NextRetr
 
jmp .wait
;--------------------------------------
align 4
@@:
; Задержка на 2,5 секунды
; mov EAX,[timer_ticks]
; add EAX,50 ;250
;@@Wait:
; call change_task
; cmp EAX,[timer_ticks]
; ja @@Wait
loop @@NextRetr
;--------------------------------------
@@End_4:
mov dword [DevErrorCode], eax
popad
ret
;-----------------------------------------------------------------------------
 
 
; Универсальные процедуры, обеспечивающие выполнение
; пакетных команд в режиме PIO
 
; Максимально допустимое время ожидания реакции
; устройства на пакетную команду (в тиках)
;-----------------------------------------------------------------------------
 
MaxCDWaitTime equ 1000 ;200 ;10 секунд
uglobal
; Область памяти для формирования пакетной команды
PacketCommand:
rb 12 ;DB 12 DUP (?)
; Область памяти для приема данных от дисковода
;CDDataBuf DB 4096 DUP (0)
; Размер принимаемого блока данных в байтах
;CDBlockSize DW ?
; Адрес считываемого сектора данных
CDSectorAddress: dd ?
CDSectorAddress:
DD ?
; Время начала очередной операции с диском
TickCounter_1 dd 0
TickCounter_1 DD 0
; Время начала ожидания готовности устройства
WURStartTime dd 0
WURStartTime DD 0
; указатель буфера для считывания
CDDataBuf_pointer dd 0
endg
;-----------------------------------------------------------------------------
;****************************************************
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
188,6 → 200,7
;****************************************************
SendPacketDatCommand:
xor eax, eax
; mov byte [DevErrorCode],al
; Задать режим CHS
mov byte [ATAAddressMode], al
; Послать ATA-команду передачи пакетной команды
196,134 → 209,125
mov byte [ATASectorNumber], al
; Загрузить размер передаваемого блока
mov [ATAHead], al
; mov AX,[CDBlockSize]
mov [ATACylinder], CDBlockSize
mov [ATACommand], 0xA0
mov [ATACommand], 0A0h
call SendCommandToHDD_1
test eax, eax
; cmp [DevErrorCode],0 ;проверить код ошибки
jnz @@End_8 ;закончить, сохранив код ошибки
 
; Ожидание готовности дисковода к приему
; пакетной команды
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
mov DX, [ATABasePortAddr]
add DX, 7 ;порт 1х7h
mov ecx, NoTickWaitTime
;--------------------------------------
align 4
@@WaitDevice0:
cmp [timer_ticks_enable], 0
jne @f
 
dec ecx
; test ecx,ecx
jz @@Err1_1
 
jmp .test
;--------------------------------------
align 4
@@:
call change_task
; Проверить время выполнения команды
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, BSYWaitTime
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, BSYWaitTime
ja @@Err1_1 ;ошибка тайм-аута
; Проверить готовность
;--------------------------------------
align 4
.test:
in al, dx
test al, 0x80 ;состояние сигнала BSY
in AL, DX
test AL, 80h ;состояние сигнала BSY
jnz @@WaitDevice0
 
test al, 1 ;состояние сигнала ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Err6
 
test al, 0x8 ;состояние сигнала DRQ
test AL, 08h ;состояние сигнала DRQ
jz @@WaitDevice0
; Послать пакетную команду
cli
mov dx, [ATABasePortAddr]
mov ax, [PacketCommand]
out dx, ax
mov ax, [PacketCommand+2]
out dx, ax
mov ax, [PacketCommand+4]
out dx, ax
mov ax, [PacketCommand+6]
out dx, ax
mov ax, [PacketCommand+8]
out dx, ax
mov ax, [PacketCommand+10]
out dx, ax
mov DX, [ATABasePortAddr]
mov AX, [PacketCommand]
out DX, AX
mov AX, [PacketCommand+2]
out DX, AX
mov AX, [PacketCommand+4]
out DX, AX
mov AX, [PacketCommand+6]
out DX, AX
mov AX, [PacketCommand+8]
out DX, AX
mov AX, [PacketCommand+10]
out DX, AX
sti
; Ожидание готовности данных
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
mov DX, [ATABasePortAddr]
add DX, 7 ;порт 1х7h
mov ecx, NoTickWaitTime
;--------------------------------------
align 4
@@WaitDevice1:
cmp [timer_ticks_enable], 0
jne @f
 
dec ecx
; test ecx,ecx
jz @@Err1_1
 
jmp .test_1
;--------------------------------------
align 4
@@:
call change_task
; Проверить время выполнения команды
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, MaxCDWaitTime
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, MaxCDWaitTime
ja @@Err1_1 ;ошибка тайм-аута
; Проверить готовность
;--------------------------------------
align 4
.test_1:
in al, dx
test al, 0x80 ;состояние сигнала BSY
in AL, DX
test AL, 80h ;состояние сигнала BSY
jnz @@WaitDevice1
 
test al, 1 ;состояние сигнала ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Err6_temp
 
test al, 0x8 ;состояние сигнала DRQ
test AL, 08h ;состояние сигнала DRQ
jz @@WaitDevice1
; Принять блок данных от контроллера
mov edi, [CDDataBuf_pointer]
mov EDI, [CDDataBuf_pointer];0x7000 ;CDDataBuf
; Загрузить адрес регистра данных контроллера
mov dx, [ATABasePortAddr]
mov DX, [ATABasePortAddr];порт 1x0h
; Загрузить в счетчик размер блока в байтах
xor ecx, ecx
mov cx, CDBlockSize
mov CX, CDBlockSize
; Вычислить размер блока в 16-разрядных словах
shr cx, 1 ;разделить размер блока на 2
shr CX, 1;разделить размер блока на 2
; Принять блок данных
cli
cld
rep insw
sti
;--------------------------------------
; Успешное завершение приема данных
@@End_8:
xor eax, eax
ret
;--------------------------------------
 
; Записать код ошибки
@@Err1_1:
xor eax, eax
inc eax
ret
;--------------------------------------
; mov [DevErrorCode],1
; ret
@@Err6_temp:
mov eax, 7
ret
;--------------------------------------
; mov [DevErrorCode],7
; ret
@@Err6:
mov eax, 6
ret
;-----------------------------------------------------------------------------
; mov [DevErrorCode],6
;@@End_8:
; ret
 
 
 
;***********************************************
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ *
336,6 → 340,7
SendPacketNoDatCommand:
pushad
xor eax, eax
; mov byte [DevErrorCode],al
; Задать режим CHS
mov byte [ATAAddressMode], al
; Послать ATA-команду передачи пакетной команды
344,93 → 349,82
mov byte [ATASectorNumber], al
mov word [ATACylinder], ax
mov byte [ATAHead], al
mov [ATACommand], 0xA0
mov [ATACommand], 0A0h
call SendCommandToHDD_1
; cmp [DevErrorCode],0 ;проверить код ошибки
test eax, eax
jnz @@End_9 ;закончить, сохранив код ошибки
; Ожидание готовности дисковода к приему
; пакетной команды
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
;--------------------------------------
align 4
mov DX, [ATABasePortAddr]
add DX, 7 ;порт 1х7h
@@WaitDevice0_1:
call change_task
; Проверить время ожидания
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, BSYWaitTime
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, BSYWaitTime
ja @@Err1_3 ;ошибка тайм-аута
; Проверить готовность
in al, dx
test al, 0x80 ;состояние сигнала BSY
in AL, DX
test AL, 80h ;состояние сигнала BSY
jnz @@WaitDevice0_1
 
test al, 1 ;состояние сигнала ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Err6_1
 
test al, 0x8 ;состояние сигнала DRQ
test AL, 08h ;состояние сигнала DRQ
jz @@WaitDevice0_1
; Послать пакетную команду
; cli
mov dx, [ATABasePortAddr]
mov ax, word [PacketCommand]
out dx, ax
mov ax, word [PacketCommand+2]
out dx, ax
mov ax, word [PacketCommand+4]
out dx, ax
mov ax, word [PacketCommand+6]
out dx, ax
mov ax, word [PacketCommand+8]
out dx, ax
mov ax, word [PacketCommand+10]
out dx, ax
mov DX, [ATABasePortAddr]
mov AX, word [PacketCommand]
out DX, AX
mov AX, word [PacketCommand+2]
out DX, AX
mov AX, word [PacketCommand+4]
out DX, AX
mov AX, word [PacketCommand+6]
out DX, AX
mov AX, word [PacketCommand+8]
out DX, AX
mov AX, word [PacketCommand+10]
out DX, AX
; sti
cmp [ignore_CD_eject_wait], 1
je @@clear_DEC
; Ожидание подтверждения приема команды
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
;--------------------------------------
align 4
mov DX, [ATABasePortAddr]
add DX, 7 ;порт 1х7h
@@WaitDevice1_1:
call change_task
; Проверить время выполнения команды
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, MaxCDWaitTime
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, MaxCDWaitTime
ja @@Err1_3 ;ошибка тайм-аута
; Ожидать освобождения устройства
in al, dx
test al, 0x80 ;состояние сигнала BSY
in AL, DX
test AL, 80h ;состояние сигнала BSY
jnz @@WaitDevice1_1
 
test al, 1 ;состояние сигнала ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Err6_1
 
test al, 0x40 ;состояние сигнала DRDY
test AL, 40h ;состояние сигнала DRDY
jz @@WaitDevice1_1
;--------------------------------------
@@clear_DEC:
and [DevErrorCode], 0
popad
ret
;--------------------------------------
; Записать код ошибки
@@Err1_3:
xor eax, eax
inc eax
jmp @@End_9
;--------------------------------------
@@Err6_1:
mov eax, 6
;--------------------------------------
@@End_9:
mov [DevErrorCode], eax
popad
ret
;-----------------------------------------------------------------------------
 
;****************************************************
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
;* Входные параметры передаются через глобальные *
451,56 → 445,45
;* возвращен код ошибки в eax *
;****************************************************
SendCommandToHDD_1:
; pushad
; mov [DevErrorCode],0 not need
; Проверить значение кода режима
cmp [ATAAddressMode], 1
ja @@Err2_4
; Проверить корректность номера канала
mov bx, [ChannelNumber]
cmp bx, 1
mov BX, [ChannelNumber]
cmp BX, 1
jb @@Err3_4
 
cmp bx, 2
cmp BX, 2
ja @@Err3_4
; Установить базовый адрес
dec bx
shl ebx, 2
dec BX
shl BX, 1
movzx ebx, bx
mov eax, [cdpos]
dec eax
shr eax, 2
imul eax, sizeof.IDE_DATA
add eax, IDE_controller_1
add eax, ebx
mov ax, [eax+IDE_DATA.BAR0_val]
mov [ATABasePortAddr], ax
mov AX, [ebx+StandardATABases]
mov [ATABasePortAddr], AX
; Ожидание готовности HDD к приему команды
; Выбрать нужный диск
mov dx, [ATABasePortAddr]
add dx, 6 ;адрес регистра головок
mov al, [DiskNumber]
cmp al, 1 ;проверить номера диска
mov DX, [ATABasePortAddr]
add DX, 6 ;адрес регистра головок
mov AL, [DiskNumber]
cmp AL, 1 ;проверить номера диска
ja @@Err4_4
 
shl al, 4
or al, 10100000b
out dx, al
shl AL, 4
or AL, 10100000b
out DX, AL
; Ожидать, пока диск не будет готов
inc dx
inc DX
mov eax, [timer_ticks]
mov [TickCounter_1], eax
mov ecx, NoTickWaitTime
;--------------------------------------
align 4
@@WaitHDReady_2:
cmp [timer_ticks_enable], 0
jne @f
 
dec ecx
; test ecx,ecx
jz @@Err1_4
 
jmp .test
;--------------------------------------
align 4
@@:
call change_task
; Проверить время ожидания
508,78 → 491,81
sub eax, [TickCounter_1]
cmp eax, BSYWaitTime ;300 ;ожидать 3 сек.
ja @@Err1_4 ;ошибка тайм-аута
;--------------------------------------
align 4
; Прочитать регистр состояния
.test:
in al, dx ; Прочитать регистр состояния
in AL, DX
; Проверить состояние сигнала BSY
test al, 0x80
test AL, 80h
jnz @@WaitHDReady_2
; Проверить состояние сигнала DRQ
test al, 0x8
test AL, 08h
jnz @@WaitHDReady_2
 
; Загрузить команду в регистры контроллера
cli
mov dx, [ATABasePortAddr]
inc dx ;регистр "особенностей"
mov al, [ATAFeatures]
out dx, al
inc dx ;счетчик секторов
mov al, [ATASectorCount]
out dx, al
inc dx ;регистр номера сектора
mov al, [ATASectorNumber]
out dx, al
inc dx ;номер цилиндра (младший байт)
mov ax, [ATACylinder]
out dx, al
inc dx ;номер цилиндра (старший байт)
mov al, ah
out dx, al
inc dx ;номер головки/номер диска
mov al, [DiskNumber]
shl al, 4
cmp [ATAHead], 0xF ;проверить номер головки
mov DX, [ATABasePortAddr]
inc DX ;регистр "особенностей"
mov AL, [ATAFeatures]
out DX, AL
inc DX ;счетчик секторов
mov AL, [ATASectorCount]
out DX, AL
inc DX ;регистр номера сектора
mov AL, [ATASectorNumber]
out DX, AL
inc DX ;номер цилиндра (младший байт)
mov AX, [ATACylinder]
out DX, AL
inc DX ;номер цилиндра (старший байт)
mov AL, AH
out DX, AL
inc DX ;номер головки/номер диска
mov AL, [DiskNumber]
shl AL, 4
cmp [ATAHead], 0Fh;проверить номер головки
ja @@Err5_4
 
or al, [ATAHead]
or al, 10100000b
mov ah, [ATAAddressMode]
shl ah, 6
or al, ah
out dx, al
or AL, [ATAHead]
or AL, 10100000b
mov AH, [ATAAddressMode]
shl AH, 6
or AL, AH
out DX, AL
; Послать команду
mov al, [ATACommand]
inc dx ;регистр команд
out dx, al
mov AL, [ATACommand]
inc DX ;регистр команд
out DX, AL
sti
;--------------------------------------
; Сбросить признак ошибки
; mov [DevErrorCode],0
@@End_10:
xor eax, eax
ret
;--------------------------------------
; Записать код ошибки
@@Err1_4:
xor eax, eax
inc eax
; mov [DevErrorCode],1
ret
;--------------------------------------
@@Err2_4:
mov eax, 2
; mov [DevErrorCode],2
ret
;--------------------------------------
@@Err3_4:
mov eax, 3
; mov [DevErrorCode],3
ret
;--------------------------------------
@@Err4_4:
mov eax, 4
; mov [DevErrorCode],4
ret
;--------------------------------------
@@Err5_4:
mov eax, 5
; mov [DevErrorCode],5
; Завершение работы программы
ret
;-----------------------------------------------------------------------------
; sti
; popad
 
;*************************************************
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ *
;* Входные параметры передаются через глобальные *
590,31 → 576,25
WaitUnitReady:
pusha
; Запомнить время начала операции
mov eax, [timer_ticks]
mov [WURStartTime], eax
mov EAX, [timer_ticks]
mov [WURStartTime], EAX
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать команду TEST UNIT READY
mov [PacketCommand], word 0
mov [PacketCommand], word 00h
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
mov ecx, NoTickWaitTime
;--------------------------------------
align 4
@@SendCommand:
; Подать команду проверки готовности
call SendPacketNoDatCommand
cmp [timer_ticks_enable], 0
jne @f
 
cmp [DevErrorCode], 0
je @@End_11
 
dec ecx
; cmp ecx,0
jz .Error
 
jmp @@SendCommand
;--------------------------------------
align 4
@@:
call change_task
; Проверить код ошибки
621,19 → 601,17
cmp [DevErrorCode], 0
je @@End_11
; Проверить время ожидания готовности
mov eax, [timer_ticks]
sub eax, [WURStartTime]
cmp eax, MaxCDWaitTime
mov EAX, [timer_ticks]
sub EAX, [WURStartTime]
cmp EAX, MaxCDWaitTime
jb @@SendCommand
;--------------------------------------
.Error:
; Ошибка тайм-аута
mov [DevErrorCode], 1
;--------------------------------------
@@End_11:
popa
ret
;-----------------------------------------------------------------------------
 
;*************************************************
;* ЗАПРЕТИТЬ СМЕНУ ДИСКА *
;* Входные параметры передаются через глобальные *
657,7 → 635,7
mov [eax], byte 1
popa
ret
;-----------------------------------------------------------------------------
 
;*************************************************
;* РАЗРЕШИТЬ СМЕНУ ДИСКА *
;* Входные параметры передаются через глобальные *
672,7 → 650,7
; Задать код команды
mov [PacketCommand], byte 0x1E
; Задать код запрета
mov [PacketCommand+4], byte 0
mov [PacketCommand+4], byte 00b
; Подать команду
call SendPacketNoDatCommand
mov eax, ATAPI_IDE0_lock
681,7 → 659,7
mov [eax], byte 0
popa
ret
;-----------------------------------------------------------------------------
 
;*************************************************
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД *
;* Входные параметры передаются через глобальные *
695,7 → 673,7
call clear_packet_buffer
; Сформировать команду START/STOP UNIT
; Задать код команды
mov [PacketCommand], word 0x1B
mov [PacketCommand], word 1Bh
; Задать операцию загрузки носителя
mov [PacketCommand+4], word 00000011b
; Подать команду
702,7 → 680,7
call SendPacketNoDatCommand
popa
ret
;-----------------------------------------------------------------------------
 
;*************************************************
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА *
;* Входные параметры передаются через глобальные *
716,7 → 694,7
call clear_packet_buffer
; Сформировать команду START/STOP UNIT
; Задать код команды
mov [PacketCommand], word 0x1B
mov [PacketCommand], word 1Bh
; Задать операцию извлечения носителя
mov [PacketCommand+4], word 00000010b
; Подать команду
723,7 → 701,7
call SendPacketNoDatCommand
popa
ret
;-----------------------------------------------------------------------------
 
;*************************************************
;* Проверить событие нажатия кнопки извлечения *
;* диска *
737,16 → 715,15
sub eax, [timer_ATAPI_check]
cmp eax, 100
jb .no
 
.yes:
xor eax, eax
inc eax
ret
;--------------------------------------
.no:
xor eax, eax
ret
endp
;-----------------------------------------------------------------------------
 
align 4
check_ATAPI_device_event:
pusha
754,96 → 731,43
sub eax, [timer_ATAPI_check]
cmp eax, 100
jb .end_1
 
pushfd
mov al, [DRIVE_DATA+1]
and al, 11b
cmp al, 10b
jz .ide3
;--------------------------------------
.ide2_1:
mov al, [DRIVE_DATA+1]
and al, 1100b
cmp al, 1000b
jz .ide2
;--------------------------------------
.ide1_1:
mov al, [DRIVE_DATA+1]
and al, 110000b
cmp al, 100000b
jz .ide1
;--------------------------------------
.ide0_1:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
jz .ide0
;--------------------------------------
.ide7_1:
mov al, [DRIVE_DATA+6]
and al, 11b
cmp al, 10b
jz .ide7
;--------------------------------------
.ide6_1:
mov al, [DRIVE_DATA+6]
and al, 1100b
cmp al, 1000b
jz .ide6
;--------------------------------------
.ide5_1:
mov al, [DRIVE_DATA+6]
and al, 110000b
cmp al, 100000b
jz .ide5
;--------------------------------------
.ide4_1:
mov al, [DRIVE_DATA+6]
and al, 11000000b
cmp al, 10000000b
jz .ide4
;--------------------------------------
.ide11_1:
mov al, [DRIVE_DATA+11]
and al, 11b
cmp al, 10b
jz .ide11
;--------------------------------------
.ide10_1:
mov al, [DRIVE_DATA+11]
and al, 1100b
cmp al, 1000b
jz .ide10
;--------------------------------------
.ide9_1:
mov al, [DRIVE_DATA+11]
and al, 110000b
cmp al, 100000b
jz .ide9
;--------------------------------------
.ide8_1:
mov al, [DRIVE_DATA+11]
and al, 11000000b
cmp al, 10000000b
jz .ide8
;--------------------------------------
.end:
popfd
 
sti
mov eax, [timer_ticks]
mov [timer_ATAPI_check], eax
;--------------------------------------
.end_1:
popa
ret
;-----------------------------------------------------------------------------
 
.ide3:
cli
cmp [ATAPI_IDE3_lock], 1
jne .ide2_1
 
cmp [IDE_Channel_2], 0
jne .ide1_1
cmp [cd_status], 0
jne .end
 
mov [IDE_Channel_2], 1
mov ecx, ide_channel2_mutex
call mutex_lock
call reserve_ok2
852,22 → 776,23
mov [cdpos], 4
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
je .eject_ide3
call syscall_cdaudio.free
jmp .ide2_1
.eject_ide3:
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide2_1
;-----------------------------------------------------------------------------
 
.ide2:
cli
cmp [ATAPI_IDE2_lock], 1
jne .ide1_1
 
cmp [IDE_Channel_2], 0
jne .ide1_1
cmp [cd_status], 0
jne .end
 
mov [IDE_Channel_2], 1
mov ecx, ide_channel2_mutex
call mutex_lock
call reserve_ok2
876,22 → 801,23
mov [cdpos], 3
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
je .eject_ide2
call syscall_cdaudio.free
jmp .ide1_1
.eject_ide2:
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide1_1
;-----------------------------------------------------------------------------
 
.ide1:
cli
cmp [ATAPI_IDE1_lock], 1
jne .ide0_1
 
cmp [IDE_Channel_1], 0
jne .end
cmp [cd_status], 0
jne .end
 
mov [IDE_Channel_1], 1
mov ecx, ide_channel1_mutex
call mutex_lock
call reserve_ok2
900,22 → 826,23
mov [cdpos], 2
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
je .eject_ide1
call syscall_cdaudio.free
jmp .ide0_1
.eject_ide1:
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide0_1
;-----------------------------------------------------------------------------
 
.ide0:
cli
cmp [ATAPI_IDE0_lock], 1
jne .ide7_1
 
jne .end
cmp [IDE_Channel_1], 0
jne .end
cmp [cd_status], 0
jne .end
 
mov [IDE_Channel_1], 1
mov ecx, ide_channel1_mutex
call mutex_lock
call reserve_ok2
924,206 → 851,14
mov [cdpos], 1
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
call .eject
;--------------------------------------
@@:
je .eject_ide0
call syscall_cdaudio.free
jmp .ide7_1
;-----------------------------------------------------------------------------
.ide7:
cli
cmp [ATAPI_IDE7_lock], 1
jne .ide6_1
 
cmp [cd_status], 0
jne .end
 
mov ecx, ide_channel4_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 1
mov [cdpos], 8
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
jmp .end
.eject_ide0:
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide6_1
;-----------------------------------------------------------------------------
.ide6:
cli
cmp [ATAPI_IDE6_lock], 1
jne .ide5_1
jmp .end
 
cmp [cd_status], 0
jne .end
 
mov ecx, ide_channel4_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 0
mov [cdpos], 7
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide5_1
;-----------------------------------------------------------------------------
.ide5:
cli
cmp [ATAPI_IDE5_lock], 1
jne .ide4_1
 
cmp [cd_status], 0
jne .end
 
mov ecx, ide_channel3_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 1
mov [cdpos], 6
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide4_1
;-----------------------------------------------------------------------------
.ide4:
cli
cmp [ATAPI_IDE4_lock], 1
jne .ide11_1
 
cmp [cd_status], 0
jne .end
 
mov ecx, ide_channel3_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 0
mov [cdpos], 5
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide11_1
;-----------------------------------------------------------------------------
.ide11:
cli
cmp [ATAPI_IDE11_lock], 1
jne .ide10_1
 
cmp [cd_status], 0
jne .end
 
mov ecx, ide_channel6_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 1
mov [cdpos], 12
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide10_1
;-----------------------------------------------------------------------------
.ide10:
cli
cmp [ATAPI_IDE10_lock], 1
jne .ide9_1
 
cmp [cd_status], 0
jne .end
 
mov ecx, ide_channel6_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 0
mov [cdpos], 11
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide9_1
;-----------------------------------------------------------------------------
.ide9:
cli
cmp [ATAPI_IDE9_lock], 1
jne .ide8_1
 
cmp [cd_status], 0
jne .end
 
mov ecx, ide_channel5_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 1
mov [cdpos], 10
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide8_1
;-----------------------------------------------------------------------------
.ide8:
cli
cmp [ATAPI_IDE8_lock], 1
jne .end
 
cmp [cd_status], 0
jne .end
 
mov ecx, ide_channel5_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 0
mov [cdpos], 9
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
 
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .end
;-----------------------------------------------------------------------------
.eject:
call clear_CD_cache
call allow_medium_removal
1131,7 → 866,6
call EjectMedium
mov [ignore_CD_eject_wait], 0
ret
;-----------------------------------------------------------------------------
iglobal
timer_ATAPI_check dd 0
ATAPI_IDE0_lock db 0
1138,17 → 872,8
ATAPI_IDE1_lock db 0
ATAPI_IDE2_lock db 0
ATAPI_IDE3_lock db 0
ATAPI_IDE4_lock db 0
ATAPI_IDE5_lock db 0
ATAPI_IDE6_lock db 0
ATAPI_IDE7_lock db 0
ATAPI_IDE8_lock db 0
ATAPI_IDE9_lock db 0
ATAPI_IDE10_lock db 0
ATAPI_IDE11_lock db 0
ignore_CD_eject_wait db 0
endg
;-----------------------------------------------------------------------------
;*************************************************
;* Получить сообщение о событии или состоянии *
;* устройства *
1174,7 → 899,7
call SendPacketDatCommand
popa
ret
;-----------------------------------------------------------------------------
 
;*************************************************
; прочитать информацию из TOC
;* Входные параметры передаются через глобальные *
1199,7 → 924,7
call SendPacketDatCommand
popa
ret
;-----------------------------------------------------------------------------
 
;*************************************************
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
;* Входные параметры передаются через глобальные *
1219,7 → 944,7
; call SendPacketDatCommand
; popa
; ret
;-----------------------------------------------------------------------------
 
clear_packet_buffer:
; Очистить буфер пакетной команды
and [PacketCommand], dword 0
1226,4 → 951,3
and [PacketCommand+4], dword 0
and [PacketCommand+8], dword 0
ret
;-----------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc
41,29 → 41,53
ret
;--------------------------------------------------------------------
clear_CD_cache:
DEBUGF 1, 'K : clear_CD_cache\n'
pusha
 
mov esi, [cdpos]
dec esi
imul esi, sizeof.IDE_CACHE
add esi, cache_ide0
 
.ide0:
xor eax, eax
 
mov [esi+IDE_CACHE.search_start], eax
mov ecx, [esi+IDE_CACHE.system_sad_size]
mov edi, [esi+IDE_CACHE.pointer]
cmp [cdpos], 1
jne .ide1
mov [cache_ide0_search_start], eax
mov ecx, [cache_ide0_system_sad_size]
mov edi, [cache_ide0_pointer]
call .clear
 
mov [esi+IDE_CACHE.appl_search_start], eax
mov ecx, [esi+IDE_CACHE.appl_sad_size]
mov edi, [esi+IDE_CACHE.data_pointer]
mov [cache_ide0_appl_search_start], eax
mov ecx, [cache_ide0_appl_sad_size]
mov edi, [cache_ide0_data_pointer]
jmp .continue
.ide1:
cmp [cdpos], 2
jne .ide2
mov [cache_ide1_search_start], eax
mov ecx, [cache_ide1_system_sad_size]
mov edi, [cache_ide1_pointer]
call .clear
 
mov [cache_ide1_appl_search_start], eax
mov ecx, [cache_ide1_appl_sad_size]
mov edi, [cache_ide1_data_pointer]
jmp .continue
.ide2:
cmp [cdpos], 3
jne .ide3
mov [cache_ide2_search_start], eax
mov ecx, [cache_ide2_system_sad_size]
mov edi, [cache_ide2_pointer]
call .clear
mov [cache_ide2_appl_search_start], eax
mov ecx, [cache_ide2_appl_sad_size]
mov edi, [cache_ide2_data_pointer]
jmp .continue
.ide3:
mov [cache_ide3_search_start], eax
mov ecx, [cache_ide3_system_sad_size]
mov edi, [cache_ide3_pointer]
call .clear
mov [cache_ide3_appl_search_start], eax
mov ecx, [cache_ide3_appl_sad_size]
mov edi, [cache_ide3_data_pointer]
.continue:
call .clear
popa
ret
;--------------------------------------
.clear:
shl ecx, 1
cld
72,131 → 96,272
;--------------------------------------------------------------------
align 4
cd_calculate_cache:
; 1 - IDE0 ... 12 - IDE11
push eax
 
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne @f
 
mov ecx, [eax+IDE_CACHE.system_sad_size]
mov esi, [eax+IDE_CACHE.pointer]
pop eax
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov esi, [cache_ide0_pointer]
ret
;--------------------------------------
@@:
mov ecx, [eax+IDE_CACHE.appl_sad_size]
mov esi, [eax+IDE_CACHE.data_pointer]
pop eax
.ide0_appl_data:
mov ecx, [cache_ide0_appl_sad_size]
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx, [cache_ide1_appl_sad_size]
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx, [cache_ide2_appl_sad_size]
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx, [cache_ide3_appl_sad_size]
mov esi, [cache_ide3_data_pointer]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_1:
; 1 - IDE0 ... 12 - IDE11
push eax
 
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne @f
 
mov esi, [eax+IDE_CACHE.pointer]
pop eax
jne .ide0_appl_data
mov esi, [cache_ide0_pointer]
ret
;--------------------------------------
@@:
mov esi, [eax+IDE_CACHE.data_pointer]
pop eax
.ide0_appl_data:
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi, [cache_ide3_data_pointer]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_2:
; 1 - IDE0 ... 12 - IDE11
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne @f
 
mov eax, [eax+IDE_CACHE.system_data]
jne .ide0_appl_data
mov eax, [cache_ide0_system_data]
ret
;--------------------------------------
@@:
mov eax, [eax+IDE_CACHE.appl_data]
.ide0_appl_data:
mov eax, [cache_ide0_appl_data]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov eax, [cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax, [cache_ide1_appl_data]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov eax, [cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax, [cache_ide2_appl_data]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov eax, [cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax, [cache_ide3_appl_data]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_3:
; 1 - IDE0 ... 12 - IDE11
push eax
; mov ecx,cache_max*10/100
; mov edi,[cache_search_start]
 
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne @f
 
mov edi, [eax+IDE_CACHE.search_start]
pop eax
jne .ide0_appl_data
mov edi, [cache_ide0_search_start]
ret
;--------------------------------------
@@:
mov edi, [eax+IDE_CACHE.appl_search_start]
pop eax
.ide0_appl_data:
mov edi, [cache_ide0_appl_search_start]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov edi, [cache_ide1_search_start]
ret
.ide1_appl_data:
mov edi, [cache_ide1_appl_search_start]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov edi, [cache_ide2_search_start]
ret
.ide2_appl_data:
mov edi, [cache_ide2_appl_search_start]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov edi, [cache_ide3_search_start]
ret
.ide3_appl_data:
mov edi, [cache_ide3_appl_search_start]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_4:
; 1 - IDE0 ... 12 - IDE11
push eax
 
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
 
; cmp edi,cache_max
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne @f
 
cmp edi, [eax+IDE_CACHE.system_sad_size]
pop eax
jne .ide0_appl_data
cmp edi, [cache_ide0_system_sad_size]
ret
;--------------------------------------
@@:
cmp edi, [eax+IDE_CACHE.appl_sad_size]
pop eax
.ide0_appl_data:
cmp edi, [cache_ide0_appl_sad_size]
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
cmp edi, [cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi, [cache_ide1_appl_sad_size]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
cmp edi, [cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi, [cache_ide2_appl_sad_size]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
cmp edi, [cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi, [cache_ide3_appl_sad_size]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_5:
; 1 - IDE0 ... 12 - IDE11
push eax
 
mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
 
; mov [cache_search_start],edi
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne @f
 
mov [eax+IDE_CACHE.search_start], edi
pop eax
jne .ide0_appl_data
mov [cache_ide0_search_start], edi
ret
;--------------------------------------
@@:
mov [eax+IDE_CACHE.appl_search_start], edi
pop eax
.ide0_appl_data:
mov [cache_ide0_appl_search_start], edi
ret
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov [cache_ide1_search_start], edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start], edi
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov [cache_ide2_search_start], edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start], edi
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov [cache_ide3_search_start], edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start], edi
ret
;--------------------------------------------------------------------
;align 4
;calculate_linear_to_real:
; shr eax, 12
; mov eax, [page_tabs+eax*4]
; and eax, 0xFFFFF000
; ret
/kernel/branches/Kolibri-acpi/boot/bootcode.inc
394,6 → 394,7
 
push 0
popf
sti
 
; set up esp
movzx esp, sp
400,21 → 401,138
 
push 0
pop es
xor ax, ax
and word [es:BOOT_IDE_BASE_ADDR], ax ;0
and word [es:BOOT_IDE_BAR0_16], ax ;0
and word [es:BOOT_IDE_BAR1_16], ax ;0
and word [es:BOOT_IDE_BAR2_16], ax ;0
and word [es:BOOT_IDE_BAR3_16], ax ;0
; \begin{Mario79}
; find HDD IDE DMA PCI device
; check for PCI BIOS
mov ax, 0xB101
int 0x1A
jc .nopci
cmp edx, 'PCI '
jnz .nopci
; find PCI class code
; class 1 = mass storage
; subclass 1 = IDE controller
; a) class 1, subclass 1, programming interface 0x80
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x80
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1 ; Parallel IDE Controller
; b) class 1, subclass 1, programming interface 0x8f
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8f
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1
; c) class 1, subclass 1, programming interface 0x85
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x85
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1
; d) class 1, subclass 1, programming interface 0x8A
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8A
mov [es:BOOT_IDE_PI_16], cx
xor si, si ; device index = 0
int 0x1A
jnc .found_1 ; Parallel IDE Controller
; Controller not found!
xor ax, ax
mov [es:BOOT_IDE_PI_16], ax
jmp .nopci
;--------------------------------------
.found_1:
; get memory base BAR4
mov ax, 0xB10A
mov di, 0x20 ; memory base is config register at 0x20
push cx
int 0x1A
jc .no_BAR4 ;.nopci
and cx, 0xFFFC ; clear address decode type
mov [es:BOOT_IDE_BASE_ADDR], cx
.no_BAR4:
pop cx
;--------------------------------------
.found:
; get Interrupt Line
mov ax, 0xB10A
mov di, 0x3c ; memory base is config register at 0x3c
push cx
int 0x1A
jc .no_Interrupt ;.nopci
 
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
mov [es:BOOT_IDE_INTERR_16], cx
.no_Interrupt:
pop cx
;--------------------------------------
; get memory base BAR0
mov ax, 0xB10A
mov di, 0x10 ; memory base is config register at 0x10
push cx
int 0x1A
jc .no_BAR0 ;.nopci
 
mov [es:BOOT_IDE_BAR0_16], cx
.no_BAR0:
pop cx
;--------------------------------------
; get memory base BAR1
mov ax, 0xB10A
mov di, 0x14 ; memory base is config register at 0x14
push cx
int 0x1A
jc .no_BAR1 ;.nopci
 
mov [es:BOOT_IDE_BAR1_16], cx
.no_BAR1:
pop cx
;--------------------------------------
; get memory base BAR2
mov ax, 0xB10A
mov di, 0x18 ; memory base is config register at 0x18
push cx
int 0x1A
jc .no_BAR2 ;.nopci
 
mov [es:BOOT_IDE_BAR2_16], cx
.no_BAR2:
pop cx
;--------------------------------------
; get memory base BAR3
mov ax, 0xB10A
mov di, 0x1C ; memory base is config register at 0x1c
push cx
int 0x1A
jc .no_BAR3 ;.nopci
 
mov [es:BOOT_IDE_BAR3_16], cx
.no_BAR3:
pop cx
;--------------------------------------
.nopci:
; \end{Mario79}
 
mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование
out 0x60, al
xor cx, cx
@@:
wait_loop: ; variant 2
; reading state of port of 8042 controller
in al, 64h
test al, 1
loopz @b
in al, 0x60
and al, 00000010b ; ready flag
; wait until 8042 controller is ready
loopnz wait_loop
 
;;;/diamond today 5.02.2008
; set keyboard typematic rate & delay
423,19 → 541,16
xor cx, cx
@@:
in al, 64h
test al, 1
loopz @b
in al, 0x60
test al, 2
loopnz @b
mov al, 0
out 0x60, al
xor cx, cx
@@:
in al, 64h
test al, 1
loopz @b
in al, 0x60
test al, 2
loopnz @b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sti
; --------------- APM ---------------------
and word [es:BOOT_APM_VERSION], 0 ; ver = 0.0 (APM not found)
mov ax, 0x5300
/kernel/branches/Kolibri-acpi/boot/booten.inc
55,7 → 55,7
start_msg db "Press [abcde] to change settings, press [Enter] to continue booting",13,10,0
time_msg db " or wait "
time_str db " 5 seconds"
db " to continue automatically",13,10,0
db " before automatical continuation",13,10,0
current_cfg_msg db "Current settings:",13,10,0
curvideo_msg db " [a] Videomode: ",0
 
/kernel/branches/Kolibri-acpi/boot/bootvesa.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
221,13 → 221,11
cmp [es:mi.BitsPerPixel], 32 ;It show only videomodes to have support 24 and 32 bpp
jb @f
 
; 16 bpp might actually be 15 bpp
cmp [es:mi.BitsPerPixel], 16
jne .l0
cmp [es:mi.GreenMaskSize], 5
jne .l0
; cmp [es:mi.BitsPerPixel],16
; jne .l0
; cmp [es:mi.GreenMaskSize],5
; jne .l0
; mov [es:mi.BitsPerPixel],15
jmp @f ; 15 bpp isnt supported ATM
 
 
.l0:
370,8 → 368,6
je .ok_found_mode
cmp word [es:si+8], 24
je .ok_found_mode
cmp word [es:si+8], 16
je .ok_found_mode
@@:
add si, size_of_step
cmp word [es:si], -1
396,8 → 392,7
; mov word [home_cursor],ax
; mov word [preboot_graph],ax
;SET default video of mode first probe will fined a move of work 1024x768@32
mov cx, 32
.find_mode:
 
mov ax, 1024
mov bx, 768
mov si, modes_table
416,8 → 411,6
call .loops
test ax, ax
jz .ok_found_mode
sub cx, 8
jnz .find_mode
 
mov si, modes_table
if ~ defined extended_primary_loader
481,15 → 474,18
jne .next
cmp bx, word [es:si+2]
jne .next
cmp cx, word [es:si+8]
jne .next
xor ax, ax
ret
cmp word [es:si+8], 32
je .ok
cmp word [es:si+8], 24
je .ok
.next:
add si, size_of_step
cmp word [es:si], -1
je .exit
jmp .loops
.ok:
xor ax, ax
ret
.exit:
or ax, -1
ret
/kernel/branches/Kolibri-acpi/boot/rdload.inc
9,10 → 9,10
 
 
read_ramdisk:
; READ RAMDISK IMAGE FROM HD (only for IDE0, IDE1, IDE2, IDE3)
; READ RAMDISK IMAGE FROM HD
 
cmp [boot_dev+OS_BASE+0x10000], 1
jne no_sys_on_hd.1
jne no_sys_on_hd
 
xor ebp, ebp
.hd_loop:
69,19 → 69,9
jb .hd_loop
jmp no_sys_on_hd
.yes:
DEBUGF 1, "K : RD found: %s\n", read_image_fsinfo.name
pop edi esi eax
jmp yes_sys_on_hd
 
call register_ramdisk
jmp yes_sys_on_hd
;-----------------------------------------------------------------------------
; Register ramdisk file system
register_ramdisk:
mov esi, boot_initramdisk
call boot_log
call ramdisk_init
ret
;-----------------------------------------------------------------------------
iglobal
align 4
read_image_fsinfo:
89,7 → 79,7
dq 0 ; offset: zero
dd 1474560 ; size
dd RAMDISK ; buffer
.name db '/hd'
db '/hd'
.name_digit db '0'
db '/'
.partition:
109,8 → 99,6
ret
 
no_sys_on_hd:
DEBUGF 1, "K : RD not found\n"
.1:
; test_to_format_ram_disk (need if not using ram disk)
cmp [boot_dev+OS_BASE+0x10000], 3
jne not_format_ram_disk
/kernel/branches/Kolibri-acpi/boot/shutdown.inc
13,24 → 13,8
 
$Revision$
 
use32
become_real:
cli
lgdt [realmode_gdt-OS_BASE]
jmp 8:@f
use16
@@:
mov ax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, cr0
and eax, not 80000001h
mov cr0, eax
jmp 0x1000:pr_mode_exit
 
align 4
pr_mode_exit:
 
; setup stack
182,7 → 166,7
pop es
mov cx, 0x8000
push cx
push 0x7100
push 0x7000
pop ds
xor si, si
xor di, di
/kernel/branches/Kolibri-acpi/bus/usb/common.inc
6,7 → 6,7
; =============================================================================
; Version of all structures related to host controllers.
; Must be the same in kernel and *hci-drivers.
USBHC_VERSION = 2
USBHC_VERSION = 1
 
; USB device must have at least 100ms of stable power before initializing can
; proceed; one timer tick is 10ms, so enforce delay in 10 ticks
46,7 → 46,6
USB_STATUS_CLOSED = 16 ; pipe closed
; either explicitly with USBClosePipe
; or implicitly due to device disconnect
USB_STATUS_CANCELLED = 17 ; transfer cancelled with USBAbortPipe
 
; Possible speeds of USB devices
USB_SPEED_FS = 0 ; full-speed
64,9 → 63,6
USB_FLAG_EXTRA_WAIT = 4
; The pipe was in wait list, while another event occured;
; when the first wait will be done, reinsert the pipe to wait list
USB_FLAG_DISABLED = 8
; The pipe is temporarily disabled so that it is not visible to hardware
; but still remains in software list. Used for usb_abort_pipe.
USB_FLAG_CLOSED_BIT = 0 ; USB_FLAG_CLOSED = 1 shl USB_FLAG_CLOSED_BIT
 
; =============================================================================
140,14 → 136,6
; Initiate configuration of a new device (create pseudo-pipe describing that
; device and call usb_new_device).
; esi -> usb_controller, eax = speed (one of USB_SPEED_* constants).
DisablePipe dd ?
; This procedure temporarily removes the given pipe from hardware queue.
; esi -> usb_controller, ebx -> usb_pipe
EnablePipe dd ?
; This procedure reinserts the given pipe to hardware queue
; after DisablePipe, with clearing transfer queue.
; esi -> usb_controller, ebx -> usb_pipe
; edx -> current descriptor, eax -> new last descriptor
ends
 
; pointers to kernel API functions that are called from *HCI-drivers
319,8 → 307,6
PrevVirt dd ?
; Previous endpoint in the processing list.
; See also NextVirt field and the description before NextVirt field.
BaseList dd ?
; Pointer to head of the processing list.
;
; Every pipe has the associated transfer queue, that is, the double-linked
; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt
441,8 → 427,6
; Size of device descriptor.
Speed db ?
; Device speed, one of USB_SPEED_*.
Timer dd ?
; Handle of timer that handles request timeout.
NumInterfaces dd ?
; Number of interfaces.
ConfigDataSize dd ?
/kernel/branches/Kolibri-acpi/bus/usb/hccommon.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; USB Host Controller support code: hardware-independent part,
; common for all controller types.
 
124,7 → 114,7
ret
endp
 
; Put the given control/bulk pipe in the wait list;
; Put the given control pipe in the wait list;
; called when the pipe structure is changed and a possible hardware cache
; needs to be synchronized. When it will be known that the cache is updated,
; usb_subscription_done procedure will be called.
138,17 → 128,6
ret
endp
 
; Same as usb_subscribe_control, but for interrupt/isochronous pipe.
proc usb_subscribe_periodic
cmp [ebx+usb_pipe.NextWait], -1
jnz @f
mov eax, [esi+usb_controller.WaitPipeListPeriodic]
mov [ebx+usb_pipe.NextWait], eax
mov [esi+usb_controller.WaitPipeListPeriodic], ebx
@@:
ret
endp
 
; Called after synchronization of hardware cache with software changes.
; Continues process of device enumeration based on when it was delayed
; due to call to usb_subscribe_control.
275,7 → 254,7
mov [esi+usb_controller.WaitPipeListAsync+edx], ebx
jmp .continue
.process:
; 7. Call the handler depending on USB_FLAG_CLOSED and USB_FLAG_DISABLED.
; 7. Call the handler depending on USB_FLAG_CLOSED.
or [ebx+usb_pipe.NextWait], -1
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED
jz .nodisconnect
282,11 → 261,6
call usb_pipe_closed
jmp .continue
.nodisconnect:
test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED
jz .nodisabled
call usb_pipe_disabled
jmp .continue
.nodisabled:
call usb_subscription_done
.continue:
; 8. Restore edx and next pipe saved in step 5 and continue the loop.
/kernel/branches/Kolibri-acpi/bus/usb/hub.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; Support for USB (non-root) hubs:
; powering up/resetting/disabling ports,
; watching for adding/removing devices.
/kernel/branches/Kolibri-acpi/bus/usb/init.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; Initialization of the USB subsystem.
; Provides usb_init procedure, includes all needed files.
 
65,7 → 55,7
mov esi, pcidev_list
push 0
.kickoff:
mov esi, [esi+PCIDEV.fd]
mov esi, [esi+PCIDEV.list.next]
cmp esi, pcidev_list
jz .done_kickoff
cmp word [esi+PCIDEV.class+1], 0x0C03
118,7 → 108,7
; for all EHCI controllers.
mov eax, pcidev_list
.scan_ehci:
mov eax, [eax+PCIDEV.fd]
mov eax, [eax+PCIDEV.list.next]
cmp eax, pcidev_list
jz .done_ehci
cmp [eax+PCIDEV.class], 0x0C0320
130,7 → 120,7
; for all UHCI and OHCI controllers.
mov eax, pcidev_list
.scan_usb1:
mov eax, [eax+PCIDEV.fd]
mov eax, [eax+PCIDEV.list.next]
cmp eax, pcidev_list
jz .done_usb1
cmp [eax+PCIDEV.class], 0x0C0300
/kernel/branches/Kolibri-acpi/bus/usb/memory.inc
1,12 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
; Memory management for USB structures.
; Protocol layer uses the common kernel heap malloc/free.
; Hardware layer has special requirements:
/kernel/branches/Kolibri-acpi/bus/usb/pipe.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; Functions for USB pipe manipulation: opening/closing, sending data etc.
;
USB_STDCALL_VERIFY = 1
23,11 → 13,6
stdcall arg
end if
}
if USB_STDCALL_VERIFY
STDCALL_VERIFY_EXTRA = 20h
else
STDCALL_VERIFY_EXTRA = 0
end if
 
; Initialization of usb_static_ep structure,
; called from controller-specific initialization; edi -> usb_static_ep
253,17 → 238,8
call mutex_lock
push ecx
; 3b. Let the controller-specific code do its job.
test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED
jnz @f
mov eax, [esi+usb_controller.HardwareFunc]
call [eax+usb_hardware_func.DisablePipe]
@@:
mov eax, [esi+usb_controller.HardwareFunc]
call [eax+usb_hardware_func.UnlinkPipe]
mov edx, [ebx+usb_pipe.NextVirt]
mov eax, [ebx+usb_pipe.PrevVirt]
mov [edx+usb_pipe.PrevVirt], eax
mov [eax+usb_pipe.NextVirt], edx
; 3c. Release the corresponding lock.
pop ecx
call mutex_unlock
286,40 → 262,6
ret
endp
 
; This procedure is called when all transfers are aborted
; either due to call to usb_abort_pipe or due to pipe closing.
; It notifies all callbacks and frees all transfer descriptors.
; ebx -> usb_pipe, esi -> usb_controller, edi -> usb_hardware_func
; three stack parameters: status code for callback functions
; and descriptors where to start and stop.
proc usb_pipe_aborted
virtual at esp
dd ? ; return address
.status dd ? ; USB_STATUS_CLOSED or USB_STATUS_CANCELLED
.first_td dd ?
.last_td dd ?
end virtual
; Loop over all transfers, calling the driver with the given status
; and freeing all descriptors except the last one.
.loop:
mov edx, [.first_td]
cmp edx, [.last_td]
jz .done
mov ecx, [edx+usb_gtd.Callback]
test ecx, ecx
jz .no_callback
stdcall_verify ecx, ebx, [.status+12+STDCALL_VERIFY_EXTRA], \
[edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData]
mov edx, [.first_td]
.no_callback:
mov eax, [edx+usb_gtd.NextVirt]
mov [.first_td], eax
stdcall [edi+usb_hardware_func.FreeTD], edx
jmp .loop
.done:
ret 12
endp
 
; This procedure is called when a pipe with USB_FLAG_CLOSED is removed from the
; corresponding wait list. It means that the hardware has fully forgot about it.
; ebx -> usb_pipe, esi -> usb_controller
326,26 → 268,30
proc usb_pipe_closed
push edi
mov edi, [esi+usb_controller.HardwareFunc]
; 1. Notify all registered callbacks with status USB_STATUS_CLOSED, if any,
; and free all transfer descriptors, including the last one.
lea ecx, [ebx+usb_pipe.Lock]
call mutex_lock
; 1. Loop over all transfers, calling the driver with USB_STATUS_CLOSED
; and freeing all descriptors.
mov edx, [ebx+usb_pipe.LastTD]
test edx, edx
jz .no_transfer
mov eax, [edx+usb_gtd.NextVirt]
mov edx, [edx+usb_gtd.NextVirt]
.transfer_loop:
cmp edx, [ebx+usb_pipe.LastTD]
jz .transfer_done
mov ecx, [edx+usb_gtd.Callback]
test ecx, ecx
jz .no_callback
push edx
push eax
call mutex_unlock
push USB_STATUS_CLOSED
call usb_pipe_aborted
; It is safe to free LastTD here:
; usb_*_transfer_async do not enqueue new transfers if USB_FLAG_CLOSED is set.
stdcall [edi+usb_hardware_func.FreeTD], [ebx+usb_pipe.LastTD]
jmp @f
stdcall_verify ecx, ebx, USB_STATUS_CLOSED, \
[edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData]
pop edx
.no_callback:
push [edx+usb_gtd.NextVirt]
stdcall [edi+usb_hardware_func.FreeTD], edx
pop edx
jmp .transfer_loop
.transfer_done:
stdcall [edi+usb_hardware_func.FreeTD], edx
.no_transfer:
call mutex_unlock
@@:
; 2. Decrement number of pipes for the device.
; If this pipe is the last pipe, go to 5.
mov ecx, [ebx+usb_pipe.DeviceData]
396,16 → 342,7
dec eax
jnz .notify_loop
.notify_done:
; 6. Kill the timer, if active.
; (Usually not; possible if device is disconnected
; while processing SET_ADDRESS request).
mov eax, [ebx+usb_pipe.DeviceData]
cmp [eax+usb_device_data.Timer], 0
jz @f
stdcall cancel_timer_hs, [eax+usb_device_data.Timer]
mov [eax+usb_device_data.Timer], 0
@@:
; 7. Bus address, if assigned, can now be reused.
; 6. Bus address, if assigned, can now be reused.
call [edi+usb_hardware_func.GetDeviceAddress]
test eax, eax
jz @f
412,7 → 349,7
bts [esi+usb_controller.ExistingAddresses], eax
@@:
dbgstr 'USB device disconnected'
; 8. All drivers have returned from disconnect callback,
; 7. All drivers have returned from disconnect callback,
; so all drivers should not use any device-related pipes.
; Free the remaining pipes.
mov eax, [ebx+usb_pipe.DeviceData]
429,74 → 366,15
.free_done:
stdcall [edi+usb_hardware_func.FreePipe], ebx
pop eax
; 9. Free the usb_device_data structure.
; 8. Free the usb_device_data structure.
sub eax, usb_device_data.ClosedPipeList - usb_pipe.NextSibling
call free
; 10. Return.
; 9. Return.
.nothing:
pop edi
ret
endp
 
; This procedure is called when a pipe with USB_FLAG_DISABLED is removed from the
; corresponding wait list. It means that the hardware has fully forgot about it.
; ebx -> usb_pipe, esi -> usb_controller
proc usb_pipe_disabled
push edi
mov edi, [esi+usb_controller.HardwareFunc]
; 1. Acquire pipe lock.
lea ecx, [ebx+usb_pipe.Lock]
call mutex_lock
; 2. Clear USB_FLAG_DISABLED in pipe state.
and [ebx+usb_pipe.Flags], not USB_FLAG_DISABLED
; 3. Sanity check: ignore uninitialized pipes.
cmp [ebx+usb_pipe.LastTD], 0
jz .no_transfer
; 4. Acquire the first and last to-be-cancelled transfer descriptor,
; save them in stack for the step 6,
; ask the controller driver to enable the pipe for hardware,
; removing transfers between first and last to-be-cancelled descriptors.
lea ecx, [esi+usb_controller.ControlLock]
cmp [ebx+usb_pipe.Type], BULK_PIPE
jb @f ; control pipe
lea ecx, [esi+usb_controller.BulkLock]
jz @f ; bulk pipe
lea ecx, [esi+usb_controller.PeriodicLock]
@@:
call mutex_lock
mov eax, [ebx+usb_pipe.BaseList]
mov edx, [eax+usb_pipe.NextVirt]
mov [ebx+usb_pipe.NextVirt], edx
mov [ebx+usb_pipe.PrevVirt], eax
mov [edx+usb_pipe.PrevVirt], ebx
mov [eax+usb_pipe.NextVirt], ebx
mov eax, [ebx+usb_pipe.LastTD]
mov edx, [eax+usb_gtd.NextVirt]
mov [eax+usb_gtd.NextVirt], eax
mov [eax+usb_gtd.PrevVirt], eax
push eax
push edx
push ecx
call [edi+usb_hardware_func.EnablePipe]
pop ecx
call mutex_unlock
; 5. Release pipe lock acquired at step 1.
; Callbacks called at step 6 can insert new transfers,
; so we cannot call usb_pipe_aborted while holding pipe lock.
lea ecx, [ebx+usb_pipe.Lock]
call mutex_unlock
; 6. Notify all registered callbacks with status USB_STATUS_CANCELLED, if any.
; Two arguments describing transfers range were pushed at step 4.
push USB_STATUS_CANCELLED
call usb_pipe_aborted
pop edi
ret
.no_transfer:
call mutex_unlock
pop edi
ret
endp
 
; Part of API for drivers, see documentation for USBNormalTransferAsync.
proc usb_normal_transfer_async stdcall uses ebx edi,\
pipe:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword
630,69 → 508,6
ret
endp
 
; Part of API for drivers, see documentation for USBAbortPipe.
proc usb_abort_pipe
push ebx esi ; save used registers to be stdcall
virtual at esp
rd 2 ; saved registers
dd ? ; return address
.pipe dd ?
end virtual
mov ebx, [.pipe]
; 1. Acquire pipe lock.
lea ecx, [ebx+usb_pipe.Lock]
call mutex_lock
; 2. If the pipe is already closed or abort is in progress,
; just release pipe lock and return.
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED + USB_FLAG_DISABLED
jnz .nothing
; 3. Mark the pipe as aborting.
or [ebx+usb_pipe.Flags], USB_FLAG_DISABLED
; 4. We cannot do anything except adding new transfers concurrently with hardware.
; Ask the controller driver to (temporarily) remove the pipe from hardware queue.
mov esi, [ebx+usb_pipe.Controller]
; 4a. Acquire queue lock.
lea ecx, [esi+usb_controller.ControlLock]
cmp [ebx+usb_pipe.Type], BULK_PIPE
jb @f ; control pipe
lea ecx, [esi+usb_controller.BulkLock]
jz @f ; bulk pipe
lea ecx, [esi+usb_controller.PeriodicLock]
@@:
call mutex_lock
push ecx
; 4b. Call the driver.
mov eax, [esi+usb_controller.HardwareFunc]
call [eax+usb_hardware_func.DisablePipe]
; 4c. Remove the pipe from software list.
mov eax, [ebx+usb_pipe.NextVirt]
mov edx, [ebx+usb_pipe.PrevVirt]
mov [eax+usb_pipe.PrevVirt], edx
mov [edx+usb_pipe.NextVirt], eax
; 4c. Register the pipe in corresponding wait list.
test [ebx+usb_pipe.Type], 1
jz .control_bulk
call usb_subscribe_periodic
jmp @f
.control_bulk:
call usb_subscribe_control
@@:
; 4d. Release queue lock.
pop ecx
call mutex_unlock
; 4e. Notify the USB thread about new work.
push ebx esi edi
call usb_wakeup
pop edi esi ebx
; That's all for now. To be continued in usb_pipe_disabled.
; 5. Release pipe lock acquired at step 1 and return.
.nothing:
lea ecx, [ebx+usb_pipe.Lock]
call mutex_unlock
pop esi ebx
ret 4
endp
 
; Part of API for drivers, see documentation for USBGetParam.
proc usb_get_param
virtual at esp
/kernel/branches/Kolibri-acpi/bus/usb/protocol.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5177 $
 
 
; Implementation of the USB protocol for device enumeration.
; Manage a USB device when it becomes ready for USB commands:
; configure, enumerate, load the corresponding driver(s),
43,19 → 33,6
; read to the debug board.
USB_DUMP_DESCRIPTORS = 1
 
; According to the USB specification (9.2.6.3),
; any device must response to SET_ADDRESS in 50 ms, or 5 timer ticks.
; Of course, our world is far from ideal.
; I have seen devices that just NAK everything when being reset from working
; state, but start to work after second reset.
; Our strategy is as follows: give 2 seconds for the first attempt,
; this should be enough for normal devices and not too long to detect buggy ones.
; If the device continues NAKing, reset it and retry several times,
; doubling the interval: 2s -> 4s -> 8s -> 16s. Give up after that.
; Numbers are quite arbitrary.
TIMEOUT_SET_ADDRESS_INITIAL = 200
TIMEOUT_SET_ADDRESS_LAST = 1600
 
; =============================================================================
; ================================ Structures =================================
; =============================================================================
202,22 → 179,7
; out: eax = 0 <=> failed, the caller should disable the port.
proc usb_new_device
push ebx edi ; save used registers to be stdcall
; 1. Check whether we're here because we were trying to reset
; already-registered device in hope to fix something serious.
; If so, skip allocation and go to 6.
movzx eax, [esi+usb_controller.ResettingPort]
mov edx, [esi+usb_controller.ResettingHub]
test edx, edx
jz .test_roothub
mov edx, [edx+usb_hub.ConnectedDevicesPtr]
mov ebx, [edx+eax*4]
jmp @f
.test_roothub:
mov ebx, [esi+usb_controller.DevicesByPort+eax*4]
@@:
test ebx, ebx
jnz .try_set_address
; 2. Allocate resources. Any device uses the following resources:
; 1. Allocate resources. Any device uses the following resources:
; - device address in the bus
; - memory for device data
; - pipe for zero endpoint
224,14 → 186,14
; If some allocation fails, we must undo our actions. Closing the pipe
; is a hard task, so we avoid it and open the pipe as the last resource.
; The order for other two allocations is quite arbitrary.
; 2a. Allocate a bus address.
; 1a. Allocate a bus address.
push ecx
call usb_set_address_request
pop ecx
; 2b. If failed, just return zero.
; 1b. If failed, just return zero.
test eax, eax
jz .nothing
; 2c. Allocate memory for device data.
; 1c. Allocate memory for device data.
; For now, we need sizeof.usb_device_data and extra 8 bytes for GET_DESCRIPTOR
; input and output, see usb_after_set_address. Later we will reallocate it
; to actual size needed for descriptors.
239,10 → 201,10
push ecx
call malloc
pop ecx
; 2d. If failed, free the bus address and return zero.
; 1d. If failed, free the bus address and return zero.
test eax, eax
jz .nomemory
; 2e. Open pipe for endpoint zero.
; 1e. Open pipe for endpoint zero.
; For now, we do not know the actual maximum packet size;
; for full-speed devices it can be any of 8, 16, 32, 64 bytes,
; low-speed devices must have 8 bytes, high-speed devices must have 64 bytes.
265,14 → 227,12
; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes.
xchg eax, ebx
pop eax
; 2f. If failed, free the memory, the bus address and return zero.
; 1f. If failed, free the memory, the bus address and return zero.
test ebx, ebx
jz .freememory
; 3. Store pointer to device data in the pipe structure.
; 2. Store pointer to device data in the pipe structure.
mov [ebx+usb_pipe.DeviceData], eax
; 4. Init device data, using usb_controller.Resetting* variables.
mov [eax+usb_device_data.Timer], edi
mov dword [eax+usb_device_data.DeviceDescriptor], TIMEOUT_SET_ADDRESS_INITIAL
; 3. Init device data, using usb_controller.Resetting* variables.
mov [eax+usb_device_data.TTHub], edi
mov [eax+usb_device_data.TTPort], 0
mov [eax+usb_device_data.NumInterfaces], edi
308,7 → 268,7
mov [eax+usb_device_data.Port], cl
mov edx, [esi+usb_controller.ResettingHub]
mov [eax+usb_device_data.Hub], edx
; 5. Store pointer to the config pipe in the hub data.
; 4. Store pointer to the config pipe in the hub data.
; Config pipe serves as device identifier.
; Root hubs use the array inside usb_controller structure,
; non-root hubs use the array immediately after usb_hub structure.
321,29 → 281,16
mov [esi+usb_controller.DevicesByPort+ecx*4], ebx
@@:
call usb_reinit_pipe_list
; 6. Issue SET_ADDRESS control request, using buffer filled in step 2a.
; 6a. Configure timer to force reset after timeout.
; Note: we can't use self-destructing timer, because we need to be able to cancel it,
; and for self-destructing timer we could have race condition in cancelling/destructing.
; DEBUGF 1,'K : pipe %x\n',ebx
.try_set_address:
xor edi, edi
mov edx, [ebx+usb_pipe.DeviceData]
stdcall timer_hs, [edx+usb_device_data.DeviceDescriptor], 7FFFFFFFh, usb_abort_pipe, ebx
test eax, eax
jz .nothing
mov edx, [ebx+usb_pipe.DeviceData]
mov [edx+usb_device_data.Timer], eax
; 6b. If it succeeded, setup timer to configure wait timeout.
; 5. Issue SET_ADDRESS control request, using buffer filled in step 1a.
; Use the return value from usb_control_async as our return value;
; if it is zero, then something has failed.
lea eax, [esi+usb_controller.SetAddressBuffer]
stdcall usb_control_async, ebx, eax, edi, edi, usb_set_address_callback, edi, edi
; Use the return value from usb_control_async as our return value;
; if it is zero, then something has failed.
.nothing:
; 7. Return.
; 6. Return.
pop edi ebx ; restore used registers to be stdcall
ret
; Handlers of failures in steps 2b, 2d, 2f.
; Handlers of failures in steps 1b, 1d, 1f.
.freememory:
call free
jmp .freeaddr
402,23 → 349,16
; Note that USB stack uses esi = pointer to usb_controller.
proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
push ebx ; save ebx to be stdcall
; Load data to registers for further references.
mov ebx, [pipe]
; 1. In any case, cancel the timer.
mov eax, [ebx+usb_pipe.DeviceData]
stdcall cancel_timer_hs, [eax+usb_device_data.Timer]
mov eax, [ebx+usb_pipe.DeviceData]
mov [eax+usb_device_data.Timer], 0
; Load data to registers for further references.
mov ecx, dword [esi+usb_controller.SetAddressBuffer+2]
mov eax, [esi+usb_controller.HardwareFunc]
; 2. Check whether the device has accepted new address. If so, proceed to 3.
; Otherwise, go to 4 if killed by usb_set_address_timeout or to 5 otherwise.
cmp [status], USB_STATUS_CANCELLED
jz .timeout
; 1. Check whether the device has accepted new address. If so, proceed to 2.
; Otherwise, go to 3.
cmp [status], 0
jnz .error
; 3. Address accepted.
; 3a. The controller-specific structure for the control pipe still uses
; 2. Address accepted.
; 2a. The controller-specific structure for the control pipe still uses
; zero address. Call the controller-specific function to change it to
; the actual address.
; Note that the hardware could cache the controller-specific structure,
427,49 → 367,25
; be safe to continue.
; dbgstr 'address set in device'
call [eax+usb_hardware_func.SetDeviceAddress]
; 3b. If the port is in non-root hub, clear 'reset in progress' flag.
; In any case, proceed to 6.
; 2b. If the port is in non-root hub, clear 'reset in progress' flag.
; In any case, proceed to 4.
mov eax, [esi+usb_controller.ResettingHub]
test eax, eax
jz .return
and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS
.return:
; 6. Address configuration done, we can proceed with other ports.
; 4. Address configuration done, we can proceed with other ports.
; Call the worker function for that.
call usb_test_pending_port
.wakeup:
push esi edi
call usb_wakeup
pop edi esi
.nothing:
pop ebx ; restore ebx to be stdcall
ret
.timeout:
; 4. Device continues to NAK the request. Reset it and retry.
mov edx, [ebx+usb_pipe.DeviceData]
mov ecx, [edx+usb_device_data.DeviceDescriptor]
add ecx, ecx
cmp ecx, TIMEOUT_SET_ADDRESS_LAST
ja .error
mov [edx+usb_device_data.DeviceDescriptor], ecx
dbgstr 'Timeout in USB device initialization, trying to reset...'
cmp [esi+usb_controller.ResettingHub], 0
jz .reset_roothub
push esi
mov esi, [esi+usb_controller.ResettingHub]
call usb_hub_initiate_reset
pop esi
jmp .nothing
.reset_roothub:
movzx ecx, [esi+usb_controller.ResettingPort]
call [eax+usb_hardware_func.InitiateReset]
jmp .wakeup
.error:
; 5. Device error: device not responding, disconnect etc.
; 3. Device error: device not responding, disconnect etc.
DEBUGF 1,'K : error %d in SET_ADDRESS, USB device disabled\n',[status]
; 5a. The address has not been accepted. Mark it as free.
; 3a. The address has not been accepted. Mark it as free.
bts dword [esi+usb_controller.ExistingAddresses], ecx
; 5b. Disable the port with bad device.
; 3b. Disable the port with bad device.
; For the root hub, call the controller-specific function and go to 6.
; For non-root hubs, let the hub code do its work and return (the request
; could take some time, the hub code is responsible for proceeding).
726,7 → 642,7
; 3d. Free old memory.
call free
pop eax
; 4. Issue control transfer GET_DESCRIPTOR(CONFIGURATION) for full descriptor.
; 4. Issue control transfer GET_DESCRIPTOR(DEVICE) for full descriptor.
movzx ecx, [eax+usb_device_data.DeviceDescrSize]
mov edx, [eax+usb_device_data.ConfigDataSize]
lea eax, [eax+ecx+sizeof.usb_device_data]
/kernel/branches/Kolibri-acpi/const.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
179,7 → 179,8
_io_map_1 rb 4096
ends
 
DRIVE_DATA_SIZE equ 16
PARTITION_COUNT equ 64
DRIVE_DATA_SIZE equ (16+PARTITION_COUNT*100)
 
OS_BASE equ 0x80000000
 
204,7 → 205,7
 
WIN_TEMP_XY equ (OS_BASE+0x000F300)
KEY_COUNT equ (OS_BASE+0x000F400)
KEY_BUFF equ (OS_BASE+0x000F401) ; 120*2 + 2*2 = 244 bytes, actually 255 bytes
KEY_BUFF equ (OS_BASE+0x000F401)
 
BTN_COUNT equ (OS_BASE+0x000F500)
BTN_BUFF equ (OS_BASE+0x000F501)
219,7 → 220,11
 
TMP_STACK_TOP equ 0x006CC00
 
sys_proc equ (OS_BASE+0x006F000)
sys_pgdir equ (OS_BASE+0x006F000)
lfb_pd_0 equ (OS_BASE+0x0070000)
lfb_pd_1 equ (OS_BASE+0x0071000)
lfb_pd_2 equ (OS_BASE+0x0072000)
lfb_pd_3 equ (OS_BASE+0x0073000)
 
SLOT_BASE equ (OS_BASE+0x0080000)
 
228,6 → 233,10
CLEAN_ZONE equ (_CLEAN_ZONE-OS_BASE)
IDE_DMA equ (_IDE_DMA-OS_BASE)
 
; unused?
SB16Buffer equ (OS_BASE+0x02A0000)
SB16_Status equ (OS_BASE+0x02B0000)
 
UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000)
 
virtual at (OS_BASE+0x05FFF80)
243,8 → 252,8
master_tab equ (page_tabs+ (page_tabs shr 10)) ;0xFDFF70000
 
LFB_BASE equ 0xFE000000
LFB_SIZE equ 12*1024*1024
 
 
new_app_base equ 0;
 
twdw equ 0x2000 ;(CURRENT_TASK-window_data)
268,8 → 277,6
REG_RET equ (RING0_STACK_SIZE-56) ;irq0.return
 
 
PAGE_SIZE equ 4096
 
PG_UNMAP equ 0x000
PG_MAP equ 0x001
PG_WRITE equ 0x002
299,7 → 306,7
BOOT_DMA equ 0x901F ;
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no
;BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr ; now free and is not used
BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount
 
BOOT_APM_ENTRY equ 0x9040
308,12 → 315,12
BOOT_APM_CODE_32 equ 0x9050
BOOT_APM_CODE_16 equ 0x9052
BOOT_APM_DATA_16 equ 0x9054
;BOOT_IDE_BAR0_16 equ 0x9056 ; now free and is not used
;BOOT_IDE_BAR1_16 equ 0x9058 ; now free and is not used
;BOOT_IDE_BAR2_16 equ 0x905A ; now free and is not used
;BOOT_IDE_BAR3_16 equ 0x905C ; now free and is not used
;BOOT_IDE_PI_16 equ 0x905E ; now free and is not used
;BOOT_IDE_INTERR_16 equ 0x9060 ; now free and is not used
BOOT_IDE_BAR0_16 equ 0x9056
BOOT_IDE_BAR1_16 equ 0x9058
BOOT_IDE_BAR2_16 equ 0x905A
BOOT_IDE_BAR3_16 equ 0x905C
BOOT_IDE_PI_16 equ 0x905E
BOOT_IDE_INTERR_16 equ 0x9060
 
TMP_FILE_NAME equ 0
TMP_CMD_LINE equ 1024
430,7 → 437,7
y dd ?
width dd ?
height dd ?
bits_per_pixel dd ?
bpp dd ?
vrefresh dd ?
pitch dd ?
lfb dd ?
454,8 → 461,6
mask_seqno dd ?
check_mouse dd ?
check_m_pixel dd ?
 
bytes_per_pixel dd ?
ends
 
struct BOOT_DATA
502,13 → 507,14
ends
 
struct PCIDEV
bk dd ?
fd dd ?
vendor_device_id dd ?
list LHEAD
vid_did dd ?
class dd ?
svid_sdid dd ?
devfn db ?
bus db ?
rb 2
irq_line db ?
rb 1
owner dd ? ; pointer to SRV or 0
ends
 
619,28 → 625,6
NumAuxSymbols db ?
ends
 
struct STRIPPED_PE_HEADER
Signature dw ?
Characteristics dw ?
AddressOfEntryPoint dd ?
ImageBase dd ?
SectionAlignmentLog db ?
FileAlignmentLog db ?
MajorOSVersion db ?
MinorOSVersion db ?
SizeOfImage dd ?
SizeOfStackReserve dd ?
SizeOfHeapReserve dd ?
SizeOfHeaders dd ?
Subsystem db ?
NumberOfRvaAndSizes db ?
NumberOfSections dw ?
ends
STRIPPED_PE_SIGNATURE = 0x4503 ; 'PE' xor 'S'
SPE_DIRECTORY_IMPORT = 0
SPE_DIRECTORY_EXPORT = 1
SPE_DIRECTORY_BASERELOC = 2
 
struct IOCTL
handle dd ?
io_code dd ?
/kernel/branches/Kolibri-acpi/core/mtrr.inc
File deleted
/kernel/branches/Kolibri-acpi/core/dll.inc
123,13 → 123,13
 
stdcall strncmp, edx, [sz_name], 16
test eax, eax
mov eax, edx
je .nothing
je .ok
 
mov edx, [edx+SRV.fd]
jmp @B
.not_load:
mov eax, [sz_name]
; Try to load .dll driver first. If not, fallback to .obj.
push edi
sub esp, 36
mov edi, esp
150,6 → 150,12
stdcall load_pe_driver, edi, 0
add esp, 36
pop edi
test eax, eax
jnz .nothing
pop ebp
jmp load_driver
.ok:
mov eax, edx
.nothing:
ret
endp
788,6 → 794,177
ret
endp
 
align 4
proc load_driver stdcall, driver_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
start dd ?
 
file_name rb 13+16+4+1 ; '/sys/drivers/<up-to-16-chars>.obj'
endl
 
lea edx, [file_name]
mov dword [edx], '/sys'
mov dword [edx+4], '/dri'
mov dword [edx+8], 'vers'
mov byte [edx+12], '/'
mov esi, [driver_name]
.redo:
lea edx, [file_name]
lea edi, [edx+13]
mov ecx, 16
@@:
lodsb
test al, al
jz @f
stosb
loop @b
@@:
mov dword [edi], '.obj'
mov byte [edi+4], 0
stdcall load_file, edx
 
test eax, eax
jz .exit
 
mov [coff], eax
 
movzx ecx, [eax+COFF_HEADER.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
@@:
add ebx, [edx+COFF_SECTION.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, sizeof.COFF_SECTION
dec ecx
jnz @B
mov [img_size], ebx
 
stdcall kernel_alloc, ebx
test eax, eax
jz .fail
mov [img_base], eax
 
mov edi, eax
xor eax, eax
mov ecx, [img_size]
add ecx, 4095
and ecx, not 4095
shr ecx, 2
cld
rep stosd
 
mov edx, [coff]
movzx ebx, [edx+COFF_HEADER.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+COFF_SECTION.VirtualAddress], edi
mov esi, [eax+COFF_SECTION.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+COFF_SECTION.SizeOfRawData]
jmp .next
.copy:
add esi, edx
mov ecx, [eax+COFF_SECTION.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15
and edi, not 15
add eax, sizeof.COFF_SECTION
dec ebx
jnz @B
 
mov ebx, [edx+COFF_HEADER.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+COFF_HEADER.nSymbols]
add ecx, ecx
lea ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
[strings], __exports
test eax, eax
jz .link_fail
 
mov ebx, [coff]
stdcall fix_coff_relocs, ebx, [sym], 0
 
stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
test eax, eax
jz .link_fail
 
mov eax, [eax]
shr eax, 16
cmp eax, DRV_COMPAT
jb .ver_fail
 
cmp eax, DRV_CURRENT
ja .ver_fail
 
mov ebx, [coff]
stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
mov [start], eax
 
stdcall kernel_free, [coff]
 
mov ebx, [start]
stdcall ebx, DRV_ENTRY
test eax, eax
jnz .ok
 
stdcall kernel_free, [img_base]
 
xor eax, eax
ret
.ok:
mov ebx, [img_base]
mov [eax+SRV.base], ebx
mov ecx, [start]
mov [eax+SRV.entry], ecx
ret
 
.ver_fail:
mov esi, msg_CR
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov esi, msg_version
call sys_msg_board_str
mov esi, msg_www
call sys_msg_board_str
jmp .cleanup
 
.link_fail:
mov esi, msg_module
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
.cleanup:
stdcall kernel_free, [img_base]
.fail:
stdcall kernel_free, [coff]
.exit:
xor eax, eax
ret
endp
 
; in: edx -> COFF_SECTION struct
; out: eax = alignment as mask for bits to drop
coff_get_align:
832,9 → 1009,10
; ignore timestamp
cli
 
mov esi, [current_process]
mov esi, [CURRENT_TASK]
shl esi, 8
lea edi, [fullname]
mov ebx, [esi+PROC.dlls_list_ptr]
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
test ebx, ebx
jz .not_in_process
mov esi, [ebx+HDLL.fd]
1194,21 → 1372,28
; out: eax = APPDATA.dlls_list_ptr if all is OK,
; NULL if memory allocation failed
init_dlls_in_thread:
mov ebx, [current_process]
mov eax, [ebx+PROC.dlls_list_ptr]
mov ebx, [current_slot]
mov eax, [ebx+APPDATA.dlls_list_ptr]
test eax, eax
jnz .ret
 
push [ebx+APPDATA.dir_table]
mov eax, 8
call malloc ; FIXME
call malloc
pop edx
test eax, eax
jz .ret
 
mov [eax], eax
mov [eax+4], eax
 
mov ebx, [current_process]
mov [ebx+PROC.dlls_list_ptr], eax
mov ecx, [TASK_COUNT]
mov ebx, SLOT_BASE+256
.set:
cmp [ebx+APPDATA.dir_table], edx
jnz @f
mov [ebx+APPDATA.dlls_list_ptr], eax
@@:
add ebx, 256
dec ecx
jnz .set
.ret:
ret
 
1229,11 → 1414,60
 
destroy_hdll:
push ebx ecx esi edi
push eax
mov ebx, [eax+HDLL.base]
mov esi, [eax+HDLL.parent]
mov edx, [esi+DLLDESCR.size]
 
; The following actions require the context of application where HDLL is mapped.
; However, destroy_hdll can be called in the context of OS thread when
; cleaning up objects created by the application which is destroyed.
; So remember current cr3 and set it to page table of target.
mov eax, [ecx+APPDATA.dir_table]
; Because we cheat with cr3, disable interrupts: task switch would restore
; page table from APPDATA of current thread.
; Also set [current_slot] because it is used by user_free.
pushf
cli
push [current_slot]
mov [current_slot], ecx
mov ecx, cr3
push ecx
mov cr3, eax
push ebx ; argument for user_free
mov eax, ebx
shr ebx, 12
push ebx
mov esi, [esi+DLLDESCR.data]
shr esi, 12
.unmap_loop:
push eax
mov eax, 2
xchg eax, [page_tabs+ebx*4]
mov ecx, [page_tabs+esi*4]
and eax, not 0xFFF
and ecx, not 0xFFF
cmp eax, ecx
jz @f
call free_page
@@:
pop eax
invlpg [eax]
add eax, 0x1000
inc ebx
inc esi
sub edx, 0x1000
ja .unmap_loop
pop ebx
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
call user_free
; Restore context.
pop eax
mov cr3, eax
pop [current_slot]
popf
; Ok, cheating is done.
pop eax
push eax
mov esi, [eax+HDLL.parent]
mov eax, [eax+HDLL.refcount]
call dereference_dll
/kernel/branches/Kolibri-acpi/core/exports.inc
7,6 → 7,11
 
$Revision$
 
iglobal
szKernel db 'KERNEL', 0
szVersion db 'version',0
endg
 
align 4
__exports:
export 'KERNEL', \
43,7 → 48,6
get_phys_addr, 'GetPhysAddr', \ ; eax
map_space, 'MapSpace', \
release_pages, 'ReleasePages', \
alloc_dma24, 'AllocDMA24', \ ; stdcall
\
mutex_init, 'MutexInit', \ ; gcc fastcall
mutex_lock, 'MutexLock', \ ; gcc fastcall
90,7 → 94,6
load_cursor, 'LoadCursor', \ ;stdcall
\
get_curr_task, 'GetCurrentTask', \
change_task, 'ChangeTask', \
load_file, 'LoadFile', \ ;retval eax, ebx
delay_ms, 'Sleep', \
\
102,7 → 105,6
strrchr, 'strrchr', \
\
timer_hs, 'TimerHS', \
timer_hs, 'TimerHs', \ ; shit happens
cancel_timer_hs, 'CancelTimerHS', \
\
reg_usb_driver, 'RegUSBDriver', \
119,8 → 121,6
NET_link_changed, 'NetLinkChanged', \
ETH_input, 'Eth_input', \
\
get_pcidev_list, 'GetPCIList', \
\
0, 'LFBAddress' ; must be the last one
load kernel_exports_count dword from __exports + 24
load kernel_exports_addresses dword from __exports + 28
/kernel/branches/Kolibri-acpi/core/heap.inc
129,11 → 129,15
loop @B
 
stdcall alloc_pages, dword 32
 
or eax, PG_SW
mov ebx, HEAP_BASE
mov ecx, 32
call commit_pages
mov edx, eax
mov edi, HEAP_BASE
.l1:
stdcall map_page, edi, edx, PG_SW
add edi, 0x1000
add edx, 0x1000
dec ecx
jnz .l1
 
mov edi, HEAP_BASE ;descriptors
mov ebx, HEAP_BASE+sizeof.MEM_BLOCK ;free space
476,39 → 480,46
mov [pages_count], ebx
 
stdcall alloc_kernel_space, eax
mov [lin_addr], eax
mov ebx, [pages_count]
test eax, eax
jz .err
mov [lin_addr], eax
 
mov ecx, [pages_count]
mov edx, eax
mov ebx, ecx
 
shr ebx, 3
jz .tail
shr ecx, 3
jz .next
 
shl ebx, 3
and ebx, not 7
push ebx
stdcall alloc_pages, ebx
test eax, eax
pop ecx ; yes ecx!!!
and eax, eax
jz .err
 
mov ecx, ebx
or eax, PG_SW
mov ebx, [lin_addr]
call commit_pages
 
mov edx, ebx ; this dirty hack
.tail:
mov ebx, [pages_count]
and ebx, 7
mov edi, eax
mov edx, [lin_addr]
@@:
stdcall map_page, edx, edi, dword PG_SW
add edx, 0x1000
add edi, 0x1000
dec ecx
jnz @B
.next:
mov ecx, [pages_count]
and ecx, 7
jz .end
@@:
push ecx
call alloc_page
pop ecx
test eax, eax
jz .err
 
stdcall map_page, edx, eax, dword PG_SW
add edx, 0x1000
dec ebx
dec ecx
jnz @B
.end:
mov eax, [lin_addr]
558,7 → 569,7
restore block_size
restore block_flags
 
;;;;;;;;;;;;;; USER HEAP ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;;
 
HEAP_TOP equ 0x80000000
 
565,29 → 576,26
align 4
proc init_heap
 
mov ebx, [current_process]
mov eax, [ebx+PROC.heap_top]
mov ebx, [current_slot]
mov eax, [ebx+APPDATA.heap_top]
test eax, eax
jz @F
sub eax, [ebx+PROC.heap_base]
sub eax, PAGE_SIZE
sub eax, [ebx+APPDATA.heap_base]
sub eax, 4096
ret
@@:
lea ecx, [ebx+PROC.heap_lock]
call mutex_init
 
mov esi, [ebx+PROC.mem_used]
mov esi, [ebx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
mov [ebx+PROC.mem_used], esi
mov [ebx+APPDATA.mem_size], esi
mov eax, HEAP_TOP
mov [ebx+PROC.heap_base], esi
mov [ebx+PROC.heap_top], eax
mov [ebx+APPDATA.heap_base], esi
mov [ebx+APPDATA.heap_top], eax
 
sub eax, esi
shr esi, 10
mov ecx, eax
sub eax, PAGE_SIZE
sub eax, 4096
or ecx, FREE_BLOCK
mov [page_tabs+esi], ecx
ret
600,28 → 608,25
push esi
push edi
 
mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
 
mov ecx, [alloc_size]
add ecx, (4095+PAGE_SIZE)
add ecx, (4095+4096)
and ecx, not 4095
 
mov esi, dword [ebx+PROC.heap_base] ; heap_base
mov edi, dword [ebx+PROC.heap_top] ; heap_top
.scan:
mov ebx, [current_slot]
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top
l_0:
cmp esi, edi
jae .m_exit
jae m_exit
 
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
test al, FREE_BLOCK
jz .test_used
jz test_used
and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size
jb .m_next
jb m_next
jz @f
 
lea edx, [esi+ecx]
643,15 → 648,13
jnz @B
.no:
 
mov edx, [current_process]
mov edx, [current_slot]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add [edx+PROC.mem_used], ebx
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
 
lea ecx, [edx+PROC.heap_lock]
call mutex_unlock
 
lea eax, [esi+4096]
 
pop edi
658,19 → 661,15
pop esi
pop ebx
ret
.test_used:
test_used:
test al, USED_BLOCK
jz .m_exit
jz m_exit
 
and eax, 0xFFFFF000
.m_next:
m_next:
add esi, eax
jmp .scan
.m_exit:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
 
jmp l_0
m_exit:
xor eax, eax
pop edi
pop esi
685,17 → 684,14
push esi
push edi
 
mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
 
mov ebx, [current_slot]
mov edx, [address]
and edx, not 0xFFF
mov [address], edx
sub edx, 0x1000
jb .error
mov esi, [ebx+PROC.heap_base]
mov edi, [ebx+PROC.heap_top]
mov esi, [ebx+APPDATA.heap_base]
mov edi, [ebx+APPDATA.heap_top]
cmp edx, esi
jb .error
.scan:
712,10 → 708,6
mov esi, ecx
jmp .scan
.error:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
 
xor eax, eax
pop edi
pop esi
767,15 → 759,14
mov [page_tabs+ebx*4], ecx
 
.nothird:
mov edx, [current_process]
 
mov edx, [current_slot]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add [edx+PROC.mem_used], ebx
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
 
lea ecx, [edx+PROC.heap_lock]
call mutex_unlock
 
mov eax, [address]
 
pop edi
791,14 → 782,10
 
mov esi, [base]
test esi, esi
jz .fail
jz .exit
 
push ebx
 
mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
 
xor ebx, ebx
shr esi, 12
mov eax, [page_tabs+(esi-1)*4]
834,30 → 821,25
.released:
push edi
 
mov edx, [current_process]
lea ecx, [edx+PROC.heap_lock]
mov esi, dword [edx+PROC.heap_base]
mov edi, dword [edx+PROC.heap_top]
sub ebx, [edx+PROC.mem_used]
mov edx, [current_slot]
mov esi, dword [edx+APPDATA.heap_base]
mov edi, dword [edx+APPDATA.heap_top]
sub ebx, [edx+APPDATA.mem_size]
neg ebx
mov [edx+PROC.mem_used], ebx
call update_mem_size
call user_normalize
pop edi
pop ebx
pop esi
ret
.exit:
call mutex_unlock
 
xor eax, eax
inc eax
pop ebx
pop esi
ret
 
.cantfree:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
jmp .exit
.fail:
xor eax, eax
pop ebx
pop esi
ret
endp
986,13 → 968,6
ret
@@:
push ecx edx
 
push eax
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_lock
pop eax
 
lea ecx, [eax - 0x1000]
shr ecx, 12
mov edx, [page_tabs+ecx*4]
1000,10 → 975,6
jnz @f
; attempt to realloc invalid pointer
.ret0:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
 
pop edx ecx
xor eax, eax
ret
1038,16 → 1009,16
jnz .nofreeall
mov eax, [page_tabs+ecx*4]
and eax, not 0xFFF
mov edx, [current_process]
mov ebx, [edx+PROC.mem_used]
mov edx, [current_slot]
mov ebx, [APPDATA.mem_size+edx]
sub ebx, eax
add ebx, 0x1000
or al, FREE_BLOCK
mov [page_tabs+ecx*4], eax
push esi edi
mov esi, [edx+PROC.heap_base]
mov edi, [edx+PROC.heap_top]
mov [edx+PROC.mem_used], ebx
mov esi, [APPDATA.heap_base+edx]
mov edi, [APPDATA.heap_top+edx]
call update_mem_size
call user_normalize
pop edi esi
jmp .ret0 ; all freed
1059,11 → 1030,11
shr ebx, 12
sub ebx, edx
push ebx ecx edx
mov edx, [current_process]
mov edx, [current_slot]
shl ebx, 12
sub ebx, [edx+PROC.mem_used]
sub ebx, [APPDATA.mem_size+edx]
neg ebx
mov [edx+PROC.mem_used], ebx
call update_mem_size
pop edx ecx ebx
lea eax, [ecx+1]
shl eax, 12
1073,8 → 1044,8
shl ebx, 12
jz .ret
push esi
mov esi, [current_process]
mov esi, [esi+PROC.heap_top]
mov esi, [current_slot]
mov esi, [APPDATA.heap_top+esi]
shr esi, 12
@@:
cmp edx, esi
1093,16 → 1064,12
or ebx, FREE_BLOCK
mov [page_tabs+ecx*4], ebx
.ret:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop eax edx ecx
ret
 
.realloc_add:
; get some additional memory
mov eax, [current_process]
mov eax, [eax+PROC.heap_top]
mov eax, [current_slot]
mov eax, [APPDATA.heap_top+eax]
shr eax, 12
cmp edx, eax
jae .cant_inplace
1134,21 → 1101,17
cld
rep stosd
pop edi
mov edx, [current_process]
mov edx, [current_slot]
shl ebx, 12
add [edx+PROC.mem_used], ebx
 
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
add ebx, [APPDATA.mem_size+edx]
call update_mem_size
pop eax edx ecx
ret
 
.cant_inplace:
push esi edi
mov eax, [current_process]
mov esi, [eax+PROC.heap_base]
mov edi, [eax+PROC.heap_top]
mov eax, [current_slot]
mov esi, [APPDATA.heap_base+eax]
mov edi, [APPDATA.heap_top+eax]
shr esi, 12
shr edi, 12
sub ebx, ecx
1211,9 → 1174,10
jnz @b
.no:
push ebx
mov edx, [current_process]
mov edx, [current_slot]
shl ebx, 12
add [edx+PROC.mem_used], ebx
add ebx, [APPDATA.mem_size+edx]
call update_mem_size
pop ebx
@@:
mov dword [page_tabs+esi*4], 2
1220,18 → 1184,50
inc esi
dec ebx
jnz @b
 
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop eax edi esi edx ecx
ret
 
if 0
align 4
proc alloc_dll
pushf
cli
bsf eax, [dll_map]
jnz .find
popf
xor eax, eax
ret
.find:
btr [dll_map], eax
popf
shl eax, 5
add eax, dll_tab
ret
endp
 
align 4
proc alloc_service
pushf
cli
bsf eax, [srv_map]
jnz .find
popf
xor eax, eax
ret
.find:
btr [srv_map], eax
popf
shl eax, 0x02
lea eax, [srv_tab+eax+eax*8] ;srv_tab+eax*36
ret
endp
 
;;;;;;;;;;;;;; SHARED MEMORY ;;;;;;;;;;;;;;;;;
end if
 
 
;;;;;;;;;;;;;; SHARED ;;;;;;;;;;;;;;;;;
 
 
; param
; eax= shm_map object
 
/kernel/branches/Kolibri-acpi/core/memory.inc
123,19 → 123,19
endp
 
align 4
;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
map_page:
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
push ebx
mov eax, [esp+12] ; phis_addr
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, [esp+16] ; flags
mov ebx, [esp+8] ; lin_addr
or eax, [flags]
mov ebx, [lin_addr]
shr ebx, 12
mov [page_tabs+ebx*4], eax
mov eax, [esp+8] ; lin_addr
mov eax, [lin_addr]
invlpg [eax]
pop ebx
invlpg [eax]
ret 12
ret
endp
 
align 4
map_space: ;not implemented
350,64 → 350,9
ret
endp
 
uglobal
sb16_buffer_allocated db 0
endg
 
; Allocates [.size] bytes so that the target memory block
; is inside one 64K page for 24-bit DMA controller,
; that is, somewhere between 00xx0000h and 00xxFFFFh.
proc alloc_dma24
; Implementation note.
; The only user of that function is SB16 driver,
; so just return a statically allocated buffer.
virtual at esp
dd ? ; return address
.size dd ?
end virtual
cmp [sb16_buffer_allocated], 0
jnz .fail
inc [sb16_buffer_allocated]
mov eax, SB16Buffer
ret 4
.fail:
xor eax, eax
ret 4
endp
 
; Allocates a physical page for master page table
; that duplicates first Mb of OS_BASE at address 0;
; used for starting APs and for shutting down,
; where it is important to execute code in trivial-mapped pages.
; Returns eax = allocated physical page.
proc create_trampoline_pgmap
; The only non-trivial moment:
; we need a linear address to fill information,
; but we don't need it outside of this function,
; so we're returning physical address.
; Therefore, allocate memory with kernel_alloc,
; this will allocate physical page and a linear address somewhere,
; and deallocate only linear address with free_kernel_space.
stdcall kernel_alloc, 0x1000
mov edi, eax
mov esi, master_tab
mov ecx, 1024
rep movsd
mov ecx, [master_tab+(OS_BASE shr 20)]
mov [eax], ecx
mov edi, eax
call get_pg_addr
push eax
stdcall free_kernel_space, edi
pop eax
ret
endp
 
align 4
proc init_LFB
locals
pg_count dd ?
endl
init_LFB:
xchg bx, bx
 
cmp dword [LFBAddress], -1
jne @f
436,61 → 381,33
@@:
call init_mtrr
 
mov edx, LFB_BASE
mov esi, [LFBAddress]
mov edi, 0x00C00000
mov dword [exp_lfb+4], edx
 
shr edi, 12
mov [pg_count], edi
shr edi, 10
 
bt [cpu_caps], CAPS_PSE
jnc .map_page_tables
or esi, PG_LARGE+PG_UW
mov edx, sys_proc+PROC.pdt_0+(LFB_BASE shr 20)
@@:
mov [edx], esi
add edx, 4
add esi, 0x00400000
dec edi
jnz @B
 
xor edx, edx
mov eax, [LFBAddress]
bt [cpu_caps], CAPS_PGE
jnc @F
or dword [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)], PG_GLOBAL
@@:
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
setc dh ;eliminate branch and
mov ecx, LFB_SIZE/4096
mov edi, lfb_pd_0
lea eax, [eax+edx+PG_UW] ;set PG_GLOBAL if supported
 
.map_page_tables:
.map_pte:
stosd
add eax, 0x1000
loop .map_pte
 
@@:
call alloc_page
stdcall map_page_table, edx, eax
add edx, 0x00400000
dec edi
jnz @B
mov ecx, (LFB_SIZE/4096)/1024
mov edi, sys_pgdir+(LFB_BASE shr 20)
lea eax, [(lfb_pd_0-OS_BASE)+PG_UW]
 
mov eax, [LFBAddress]
mov edi, page_tabs + (LFB_BASE shr 10)
or eax, PG_UW
mov ecx, [pg_count]
cld
@@:
.map_pde:
stosd
add eax, 0x1000
dec ecx
jnz @B
loop .map_pde
 
mov dword [exp_lfb+4], LFB_BASE
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
 
ret
endp
 
align 4
proc new_mem_resize stdcall, new_size:dword
500,9 → 417,7
push edi
 
mov edx, [current_slot]
mov ebx, [edx+APPDATA.process]
 
cmp [ebx+PROC.heap_base], 0
cmp [edx+APPDATA.heap_base], 0
jne .exit
 
mov edi, [new_size]
510,7 → 425,7
and edi, not 4095
mov [new_size], edi
 
mov esi, [ebx+PROC.mem_used]
mov esi, [edx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
 
545,8 → 460,7
.update_size:
mov edx, [current_slot]
mov ebx, [new_size]
mov edx, [edx+APPDATA.process]
mov [edx+PROC.mem_used], ebx
call update_mem_size
.exit:
pop edi
pop esi
622,6 → 536,38
endp
 
 
align 4
update_mem_size:
; in: edx = slot base
; ebx = new memory size
; destroys eax,ecx,edx
 
mov [APPDATA.mem_size+edx], ebx
;search threads and update
;application memory size infomation
mov ecx, [APPDATA.dir_table+edx]
mov eax, 2
 
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax, [TASK_COUNT]
jg .search_threads_end
mov edx, eax
shl edx, 5
cmp word [CURRENT_TASK+edx+TASKDATA.state], 9 ;if slot empty?
jz .search_threads_next
shl edx, 3
cmp [SLOT_BASE+edx+APPDATA.dir_table], ecx ;if it is our thread?
jnz .search_threads_next
mov [SLOT_BASE+edx+APPDATA.mem_size], ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
ret
 
; param
; eax= linear address
;
678,6 → 624,11
pop ebx ;restore exception number (#PF)
ret
 
; xchg bx, bx
; add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
; restore_ring3_context
; iretd
 
.user_space:
test eax, PG_MAP
jnz .err_access ;Страница присутствует
717,8 → 668,9
; access denied? this may be a result of copy-on-write protection for DLL
; check list of HDLLs
and ebx, not 0xFFF
mov eax, [current_process]
mov eax, [eax+PROC.dlls_list_ptr]
mov eax, [CURRENT_TASK]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
test eax, eax
jz .fail
mov esi, [eax+HDLL.fd]
794,31 → 746,35
endp
 
; returns number of mapped bytes
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
proc map_mem stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
locals
count dd ?
process dd ?
endl
push 0 ; initialize number of mapped bytes
 
mov [count], 0
cmp [buf_size], 0
jz .exit
 
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.process]
test eax, eax
jz .exit
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
 
mov [process], eax
stdcall map_page, [ipc_pdir], eax, PG_UW
mov ebx, [ofs]
shr ebx, 22
mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table
mov esi, [ipc_ptab]
mov esi, [ipc_pdir]
mov edi, [ipc_ptab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page, esi, eax, PG_SW
stdcall map_page, edi, eax, PG_UW
; inc ebx
; add edi, 0x1000
; mov eax, [esi+ebx*4]
; test eax, eax
; jz @f
; and eax, 0xFFFFF000
; stdcall map_page, edi, eax
 
@@:
mov edi, [lin_addr]
and edi, 0xFFFFF000
825,63 → 781,61
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx ; ???????????
inc ecx
 
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [ipc_ptab]
 
.map:
stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit
add [count], PAGE_SIZE
add [ofs], PAGE_SIZE
add dword [ebp-4], 4096
add [ofs], 4096
dec ecx
jz .exit
 
add edi, PAGE_SIZE
add edi, 0x1000
inc edx
cmp edx, 1024
cmp edx, 0x400
jnz .map
 
inc ebx
mov eax, [process]
mov eax, [eax+PROC.pdt_0+ebx*4]
mov eax, [ipc_pdir]
mov eax, [eax+ebx*4]
and eax, 0xFFFFF000
jz .exit
 
stdcall map_page, esi, eax, PG_SW
stdcall map_page, esi, eax, PG_UW
xor edx, edx
jmp .map
 
.exit:
mov eax, [count]
pop eax
ret
endp
 
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
locals
count dd ?
process dd ?
endl
push 0 ; initialize number of mapped bytes
 
mov [count], 0
cmp [buf_size], 0
jz .exit
 
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.process]
test eax, eax
jz .exit
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
 
mov [process], eax
stdcall map_page, [proc_mem_pdir], eax, PG_UW
mov ebx, [ofs]
shr ebx, 22
mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table
mov esi, [proc_mem_tab]
mov esi, [proc_mem_pdir]
mov edi, [proc_mem_tab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page, esi, eax, PG_SW
stdcall map_page, edi, eax, PG_UW
 
@@:
mov edi, [lin_addr]
and edi, 0xFFFFF000
888,35 → 842,24
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx ; ???????????
inc ecx
 
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [proc_mem_tab]
 
.map:
stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit
add [count], PAGE_SIZE
add [ofs], PAGE_SIZE
add dword [ebp-4], 0x1000
add edi, 0x1000
add [ofs], 0x1000
inc edx
dec ecx
jz .exit
 
add edi, PAGE_SIZE
inc edx
cmp edx, 1024
jnz .map
 
inc ebx
mov eax, [process]
mov eax, [eax+PROC.pdt_0+ebx*4]
and eax, 0xFFFFF000
jz .exit
 
stdcall map_page, esi, eax, PG_SW
xor edx, edx
jmp .map
.exit:
mov eax, [count]
pop eax
ret
endp
 
962,8 → 905,7
push ebx ecx
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.process]
mov eax, [eax+PROC.dlls_list_ptr]
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
test eax, eax
jz .no_hdll
mov ecx, [eax+HDLL.fd]
1050,6 → 992,29
mov [esp+32], eax
ret
 
;align 4
;proc set_ipc_buff
 
; mov eax,[current_slot]
; pushf
; cli
; mov [eax+APPDATA.ipc_start],ebx ;set fields in extended information area
; mov [eax+APPDATA.ipc_size],ecx
;
; add ecx, ebx
; add ecx, 4095
; and ecx, not 4095
;
;.touch: mov eax, [ebx]
; add ebx, 0x1000
; cmp ebx, ecx
; jb .touch
;
; popf
; xor eax, eax
; ret
;endp
 
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
locals
dst_slot dd ?
1068,7 → 1033,7
 
mov [dst_slot], eax
shl eax, 8
mov edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined?
mov edi, [eax+SLOT_BASE+0xa0] ;is ipc area defined?
test edi, edi
jz .no_ipc_area
 
1076,7 → 1041,7
and ebx, 0xFFF
mov [dst_offset], ebx
 
mov esi, [eax+SLOT_BASE+APPDATA.ipc_size]
mov esi, [eax+SLOT_BASE+0xa4]
mov [buf_size], esi
 
mov ecx, [ipc_tmp]
1089,7 → 1054,7
pop edi esi
@@:
mov [used_buf], ecx
stdcall map_mem_ipc, ecx, [dst_slot], \
stdcall map_mem, ecx, [dst_slot], \
edi, esi, PG_SW
 
mov edi, [dst_offset]
1160,7 → 1125,7
.ret:
mov eax, [used_buf]
cmp eax, [ipc_tmp]
je @f
jz @f
stdcall free_kernel_space, eax
@@:
pop eax
1365,6 → 1330,113
endp
 
align 4
proc init_mtrr
 
cmp [BOOT_VARS+BOOT_MTRR], byte 2
je .exit
 
bt [cpu_caps], CAPS_MTRR
jnc .exit
 
mov eax, cr0
or eax, 0x60000000 ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
mov ecx, 0x2FF
rdmsr ;
; has BIOS already initialized MTRRs?
test ah, 8
jnz .skip_init
; rarely needed, so mainly placeholder
; main memory - cached
push eax
 
mov eax, [MEM_AMOUNT]
; round eax up to next power of 2
dec eax
bsr ecx, eax
mov ebx, 2
shl ebx, cl
dec ebx
; base of memory range = 0, type of memory range = MEM_WB
xor edx, edx
mov eax, MEM_WB
mov ecx, 0x200
wrmsr
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
; clear unused MTRRs
xor eax, eax
xor edx, edx
@@:
inc ecx
wrmsr
cmp ecx, 0x20F
jb @b
; enable MTRRs
pop eax
or ah, 8
and al, 0xF0; default memtype = UC
mov ecx, 0x2FF
wrmsr
.skip_init:
stdcall set_mtrr, [LFBAddress], [LFBSize], MEM_WC
 
wbinvd ;again invalidate
 
mov eax, cr0
and eax, not 0x60000000
mov cr0, eax ; enable caching
.exit:
ret
endp
 
align 4
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
; find unused register
mov ecx, 0x201
@@:
rdmsr
dec ecx
test ah, 8
jz .found
rdmsr
mov al, 0; clear memory type field
cmp eax, [base]
jz .ret
add ecx, 3
cmp ecx, 0x210
jb @b
; no free registers, ignore the call
.ret:
ret
.found:
; found, write values
xor edx, edx
mov eax, [base]
or eax, [mem_type]
wrmsr
 
mov ebx, [size]
dec ebx
mov eax, 0xFFFFFFFF
mov edx, 0x00000000
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
ret
endp
 
align 4
proc create_ring_buffer stdcall, size:dword, flags:dword
locals
buf_ptr dd ?
/kernel/branches/Kolibri-acpi/core/peload.inc
24,30 → 24,15
 
mov [image], eax
 
mov edx, [eax+STRIPPED_PE_HEADER.SizeOfImage]
; mov cl, [eax+STRIPPED_PE_HEADER.Subsystem]
cmp word [eax], STRIPPED_PE_SIGNATURE
jz @f
 
mov edx, [eax+60]
; mov cl, [eax+5Ch+edx]
mov edx, [eax+80+edx]
 
@@:
mov [entry], 0
; cmp cl, 1
; jnz .cleanup
stdcall kernel_alloc, edx
stdcall kernel_alloc, [eax+80+edx]
test eax, eax
jz .cleanup
 
mov [base], eax
 
push ebx ebp
mov ebx, [image]
mov ebp, eax
call map_PE
pop ebp ebx
stdcall map_PE, eax, [image]
 
mov [entry], eax
test eax, eax
63,200 → 48,199
ret
endp
 
map_PE: ;ebp=base:dword, ebx=image:dword
DWORD equ dword
PTR equ
 
align 4
map_PE: ;stdcall base:dword, image:dword
cld
push ebp
push edi
push esi
sub esp, .locals_size
virtual at esp
.numsections dd ?
.import_names dd ?
.import_targets dd ?
.peheader dd ?
.bad_import dd ?
.import_idx dd ?
.import_descr dd ?
.relocs_rva dd ?
.relocs_size dd ?
.section_header_size dd ?
.AddressOfEntryPoint dd ?
.ImageBase dd ?
.locals_size = $ - esp
end virtual
cmp word [ebx], STRIPPED_PE_SIGNATURE
jz .stripped
 
push ebx
sub esp, 60
mov ebx, DWORD PTR [esp+84]
mov ebp, DWORD PTR [esp+80]
mov edx, ebx
add edx, [ebx+60]
movzx eax, word [edx+6]
mov [.numsections], eax
mov eax, [edx+40]
mov [.AddressOfEntryPoint], eax
mov eax, [edx+52]
mov [.ImageBase], eax
mov ecx, [edx+84]
mov [.section_header_size], 40
mov eax, [edx+128]
mov [.import_descr], eax
mov eax, [edx+160]
mov [.relocs_rva], eax
mov eax, [edx+164]
mov [.relocs_size], eax
add edx, 256
 
jmp .common
.stripped:
mov eax, [ebx+STRIPPED_PE_HEADER.AddressOfEntryPoint]
mov [.AddressOfEntryPoint], eax
mov eax, [ebx+STRIPPED_PE_HEADER.ImageBase]
mov [.ImageBase], eax
movzx eax, [ebx+STRIPPED_PE_HEADER.NumberOfSections]
mov [.numsections], eax
movzx ecx, [ebx+STRIPPED_PE_HEADER.NumberOfRvaAndSizes]
xor eax, eax
mov [.relocs_rva], eax
mov [.relocs_size], eax
test ecx, ecx
jz @f
mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_IMPORT*8]
@@:
mov [.import_descr], eax
cmp ecx, SPE_DIRECTORY_BASERELOC
jbe @f
mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8]
mov [.relocs_rva], eax
mov eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8+4]
mov [.relocs_size], eax
@@:
mov [.section_header_size], 28
lea edx, [ebx+ecx*8+sizeof.STRIPPED_PE_HEADER+8]
mov ecx, [ebx+STRIPPED_PE_HEADER.SizeOfHeaders]
 
.common:
mov esi, ebx
add edx, DWORD PTR [ebx+60]
mov edi, ebp
mov DWORD PTR [esp+32], edx
mov ecx, DWORD PTR [edx+84]
 
shr ecx, 2
rep movsd
 
cmp [.numsections], 0
jz .nosections
.copy_sections:
mov eax, [edx+8]
movzx eax, WORD PTR [edx+6]
mov DWORD PTR [esp+36], 0
mov DWORD PTR [esp+16], eax
jmp L2
L3:
mov eax, DWORD PTR [edx+264]
test eax, eax
je .no_section_data
je L4
mov esi, ebx
mov edi, ebp
add esi, [edx+12]
add esi, DWORD PTR [edx+268]
mov ecx, eax
add edi, [edx+4]
add edi, DWORD PTR [edx+260]
 
add ecx, 3
shr ecx, 2
rep movsd
 
.no_section_data:
mov ecx, [edx]
L4:
mov ecx, DWORD PTR [edx+256]
cmp ecx, eax
jbe .no_section_fill
jbe L6
sub ecx, eax
add eax, [edx+4]
add eax, DWORD PTR [edx+260]
lea edi, [eax+ebp]
 
xor eax, eax
rep stosb
 
.no_section_fill:
add edx, [.section_header_size]
dec [.numsections]
jnz .copy_sections
.nosections:
cmp [.relocs_size], 0
je .no_relocations
L6:
inc DWORD PTR [esp+36]
add edx, 40
L2:
mov esi, DWORD PTR [esp+16]
cmp DWORD PTR [esp+36], esi
jne L3
mov edi, DWORD PTR [esp+32]
cmp DWORD PTR [edi+164], 0
je L9
pushd [edi+164]
mov esi, ebp
mov ecx, ebp
sub esi, [.ImageBase]
add ecx, [.relocs_rva]
.relocs_block:
mov edi, [ecx]
add edi, ebp
mov ebx, [ecx+4]
add ecx, 8
sub [.relocs_size], ebx
sub ebx, 8
sub esi, DWORD PTR [edi+52]
add ecx, DWORD PTR [edi+160]
mov eax, esi
shr eax, 16
mov DWORD PTR [esp+16], eax
L12:
mov eax, [ecx+4]
sub [esp], eax
lea ebx, [eax-8]
xor edi, edi
shr ebx, 1
jz .relocs_next_block
.one_reloc:
movzx eax, word [ecx]
add ecx, 2
jmp L13
L14:
movzx eax, WORD PTR [ecx+8+edi*2]
mov edx, eax
shr eax, 12
and edx, 4095
cmp eax, 3
jne @f
add [edx+edi], esi
@@:
dec ebx
jnz .one_reloc
.relocs_next_block:
cmp [.relocs_size], 0
jg .relocs_block
.no_relocations:
cmp [.import_descr], 0
je .no_imports
add [.import_descr], ebp
mov [.bad_import], 0
.import_block:
mov ecx, [.import_descr]
cmp dword [ecx+4], 0
jne @f
cmp dword [ecx+12], 0
je .done_imports
@@:
mov edx, dword [ecx]
mov ecx, dword [ecx+16]
add edx, DWORD PTR [ecx]
cmp ax, 2
je L17
cmp ax, 3
je L18
dec ax
jne L15
mov eax, DWORD PTR [esp+16]
add WORD PTR [edx+ebp], ax
L17:
add WORD PTR [edx+ebp], si
L18:
add DWORD PTR [edx+ebp], esi
L15:
inc edi
L13:
cmp edi, ebx
jne L14
add ecx, DWORD PTR [ecx+4]
L11:
cmp dword [esp], 0
jg L12
pop eax
L9:
mov edx, DWORD PTR [esp+32]
cmp DWORD PTR [edx+132], 0
je L20
mov eax, ebp
add eax, DWORD PTR [edx+128]
mov DWORD PTR [esp+40], 0
add eax, 20
mov DWORD PTR [esp+56], eax
L22:
mov ecx, DWORD PTR [esp+56]
cmp DWORD PTR [ecx-16], 0
jne L23
cmp DWORD PTR [ecx-8], 0
je L25
L23:
mov edi, DWORD PTR [__exports+32]
mov esi, DWORD PTR [__exports+28]
mov eax, DWORD PTR [esp+56]
mov DWORD PTR [esp+20], edi
add edi, OS_BASE
add esi, OS_BASE
mov DWORD PTR [esp+44], esi
mov ecx, DWORD PTR [eax-4]
mov DWORD PTR [esp+48], edi
mov edx, DWORD PTR [eax-20]
test edx, edx
jnz @f
mov edx, ecx
@@:
mov [.import_idx], 0
mov DWORD PTR [esp+52], 0
add ecx, ebp
add edx, ebp
mov [.import_names], edx
mov [.import_targets], ecx
.import_func:
mov esi, [.import_idx]
mov edi, [.import_names]
mov eax, [edi+esi*4]
mov DWORD PTR [esp+24], edx
mov DWORD PTR [esp+28], ecx
L26:
mov esi, DWORD PTR [esp+52]
mov edi, DWORD PTR [esp+24]
mov eax, DWORD PTR [edi+esi*4]
test eax, eax
je .next_import_block
js .next_import_block
je L27
test eax, eax
js L27
lea edi, [ebp+eax]
mov eax, [.import_targets]
mov dword [eax+esi*4], 0
mov eax, DWORD PTR [esp+28]
mov DWORD PTR [eax+esi*4], 0
lea esi, [edi+2]
movzx ebx, word [edi]
push eax
push 32
mov ecx, [__exports+32]
mov eax, [ecx+OS_BASE+ebx*4]
movzx eax, WORD PTR [edi]
mov edx, DWORD PTR [esp+56]
mov eax, DWORD PTR [edx+eax*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop ebx
xor ebx, ebx
test eax, eax
jz .import_func_found
xor ebx, ebx
.import_func_candidate:
jne L32
jmp L30
L33:
push ecx
push 32
mov ecx, [__exports+32]
mov eax, [ecx+OS_BASE+ebx*4]
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop edx
test eax, eax
je .import_func_found
jne L34
mov esi, DWORD PTR [esp+44]
mov edx, DWORD PTR [esp+52]
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+ebx*4]
add eax, OS_BASE
mov DWORD PTR [ecx+edx*4], eax
jmp L36
L34:
inc ebx
cmp ebx, [__exports+24]
jb .import_func_candidate
L32:
cmp ebx, DWORD PTR [__exports+24]
jb L33
L36:
cmp ebx, DWORD PTR [__exports+24]
jne L37
 
mov esi, msg_unresolved
call sys_msg_board_str
265,30 → 249,34
mov esi, msg_CR
call sys_msg_board_str
 
mov [.bad_import], 1
jmp .next_import_func
.import_func_found:
mov esi, [__exports+28]
mov edx, [.import_idx]
mov ecx, [.import_targets]
mov eax, [esi+OS_BASE+ebx*4]
mov DWORD PTR [esp+40], 1
jmp L37
L30:
movzx eax, WORD PTR [edi]
mov esi, DWORD PTR [esp+44]
mov edi, DWORD PTR [esp+52]
mov edx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+eax*4]
add eax, OS_BASE
mov [ecx+edx*4], eax
.next_import_func:
inc [.import_idx]
jmp .import_func
.next_import_block:
add [.import_descr], 20
jmp .import_block
.done_imports:
mov DWORD PTR [edx+edi*4], eax
L37:
inc DWORD PTR [esp+52]
jmp L26
L27:
add DWORD PTR [esp+56], 20
jmp L22
L25:
xor eax, eax
cmp [.bad_import], 0
jne @f
.no_imports:
cmp DWORD PTR [esp+40], 0
jne L40
L20:
mov ecx, DWORD PTR [esp+32]
mov eax, ebp
add eax, [.AddressOfEntryPoint]
@@:
add esp, .locals_size
add eax, DWORD PTR [ecx+40]
L40:
add esp, 60
pop ebx
pop esi
pop edi
ret
pop ebp
ret 8
/kernel/branches/Kolibri-acpi/core/sys32.inc
413,26 → 413,23
 
align 4
terminate: ; terminate application
destroy_thread:
 
.slot equ esp+4 ;locals
.process equ esp ;ptr to parent process
.slot equ esp ;locals
 
 
push esi ;save .slot
 
shl esi, 8
mov edx, [SLOT_BASE+esi+APPDATA.process]
test edx, edx
jnz @F
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0
jne @F
pop esi
shl esi, 5
mov [CURRENT_TASK+esi+TASKDATA.state], 9
ret
@@:
push edx ;save .process
lea edx, [SLOT_BASE+esi]
call scheduler_remove_thread
;mov esi,process_terminating
;call sys_msg_board_str
call lock_application_table
 
; if the process is in V86 mode...
445,7 → 442,7
; ...it has page directory for V86 mode
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
mov ecx, [esi+4]
mov [eax+SLOT_BASE+APPDATA.process], ecx
mov [eax+SLOT_BASE+APPDATA.dir_table], ecx
; ...and I/O permission map for V86 mode
mov ecx, [esi+12]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
452,7 → 449,7
mov ecx, [esi+8]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
.nov86:
;destroy per-thread kernel objects
 
mov esi, [.slot]
shl esi, 8
add esi, SLOT_BASE+APP_OBJ_OFFSET
470,6 → 467,11
pop esi
jmp @B
@@:
 
mov eax, [.slot]
shl eax, 8
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
 
mov esi, [.slot]
cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2
jne @F
628,9 → 630,6
je @F
call free_page
@@:
lea ebx, [edi+APPDATA.list]
list_del ebx ;destroys edx, ecx
 
mov eax, 0x20202020
stosd
stosd
746,17 → 745,7
add ecx, 0x100
jmp .xd0
.xd1:
;release slot
 
bts [thr_slot_map], esi
 
mov ecx, [.process]
lea eax, [ecx+PROC.thr_list]
cmp eax, [eax+LHEAD.next]
jne @F
 
call destroy_process.internal
@@:
; call systest
sti ; .. and life goes on
 
mov eax, [draw_limits.left]
771,11 → 760,19
call unlock_application_table
;mov esi,process_terminated
;call sys_msg_board_str
add esp, 8
add esp, 4
ret
restore .slot
restore .process
 
;build_scheduler:
; mov esi, boot_sched_1
; call boot_log
; call build_process_gdt_tss_pointer
 
; mov esi,boot_sched_2
; call boot_log
; ret
 
; Three following procedures are used to guarantee that
; some part of kernel code will not be terminated from outside
; while it is running.
/kernel/branches/Kolibri-acpi/core/taskman.inc
70,7 → 70,7
filename rd 256 ;1024/4
flags dd ?
 
save_proc dd ?
save_cr3 dd ?
slot dd ?
slot_base dd ?
file_base dd ?
215,7 → 215,7
 
call lock_application_table
 
call alloc_thread_slot
call get_new_process_place
test eax, eax
mov esi, -0x20 ; too many processes
jz .err
248,24 → 248,19
loop .copy_process_name_loop
.copy_process_name_done:
 
mov ebx, [current_process]
mov [save_proc], ebx
mov ebx, cr3
mov [save_cr3], ebx
 
stdcall create_process, [hdr_mem], [file_base], [file_size]
stdcall create_app_space, [hdr_mem], [file_base], [file_size]
mov esi, -30; no memory
test eax, eax
jz .failed
 
mov ebx, [hdr_mem]
mov [eax+PROC.mem_used], ebx
 
mov ebx, [slot_base]
mov [ebx+APPDATA.process], eax
mov [ebx+APPDATA.dir_table], eax
mov eax, [hdr_mem]
mov [ebx+APPDATA.mem_size], eax
 
lea edx, [ebx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail edx, ecx
 
xor edx, edx
cmp word [6], '02'
jne @f
297,7 → 292,7
lea ecx, [filename]
stdcall set_app_params , [slot], eax, ebx, ecx, [flags]
 
mov eax, [save_proc]
mov eax, [save_cr3]
call set_cr3
 
mov eax, [process_number];set result
306,7 → 301,7
jmp .final
 
.failed:
mov eax, [save_proc]
mov eax, [save_cr3]
call set_cr3
.err:
.err_hdr:
390,55 → 385,53
ret
 
align 4
alloc_thread_slot:
proc get_new_process_place
;input:
; none
;result:
; eax=[new_thread_slot]<>0 - ok
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
 
 
mov edx, thr_slot_map
pushfd
cli
.l1:
bsf eax, [edx]
jnz .found
add edx, 4
cmp edx, thr_slot_map+32
jb .l1
 
popfd
mov eax, CURRENT_TASK
mov ebx, [TASK_COUNT]
inc ebx
shl ebx, 5
add ebx, eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax, ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax, 0x20
cmp word [eax+0xa], 9;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx, eax
sub eax, CURRENT_TASK
shr eax, 5 ;calculate slot index
cmp eax, 256
jge .failed ;it should be <256
mov word [ebx+0xa], 9;set process state to 9 (for slot after hight boundary)
ret
.failed:
xor eax, eax
ret
.found:
btr [edx], eax
sub edx, thr_slot_map
lea eax, [eax+edx*8]
popfd
ret
endp
 
 
align 4
proc create_process stdcall, app_size:dword,img_base:dword,img_size:dword
proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
locals
app_pages dd ?
img_pages dd ?
process dd ?
dir_addr dd ?
app_tabs dd ?
endl
 
push ebx
push esi
push edi
 
mov ecx, pg_data.mutex
call mutex_lock
 
xor eax, eax
mov [process], eax
mov [dir_addr], eax
 
mov eax, [app_size]
add eax, 4095
461,59 → 454,39
shr ecx, 12
mov [img_pages], ecx
 
if GREEDY_KERNEL
lea eax, [ecx+ebx+2];only image size
else
lea eax, [eax+ebx+2];all requested memory
 
end if
cmp eax, [pg_data.pages_free]
ja .fail
 
stdcall kernel_alloc, 0x2000
call alloc_page
test eax, eax
jz .fail
mov [process], eax
mov [dir_addr], eax
stdcall map_page, [tmp_task_pdir], eax, dword PG_SW
 
lea edi, [eax+PROC.heap_lock]
mov ecx, (PROC.ht_next-PROC.heap_lock)/4
 
list_init eax
add eax, PROC.thr_list
list_init eax
 
mov edi, [tmp_task_pdir]
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
cld
rep stosd
 
mov ecx, (PROC.pdt_0 - PROC.htab)/4
@@:
stosd
inc eax
cmp eax, ecx
jbe @B
 
mov [edi-4096+PROC.ht_next], 1 ;reserve handle 0
mov eax, edi
call get_pg_addr
mov [edi-4096+PROC.pdt_0_phys], eax
 
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
rep stosd
 
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_proc+PROC.pdt_0+(OS_BASE shr 20)
mov esi, sys_pgdir+(OS_BASE shr 20)
rep movsd
 
mov eax, [edi-8192+PROC.pdt_0_phys]
mov eax, [dir_addr]
or eax, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
 
lea eax, [edi-8192]
and eax, -4096
call set_cr3
 
mov ecx, [app_tabs]
test ecx, ecx
jz .done
 
xor edi, edi
mov edx, [app_tabs]
mov edi, new_app_base
@@:
call alloc_page
test eax, eax
521,9 → 494,12
 
stdcall map_page_table, edi, eax
add edi, 0x00400000
loop @B
dec edx
jnz @B
 
mov edi, page_tabs
mov edi, new_app_base
shr edi, 10
add edi, page_tabs
 
mov ecx, [app_tabs]
shl ecx, 10
530,17 → 506,15
xor eax, eax
rep stosd
 
xor edx, edx
mov ecx, [img_pages]
jcxz .bss
 
sub [app_pages], ecx
 
mov ebx, PG_UW
mov edx, new_app_base
mov esi, [img_base]
mov edi, new_app_base
shr esi, 10
shr edi, 10
add esi, page_tabs
mov edi, page_tabs
add edi, page_tabs
.remap:
lodsd
and eax, 0xFFFFF000
547,13 → 521,20
or eax, ebx; force user level r/w access
stosd
add edx, 0x1000
loop .remap
.bss:
mov ebx, [app_pages]
test ebx, ebx
dec [app_pages]
dec ecx
jnz .remap
 
mov ecx, [app_pages]
test ecx, ecx
jz .done
 
.map_bss:
if GREEDY_KERNEL
mov eax, 0x02
rep stosd
else
 
.alloc:
call alloc_page
test eax, eax
jz .fail
560,42 → 541,34
 
stdcall map_page, edx, eax, dword PG_UW
add edx, 0x1000
dec ebx
jnz .map_bss
dec [app_pages]
jnz .alloc
end if
 
.done:
stdcall map_page, [tmp_task_pdir], dword 0, dword PG_UNMAP
 
mov ecx, pg_data.mutex
call mutex_unlock
mov eax, [process]
 
pop edi
pop esi
pop ebx
mov eax, [dir_addr]
ret
.fail:
mov ecx, pg_data.mutex
call mutex_unlock
cmp [process], 0
cmp [dir_addr], 0
je @f
;; stdcall destroy_app_space, [dir_addr], 0
stdcall destroy_app_space, [dir_addr], 0
@@:
xor eax, eax
pop edi
pop esi
pop ebx
ret
endp
 
align 4
set_cr3:
pushfd
cli
 
mov ebx, [current_slot]
mov [current_process], eax
mov [ebx+APPDATA.process], eax
mov eax, [eax+PROC.pdt_0_phys]
mov [ebx+APPDATA.dir_table], eax
mov cr3, eax
popfd
ret
 
align 4
609,8 → 582,6
mov eax, [esi]
test eax, 1
jz .next
test eax, 2
jz .next
test eax, 1 shl 9
jnz .next ;skip shared pages
call free_page
623,25 → 594,46
endp
 
align 4
destroy_process: ;fastcall ecx= ptr to process
proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
 
lea eax, [ecx+PROC.thr_list]
cmp eax, [eax+LHEAD.next]
jne .exit
xor edx, edx
push edx
mov eax, 0x1
mov ebx, [pg_dir]
.loop:
;eax = current slot of process
mov ecx, eax
shl ecx, 5
cmp byte [CURRENT_TASK+ecx+0xa], 9;if process running?
jz @f ;skip empty slots
shl ecx, 3
add ecx, SLOT_BASE
cmp [ecx+APPDATA.dir_table], ebx;compare page directory addresses
jnz @f
mov [ebp-4], ecx
inc edx ;thread found
@@:
inc eax
cmp eax, [TASK_COUNT] ;exit loop if we look through all processes
jle .loop
 
align 4
.internal:
push ecx
;edx = number of threads
;our process is zombi so it isn't counted
pop ecx
cmp edx, 1
jg .ret
;if there isn't threads then clear memory.
mov esi, [dlls_list]
call destroy_all_hdlls;ecx=APPDATA
 
mov esi, [ecx+PROC.dlls_list_ptr]
call destroy_all_hdlls
mov ecx, pg_data.mutex
call mutex_lock
 
; mov ecx, pg_data.mutex
; call mutex_lock
 
mov esi, [esp]
add esi, PROC.pdt_0
mov edi, (0x80000000 shr 20)/4
mov eax, [pg_dir]
and eax, not 0xFFF
stdcall map_page, [tmp_task_pdir], eax, PG_SW
mov esi, [tmp_task_pdir]
mov edi, (OS_BASE shr 20)/4
.destroy:
mov eax, [esi]
test eax, 1
656,13 → 648,16
dec edi
jnz .destroy
 
call kernel_free ;ecx still in stack
mov eax, [pg_dir]
call free_page
.exit:
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
; mov ecx, pg_data.mutex
; call mutex_unlock
 
.exit:
stdcall map_page, [tmp_task_pdir], 0, PG_UNMAP
mov ecx, pg_data.mutex
call mutex_unlock
.ret:
ret
endp
 
align 4
get_pid:
713,10 → 708,6
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
 
mov eax, 1
ret
if 0
mov eax, [CURRENT_TASK]
; jmp check_process_region
;-----------------------------------------------------------------------------
741,13 → 732,57
 
mov eax, 1
ret
 
 
; call MEM_Get_Linear_Address
; push ebx
; push ecx
; push edx
; mov edx,ebx
; and edx,not (4096-1)
; sub ebx,edx
; add ecx,ebx
; mov ebx,edx
; add ecx,(4096-1)
; and ecx,not (4096-1)
;.loop:
;;eax - linear address of page directory
;;ebx - current page
;;ecx - current size
; mov edx,ebx
; shr edx,22
; mov edx,[eax+4*edx]
; and edx,not (4096-1)
; test edx,edx
; jz .failed1
; push eax
; mov eax,edx
; call MEM_Get_Linear_Address
; mov edx,ebx
; shr edx,12
; and edx,(1024-1)
; mov eax,[eax+4*edx]
; and eax,not (4096-1)
; test eax,eax
; pop eax
; jz .failed1
; add ebx,4096
; sub ecx,4096
; jg .loop
; pop edx
; pop ecx
; pop ebx
.ok:
mov eax, 1
ret
;
;.failed1:
; pop edx
; pop ecx
; pop ebx
.failed:
xor eax, eax
ret
end if
 
align 4
proc read_process_memory
919,7 → 954,7
 
call lock_application_table
 
call alloc_thread_slot
call get_new_process_place
test eax, eax
jz .failed
 
941,13 → 976,21
mov ecx, 11
rep movsb ;copy process name
 
mov eax, [ebx+APPDATA.process]
mov [edx+APPDATA.process], eax
mov eax, [ebx+APPDATA.heap_base]
mov [edx+APPDATA.heap_base], eax
 
lea ebx, [edx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail ebx, ecx ;add thread to process child's list
mov ecx, [ebx+APPDATA.heap_top]
mov [edx+APPDATA.heap_top], ecx
 
mov eax, [ebx+APPDATA.mem_size]
mov [edx+APPDATA.mem_size], eax
 
mov ecx, [ebx+APPDATA.dir_table]
mov [edx+APPDATA.dir_table], ecx;copy page directory
 
mov eax, [ebx+APPDATA.dlls_list_ptr]
mov [edx+APPDATA.dlls_list_ptr], eax
 
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
jz @F
1075,8 → 1118,8
add eax, 256
jc @f
 
; cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
; ja @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
 
mov eax, [cmd_line]
 
1115,8 → 1158,8
mov eax, edx
add eax, 1024
jc @f
; cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
; ja @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
stdcall strncpy, edx, [app_path], 1024
@@:
mov ebx, [slot]
1145,9 → 1188,9
xor eax, eax
mov [ecx+0], dword eax
mov [ecx+4], dword eax
mov eax, [Screen_Max_X]
mov eax, [_display.width]
mov [ecx+8], eax
mov eax, [Screen_Max_Y]
mov eax, [_display.height]
mov [ecx+12], eax
 
mov ebx, [pl0_stack]
/kernel/branches/Kolibri-acpi/core/clipboard.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
;------------------------------------------------------------------------------
align 4
sys_clipboard:
/kernel/branches/Kolibri-acpi/core/conf_lib-sp.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; Éste archivo debe ser editado con codificación CP866
 
ugui_mouse_speed cp850 'velocidad del ratón',0
/kernel/branches/Kolibri-acpi/core/sys32-sp.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; Éste archivo debe ser editado con codificación CP866
 
msg_sel_ker cp850 "núcleo", 0
/kernel/branches/Kolibri-acpi/core/apic.inc
1,13 → 1,11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
iglobal
IRQ_COUNT dd 24
endg
/kernel/branches/Kolibri-acpi/core/irq.inc
1,13 → 1,10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
IRQ_RESERVED equ 24
 
IRQ_POOL_SIZE equ 48
/kernel/branches/Kolibri-acpi/core/v86.inc
14,7 → 14,9
 
struct V86_machine
; page directory
process dd ?
pagedir dd ?
; translation table: V86 address -> flat linear address
pages dd ?
; mutex to protect all data from writing by multiple threads at one time
mutex dd ?
; i/o permission map
36,87 → 38,91
and dword [eax+V86_machine.mutex], 0
; allocate tables
mov ebx, eax
 
stdcall create_process, 4096, eax, 4096 ;FIXME
test eax, eax
jz .fail2
 
mov [eax+PROC.mem_used], 4096
mov [ebx+V86_machine.process], eax
 
push 2000h
; We allocate 4 pages.
; First is main page directory for V86 mode.
; Second page:
; first half (0x800 bytes) is page table for addresses 0 - 0x100000,
; second half is for V86-to-linear translation.
; Third and fourth are for I/O permission map.
push 8000h ; blocks less than 8 pages are discontinuous
call kernel_alloc
test eax, eax
jz .fail2
 
mov [ebx+V86_machine.iopm], eax
 
 
mov [ebx+V86_machine.pagedir], eax
push edi eax
mov edi, eax
add eax, 1800h
mov [ebx+V86_machine.pages], eax
; initialize tables
push edi
mov edi, eax
mov eax, -1
mov ecx, 2000h/4
xor eax, eax
rep stosd
mov [ebx+V86_machine.iopm], edi
dec eax
mov ecx, 2000h/4
rep stosd
pop eax
; page directory: first entry is page table...
mov edi, eax
add eax, 1000h
push eax
call get_pg_addr
or al, PG_UW
stosd
; ...and also copy system page tables
; thx to Serge, system is located at high addresses
add edi, (OS_BASE shr 20) - 4
push esi
mov esi, (OS_BASE shr 20) + sys_pgdir
mov ecx, 0x80000000 shr 22
rep movsd
 
mov eax, [ebx+V86_machine.process]
mov eax, [eax+PROC.pdt_0_phys]
mov eax, [ebx+V86_machine.pagedir] ;root dir also is
call get_pg_addr ;used as page table
or al, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
 
pushfd
cli
mov cr3, eax
 
 
pop esi
; now V86 specific: initialize known addresses in first Mb
 
pop eax
; first page - BIOS data (shared between all machines!)
; 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
; (I have seen one computer with EBDA segment = 0x9D80,
; all other computers use less memory)
 
mov eax, PG_UW
mov [page_tabs], eax
invlpg [eax]
 
mov byte [0x500], 0xCD
mov byte [0x501], 0x13
mov byte [0x502], 0xF4
mov byte [0x503], 0xCD
mov byte [0x504], 0x10
mov byte [0x505], 0xF4
 
mov eax, 0x99000+PG_UW
mov edi, page_tabs+0x99*4
mov edx, 0x1000
mov ecx, 7
mov ecx, 4
mov edx, 0x9C000
push eax
lea edi, [eax+0x9C*4]
@@:
lea eax, [edx + OS_BASE]
mov [edi+800h], eax
lea eax, [edx + 111b]
stosd
add eax, edx
add edx, 0x1000
loop @b
 
pop eax
pop edi
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
; physical address = 0xC0000
 
mov eax, 0xC0000+PG_UW
mov edi, page_tabs+0xC0*4
mov ecx, 64
; linear address = 0x800C0000
mov ecx, 0xC0
@@:
stosd
add eax, edx
loop @b
 
mov eax, sys_proc
push ebx
call set_cr3
pop ebx
popfd
 
pop edi
 
mov edx, ecx
shl edx, 12
push edx
or edx, 111b
mov [eax+ecx*4], edx
pop edx
add edx, OS_BASE
mov [eax+ecx*4+0x800], edx
inc cl
jnz @b
mov eax, ebx
ret
.fail2:
126,16 → 132,15
xor eax, eax
ret
 
;not used
; Destroy V86 machine
; in: eax = handle
; out: nothing
; destroys: eax, ebx, ecx, edx (due to free)
;v86_destroy:
; push eax
; stdcall kernel_free, [eax+V86_machine.pagedir]
; pop eax
; jmp free
v86_destroy:
push eax
stdcall kernel_free, [eax+V86_machine.pagedir]
pop eax
jmp free
 
; Translate V86-address to linear address
; in: eax=V86 address
145,15 → 150,13
v86_get_lin_addr:
push ecx edx
mov ecx, eax
mov edx, [esi+V86_machine.pages]
shr ecx, 12
mov edx, [page_tabs+ecx*4]
and eax, 0xFFF
and edx, 0xFFFFF000
or eax, edx
add eax, [edx+ecx*4] ; atomic operation, no mutex needed
pop edx ecx
ret
 
;not used
; Sets linear address for V86-page
; in: eax=linear address (must be page-aligned)
; ecx=V86 page (NOT address!)
160,15 → 163,15
; esi=handle
; out: nothing
; destroys: nothing
;v86_set_page:
; push eax ebx
; mov ebx, [esi+V86_machine.pagedir]
; mov [ebx+ecx*4+0x1800], eax
; call get_pg_addr
; or al, 111b
; mov [ebx+ecx*4+0x1000], eax
; pop ebx eax
; ret
v86_set_page:
push eax ebx
mov ebx, [esi+V86_machine.pagedir]
mov [ebx+ecx*4+0x1800], eax
call get_pg_addr
or al, 111b
mov [ebx+ecx*4+0x1000], eax
pop ebx eax
ret
 
; Allocate memory in V86 machine
; in: eax=size (in bytes)
211,7 → 214,21
mov [sys_v86_machine], eax
test eax, eax
jz .ret
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)
mov dword [ebx+0x99*4+0x1000], 0x99000 or 111b
mov dword [ebx+0x99*4+0x1800], OS_BASE + 0x99000
mov dword [ebx+0x9A*4+0x1000], 0x9A000 or 111b
mov dword [ebx+0x9A*4+0x1800], OS_BASE + 0x9A000
mov dword [ebx+0x9B*4+0x1000], 0x9B000 or 111b
mov dword [ebx+0x9B*4+0x1800], OS_BASE + 0x9B000
if ~DEBUG_SHOW_IO
; allow access to all ports
mov ecx, [esi+V86_machine.iopm]
255,39 → 272,37
; eax = 3 - IRQ is already hooked by another VM
; destroys: nothing
v86_start:
 
pushad
 
cli
 
mov ecx, [current_slot]
mov ecx, [CURRENT_TASK]
shl ecx, 8
add ecx, SLOT_BASE
 
push dword [ecx+APPDATA.io_map]
push dword [ecx+APPDATA.io_map+4]
push [ecx+APPDATA.process]
push [ecx+APPDATA.saved_esp0]
mov [ecx+APPDATA.saved_esp0], esp
mov [tss._esp0], esp
 
mov eax, [esi+V86_machine.iopm]
call get_pg_addr
inc eax
push dword [ecx+APPDATA.io_map]
push dword [ecx+APPDATA.io_map+4]
mov dword [ecx+APPDATA.io_map], eax
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax
 
mov eax, [esi+V86_machine.iopm]
add eax, 0x1000
call get_pg_addr
inc eax
mov dword [ecx+APPDATA.io_map+4], eax
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax
 
mov eax, [esi+V86_machine.process]
mov [ecx+APPDATA.process], eax
mov [current_process], eax
mov eax, [eax+PROC.pdt_0_phys]
push [ecx+APPDATA.dir_table]
push [ecx+APPDATA.saved_esp0]
mov [ecx+APPDATA.saved_esp0], esp
mov [tss._esp0], esp
 
mov eax, [esi+V86_machine.pagedir]
call get_pg_addr
mov [ecx+APPDATA.dir_table], eax
mov cr3, eax
 
; mov [irq_tab+5*4], my05
 
; We do not enable interrupts, because V86 IRQ redirector assumes that
; machine is running
; They will be enabled by IRET.
767,21 → 782,19
mov esp, esi
 
cli
mov ecx, [current_slot]
mov ecx, [CURRENT_TASK]
shl ecx, 8
pop eax
 
mov [ecx+APPDATA.saved_esp0], eax
mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax
mov [tss._esp0], eax
pop eax
mov [ecx+APPDATA.process], eax
mov [current_process], eax
mov [SLOT_BASE+ecx+APPDATA.dir_table], eax
pop ebx
mov dword [ecx+APPDATA.io_map+4], ebx
mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx
mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx
pop ebx
mov dword [ecx+APPDATA.io_map], ebx
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx
mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax
sti
 
830,10 → 843,11
pop eax
v86_irq2:
mov esi, [v86_irqhooks+edi*8] ; get VM handle
mov eax, [esi+V86_machine.process]
mov eax, [esi+V86_machine.pagedir]
call get_pg_addr
mov ecx, [CURRENT_TASK]
shl ecx, 8
cmp [SLOT_BASE+ecx+APPDATA.process], eax
cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax
jnz .notcurrent
lea eax, [edi+8]
cmp al, 10h
846,7 → 860,7
mov ebx, SLOT_BASE + 0x100
mov ecx, [TASK_COUNT]
.scan:
cmp [ebx+APPDATA.process], eax
cmp [ebx+APPDATA.dir_table], eax
jnz .cont
push ecx
mov ecx, [ebx+APPDATA.saved_esp0]
881,7 → 895,6
popad
iretd
.found:
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax
mov esi, [ebx+APPDATA.saved_esp0]
sub word [esi-sizeof.v86_regs+v86_regs.esp], 6
/kernel/branches/Kolibri-acpi/core/sched.inc
29,7 → 29,8
.nocounter:
xor ecx, ecx ; send End Of Interrupt signal
call irq_eoi
 
; btr dword[DONT_SWITCH], 0
; jc .return
mov bl, SCHEDULE_ANY_PRIORITY
call find_next_task
jz .return ; if there is only one running process
43,10 → 44,26
pushfd
cli
pushad
if 0
; \begin{Mario79} ; <- must be refractoried, if used...
cmp [dma_task_switched], 1
jne .find_next_task
mov [dma_task_switched], 0
mov ebx, [dma_process]
cmp [CURRENT_TASK], ebx
je .return
mov edi, [dma_slot_ptr]
mov [CURRENT_TASK], ebx
mov [TASK_BASE], edi
jmp @f
.find_next_task:
; \end{Mario79}
end if
mov bl, SCHEDULE_ANY_PRIORITY
call find_next_task
jz .return ; the same task -> skip switch
 
@@:
; mov byte[DONT_SWITCH], 1
call do_change_task
.return:
popad
104,11 → 121,10
Mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
Mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
; set new thread memory-map
mov eax, [ebx+APPDATA.process]
cmp eax, [current_process]
mov ecx, APPDATA.dir_table
mov eax, [ebx+ecx] ;offset>0x7F
cmp eax, [esi+ecx] ;offset>0x7F
je @f
mov [current_process], eax
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax
@@:
; set tss.esp0
143,7 → 159,7
jz @f
xor eax, eax
mov dr6, eax
lea esi, [ebx+APPDATA.dbg_regs]
lea esi, [ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table];offset>0x7F
cld
macro lodsReg [reg] {
lodsd
/kernel/branches/Kolibri-acpi/core/debug.inc
136,18 → 136,9
; ecx=pid
; edx=sizeof(CONTEXT)
; esi->CONTEXT
; destroys eax,ebx,ecx,edx,esi,edi
 
xor ebx, ebx ; 0 - get only gp regs
cmp edx, 40
je .std_ctx
 
cmp edx, 48+288
jne .ret
 
inc ebx ; 1 - get sse context
; TODO legacy 32-bit FPU/MMX context
.std_ctx:
; destroys eax,ecx,edx,esi,edi
cmp edx, 28h
jnz .ret
; push ecx
; mov ecx, esi
call check_region
156,15 → 147,8
jnz .ret
call get_debuggee_slot
jc .ret
 
shr eax, 5
cmp eax, [fpu_owner]
jne @f
inc bh ; set swap context flag
@@:
shl eax, 8
mov edi, esi
mov eax, [eax+SLOT_BASE+APPDATA.pl0_stack]
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
lea esi, [eax+RING0_STACK_SIZE]
 
.ring0:
194,29 → 178,6
mov [edi+4], eax
lodsd ;esp
mov [edi+18h], eax
 
dec bl
js .ret
dec bl
jns .ret
 
test bh, bh ; check swap flag
jz @F
 
ffree st0 ; swap context
@@:
 
add esi, 4 ;top of ring0 stack
;fpu/sse context saved here
add edi, 40
mov eax, 1 ;sse context
stosd
xor eax, eax ;reserved dword
stosd
 
mov ecx, 288/4
rep movsd ;copy sse context
 
.ret:
sti
ret
/kernel/branches/Kolibri-acpi/detect/init_ata.inc
File deleted
/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc
17,192 → 17,93
;****************************************************
;* ПОИСК HDD и CD *
;****************************************************
cmp [ecx+IDE_DATA.ProgrammingInterface], 0
cmp [IDEContrProgrammingInterface], 0
je EndFindHDD
 
FindHDD:
push ecx
 
xor ebx, ebx
inc ebx
 
cmp ecx, IDE_controller_2
jne @f
 
add bl, 5
jmp .find
@@:
cmp ecx, IDE_controller_3
jne .find
 
add bl, 10
;--------------------------------------
.find:
 
mov [ChannelNumber], 1
mov [DiskNumber], 0
call FindHDD_2
 
call FindHDD_3
; mov ax,[Sector512+176]
; mov [DRIVE_DATA+6],ax
; mov ax,[Sector512+126]
; mov [DRIVE_DATA+8],ax
; mov ax,[Sector512+128]
; mov [DRIVE_DATA+8],ax
mov [DiskNumber], 1
call FindHDD_2
 
call FindHDD_3
; mov al,[Sector512+176]
; mov [DRIVE_DATA+7],al
inc [ChannelNumber]
 
mov [DiskNumber], 0
call FindHDD_2
 
call FindHDD_3
; mov al,[Sector512+176]
; mov [DRIVE_DATA+8],al
mov [DiskNumber], 1
call FindHDD_1
; mov al,[Sector512+176]
; mov [DRIVE_DATA+9],al
 
pop ecx
jmp EndFindHDD
;-----------------------------------------------------------------------------
FindHDD_2:
call FindHDD_1
shl byte [ebx+DRIVE_DATA], 2
ret
;-----------------------------------------------------------------------------
 
FindHDD_1:
DEBUGF 1, "K : Channel %d ",[ChannelNumber]:2
DEBUGF 1, "Disk %d\n",[DiskNumber]:1
push ebx ecx
call ReadHDD_ID
pop ecx ebx
cmp [DevErrorCode], 7
je .end
cmp [DevErrorCode], 0
jne .FindCD
 
jne FindHDD_2
cmp [Sector512+6], word 16
ja .FindCD
 
ja FindHDD_2
cmp [Sector512+12], word 255
ja .FindCD
 
inc byte [ebx+DRIVE_DATA]
jmp .Print_Device_Name
;--------------------------------------
.FindCD:
push ebx ecx
ja FindHDD_2
inc byte [DRIVE_DATA+1]
jmp Print_Device_Name
FindHDD_2:
call DeviceReset
pop ecx ebx
cmp [DevErrorCode], 0
jne .end
 
push ebx ecx
jne FindHDD_2_2
call ReadCD_ID
pop ecx ebx
cmp [DevErrorCode], 0
jne .end
 
add [ebx+DRIVE_DATA], byte 2
;--------------------------------------
.Print_Device_Name:
jne FindHDD_2_2
inc byte [DRIVE_DATA+1]
inc byte [DRIVE_DATA+1]
Print_Device_Name:
pushad
pushfd
 
xor ebx, ebx
mov bx, [ChannelNumber]
dec ebx
shl ebx, 1
add bl, [DiskNumber]
shl ebx, 1
 
call calculate_IDE_device_values_storage
;--------------------------------------
.copy_dev_name:
mov esi, Sector512+27*2
mov edi, dev_name
mov ecx, 20
cld
;--------------------------------------
@@:
lodsw
xchg ah, al
stosw
loop @b
 
popfd
popad
DEBUGF 1, "K : Dev: %s \n", dev_name
 
xor eax, eax
mov ax, [Sector512+64*2]
DEBUGF 1, "K : PIO possible modes %x\n", al
 
mov ax, [Sector512+51*2]
mov al, ah
call convert_Sector512_value
DEBUGF 1, "K : PIO set mode %x\n", ah
 
DEBUGF 1, "K : PIO mode %x\n", eax
mov ax, [Sector512+63*2]
DEBUGF 1, "K : Multiword DMA possible modes %x\n", al
 
mov al, ah
call convert_Sector512_value
DEBUGF 1, "K : Multiword DMA set mode %x\n", ah
 
DEBUGF 1, "K : Multiword DMA mode %x\n", eax
mov ax, [Sector512+88*2]
DEBUGF 1, "K : Ultra DMA possible modes %x\n", al
 
mov [ebx+IDE_DEVICE.UDMA_possible_modes], al
 
mov al, ah
call convert_Sector512_value
DEBUGF 1, "K : Ultra DMA set mode %x\n", ah
 
mov [ebx+IDE_DEVICE.UDMA_set_mode], ah
 
popfd
popad
DEBUGF 1, "K : Ultra DMA mode %x\n", eax
FindHDD_2_2:
ret
;--------------------------------------
.end:
DEBUGF 1, "K : Device not found\n"
ret
;-----------------------------------------------------------------------------
calculate_IDE_device_values_storage:
cmp ecx, IDE_controller_1
jne @f
 
add ebx, IDE_device_1
jmp .exit
;--------------------------------------
@@:
cmp ecx, IDE_controller_2
jne @f
 
add ebx, IDE_device_2
jmp .exit
;--------------------------------------
@@:
add ebx, IDE_device_3
;--------------------------------------
.exit:
FindHDD_3:
call FindHDD_1
shl byte [DRIVE_DATA+1], 2
ret
;-----------------------------------------------------------------------------
convert_Sector512_value:
mov ecx, 8
xor ah, ah
;--------------------------------------
@@:
test al, 1b
jnz .end
 
shr al, 1
inc ah
loop @b
 
xor ah, ah
;--------------------------------------
.end:
ret
;-----------------------------------------------------------------------------
; Адрес считываемого сектора в режиме LBA
uglobal
SectorAddress dd ?
SectorAddress DD ?
dev_name:
rb 41
endg
;-----------------------------------------------------------------------------
;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА *
;* Входные параметры передаются через глобальные *
218,32 → 119,32
; Послать команду идентификации устройства
mov [ATAFeatures], 0
mov [ATAHead], 0
mov [ATACommand], 0xEC
mov [ATACommand], 0ECh
call SendCommandToHDD
cmp [DevErrorCode], 0 ;проверить код ошибки
jne @@End ;закончить, сохранив код ошибки
 
mov dx, [ATABasePortAddr]
add dx, 7 ;адрес регистра состояни
mov DX, [ATABasePortAddr]
add DX, 7 ;адрес регистра состояни
mov ecx, 0xffff
@@WaitCompleet:
; Проверить время выполнения команды
dec ecx
; cmp ecx,0
jz @@Error1 ;ошибка тайм-аута
; Проверить готовность
in al, dx
test al, 80h ;состояние сигнала BSY
in AL, DX
test AL, 80h ;состояние сигнала BSY
jnz @@WaitCompleet
 
test al, 1 ;состояние сигнала ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Error6
 
test al, 08h ;состояние сигнала DRQ
test AL, 08h ;состояние сигнала DRQ
jz @@WaitCompleet
; Принять блок данных от контроллера
mov edi, Sector512
mov dx, [ATABasePortAddr];регистр данных
mov cx, 256 ;число считываемых слов
; mov AX,DS
; mov ES,AX
mov EDI, Sector512 ;offset Sector512
mov DX, [ATABasePortAddr];регистр данных
mov CX, 256 ;число считываемых слов
rep insw ;принять блок данных
ret
; Записать код ошибки
254,32 → 155,34
mov [DevErrorCode], 6
@@End:
ret
;-----------------------------------------------------------------------------
 
 
iglobal
; Стандартные базовые адреса каналов 1 и 2
StandardATABases DW 1F0h, 170h
endg
uglobal
; Стандартные базовые адреса каналов 1 и 2
StandardATABases dw ?, ? ; 1F0h, 170h
; Номер канала
ChannelNumber dw ?
ChannelNumber DW ?
; Номер диска
DiskNumber db ?
DiskNumber DB ?
; Базовый адрес группы портов контроллера ATA
ATABasePortAddr dw ?
ATABasePortAddr DW ?
; Параметры ATA-команды
ATAFeatures db ? ;особенности
ATASectorCount db ? ;количество обрабатываемых секторов
ATASectorNumber db ? ;номер начального сектора
ATACylinder dw ? ;номер начального цилиндра
ATAHead db ? ;номер начальной головки
ATAAddressMode db ? ;режим адресации (0 - CHS, 1 - LBA)
ATACommand db ? ;код команды, подлежащей выполнению
ATAFeatures DB ? ;особенности
ATASectorCount DB ? ;количество обрабатываемых секторов
ATASectorNumber DB ? ;номер начального сектора
ATACylinder DW ? ;номер начального цилиндра
ATAHead DB ? ;номер начальной головки
ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA)
ATACommand DB ? ;код команды, подлежащей выполнению
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
; интервал ожидания, 2 - неверный код режима адресации,
; 3 - неверный номер канала, 4 - неверный номер диска,
; 5 - неверный номер головки, 6 - ошибка при выполнении
; команды, 7 - таймаут при выборе канала)
; команды)
DevErrorCode dd ?
endg
;-----------------------------------------------------------------------------
;****************************************************
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
;* Входные параметры передаются через глобальные *
304,78 → 207,82
cmp [ATAAddressMode], 1
ja @@Err2
; Проверить корректность номера канала
mov bx, [ChannelNumber]
cmp bx, 1
mov BX, [ChannelNumber]
cmp BX, 1
jb @@Err3
 
cmp bx, 2
cmp BX, 2
ja @@Err3
; Установить базовый адрес
dec bx
shl bx, 1
dec BX
shl BX, 1
movzx ebx, bx
mov ax, [ebx+StandardATABases]
mov [ATABasePortAddr], ax
mov AX, [ebx+StandardATABases]
mov [ATABasePortAddr], AX
; Ожидание готовности HDD к приему команды
; Выбрать нужный диск
mov dx, [ATABasePortAddr]
add dx, 6 ;адрес регистра головок
mov al, [DiskNumber]
cmp al, 1 ;проверить номера диска
mov DX, [ATABasePortAddr]
add DX, 6 ;адрес регистра головок
mov AL, [DiskNumber]
cmp AL, 1 ;проверить номера диска
ja @@Err4
 
shl al, 4
or al, 10100000b
out dx, al
shl AL, 4
or AL, 10100000b
out DX, AL
; Ожидать, пока диск не будет готов
inc dx
inc DX
mov ecx, 0xfff
; mov eax,[timer_ticks]
; mov [TickCounter_1],eax
@@WaitHDReady:
; Проверить время ожидани
dec ecx
; cmp ecx,0
jz @@Err1
; mov eax,[timer_ticks]
; sub eax,[TickCounter_1]
; cmp eax,300 ;ожидать 300 тиков
; ja @@Err1 ;ошибка тайм-аута
; Прочитать регистр состояни
in al, dx
in AL, DX
; Проверить состояние сигнала BSY
test al, 80h
test AL, 80h
jnz @@WaitHDReady
; Проверить состояние сигнала DRQ
test al, 08h
test AL, 08h
jnz @@WaitHDReady
; Загрузить команду в регистры контроллера
cli
mov dx, [ATABasePortAddr]
inc dx ;регистр "особенностей"
mov al, [ATAFeatures]
out dx, AL
inc dx ;счетчик секторов
mov al, [ATASectorCount]
out dx, AL
inc dx ;регистр номера сектора
mov al, [ATASectorNumber]
out dx, AL
inc dx ;номер цилиндра (младший байт)
mov ax, [ATACylinder]
out dx, AL
inc dx ;номер цилиндра (старший байт)
mov al, AH
out dx, AL
inc dx ;номер головки/номер диска
mov al, [DiskNumber]
shl al, 4
cmp [ATAHead], 0xF ;проверить номер головки
mov DX, [ATABasePortAddr]
inc DX ;регистр "особенностей"
mov AL, [ATAFeatures]
out DX, AL
inc DX ;счетчик секторов
mov AL, [ATASectorCount]
out DX, AL
inc DX ;регистр номера сектора
mov AL, [ATASectorNumber]
out DX, AL
inc DX ;номер цилиндра (младший байт)
mov AX, [ATACylinder]
out DX, AL
inc DX ;номер цилиндра (старший байт)
mov AL, AH
out DX, AL
inc DX ;номер головки/номер диска
mov AL, [DiskNumber]
shl AL, 4
cmp [ATAHead], 0Fh;проверить номер головки
ja @@Err5
 
or al, [ATAHead]
or al, 10100000b
mov ah, [ATAAddressMode]
shl ah, 6
or al, ah
out dx, al
or AL, [ATAHead]
or AL, 10100000b
mov AH, [ATAAddressMode]
shl AH, 6
or AL, AH
out DX, AL
; Послать команду
mov al, [ATACommand]
inc dx ;регистр команд
out dx, al
mov AL, [ATACommand]
inc DX ;регистр команд
out DX, AL
sti
; Сбросить признак ошибки
mov [DevErrorCode], 0
382,7 → 289,7
ret
; Записать код ошибки
@@Err1:
mov [DevErrorCode], 7
mov [DevErrorCode], 1
ret
@@Err2:
mov [DevErrorCode], 2
397,7 → 304,7
mov [DevErrorCode], 5
; Завершение работы программы
ret
;-----------------------------------------------------------------------------
 
;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI *
;* Входные параметры передаются через глобальные *
416,32 → 323,33
mov [ATASectorNumber], 0
mov [ATACylinder], 0
mov [ATAHead], 0
mov [ATACommand], 0xA1
mov [ATACommand], 0A1h
call SendCommandToHDD
cmp [DevErrorCode], 0;проверить код ошибки
jne @@End_1 ;закончить, сохранив код ошибки
; Ожидать готовность данных HDD
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
mov DX, [ATABasePortAddr]
add DX, 7 ;порт 1х7h
mov ecx, 0xffff
@@WaitCompleet_1:
; Проверить врем
dec ecx
; cmp ecx,0
jz @@Error1_1 ;ошибка тайм-аута
; Проверить готовность
in al, dx
test al, 80h ;состояние сигнала BSY
in AL, DX
test AL, 80h ;состояние сигнала BSY
jnz @@WaitCompleet_1
 
test al, 1 ;состояние сигнала ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Error6_1
 
test al, 08h ;состояние сигнала DRQ
test AL, 08h ;состояние сигнала DRQ
jz @@WaitCompleet_1
; Принять блок данных от контроллера
mov edi, Sector512 ;offset Sector512
mov dx, [ATABasePortAddr];порт 1x0h
mov cx, 256;число считываемых слов
; mov AX,DS
; mov ES,AX
mov EDI, Sector512 ;offset Sector512
mov DX, [ATABasePortAddr];порт 1x0h
mov CX, 256;число считываемых слов
rep insw
ret
; Записать код ошибки
452,7 → 360,7
mov [DevErrorCode], 6
@@End_1:
ret
;-----------------------------------------------------------------------------
 
;*************************************************
;* СБРОС УСТРОЙСТВА *
;* Входные параметры передаются через глобальные *
462,40 → 370,39
;*************************************************
DeviceReset:
; Проверить корректность номера канала
mov bx, [ChannelNumber]
cmp bx, 1
mov BX, [ChannelNumber]
cmp BX, 1
jb @@Err3_2
 
cmp bx, 2
cmp BX, 2
ja @@Err3_2
; Установить базовый адрес
dec bx
shl bx, 1
dec BX
shl BX, 1
movzx ebx, bx
mov dx, [ebx+StandardATABases]
mov [ATABasePortAddr], dx
mov DX, [ebx+StandardATABases]
mov [ATABasePortAddr], DX
; Выбрать нужный диск
add dx, 6 ;адрес регистра головок
mov al, [DiskNumber]
cmp al, 1 ;проверить номера диска
add DX, 6 ;адрес регистра головок
mov AL, [DiskNumber]
cmp AL, 1 ;проверить номера диска
ja @@Err4_2
 
shl al, 4
or al, 10100000b
out dx, al
shl AL, 4
or AL, 10100000b
out DX, AL
; Послать команду "Сброс"
mov al, 0x8
inc dx ;регистр команд
out dx, al
mov AL, 08h
inc DX ;регистр команд
out DX, AL
mov ecx, 0x80000
@@WaitHDReady_1:
; Проверить время ожидани
dec ecx
; cmp ecx,0
je @@Err1_2 ;ошибка тайм-аута
; Прочитать регистр состояни
in al, dx
in AL, DX
; Проверить состояние сигнала BSY
test al, 80h
test AL, 80h
jnz @@WaitHDReady_1
; Сбросить признак ошибки
mov [DevErrorCode], 0
511,5 → 418,6
mov [DevErrorCode], 4
; Записать код ошибки
ret
;-----------------------------------------------------------------------------
 
EndFindHDD:
 
/kernel/branches/Kolibri-acpi/detect/getcache.inc
7,7 → 7,6
 
$Revision$
 
;-----------------------------------------------------------------------------
pusha
 
mov eax, [pg_data.pages_free]
21,167 → 20,89
; check a upper size of the cache, no more than 1 Mb on the physical device
cmp eax, 1024*1024
jbe @f
 
mov eax, 1024*1024
jmp .continue
;--------------------------------------
@@:
; check a lower size of the cache, not less than 128 Kb on the physical device
cmp eax, 128*1024
jae .continue
 
jae @f
mov eax, 128*1024
;--------------------------------------
@@:
.continue:
push ecx
mov ecx, 12
mov esi, cache_ide0+IDE_CACHE.size
cld
@@:
mov [esi], eax
add esi, sizeof.IDE_CACHE
loop @b
 
pop ecx
 
mov [cache_ide0_size], eax
mov [cache_ide1_size], eax
mov [cache_ide2_size], eax
mov [cache_ide3_size], eax
xor eax, eax
mov [hdd_appl_data], 1 ;al
mov [cd_appl_data], 1
;--------------------------------------
test byte [DRIVE_DATA+1], 0x80
je @f
 
mov esi, cache_ide0
test byte [DRIVE_DATA+1], 2
je .ide2
mov esi, cache_ide3
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+1], 0x20
je @f
 
mov esi, cache_ide1
call get_cache_ide
;--------------------------------------
@@:
.ide2:
test byte [DRIVE_DATA+1], 8
je @f
 
je .ide1
mov esi, cache_ide2
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+1], 2
je @f
 
mov esi, cache_ide3
.ide1:
test byte [DRIVE_DATA+1], 0x20
je .ide0
mov esi, cache_ide1
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+6], 0x80
.ide0:
test byte [DRIVE_DATA+1], 0x80
je @f
 
mov esi, cache_ide4
mov esi, cache_ide0
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+6], 0x20
je @f
jmp end_get_cache
 
mov esi, cache_ide5
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+6], 8
je @f
 
mov esi, cache_ide6
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+6], 2
je @f
 
mov esi, cache_ide7
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+11], 0x80
je @f
 
mov esi, cache_ide8
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+11], 0x20
je @f
 
mov esi, cache_ide9
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+11], 8
je @f
 
mov esi, cache_ide10
call get_cache_ide
;--------------------------------------
@@:
test byte [DRIVE_DATA+11], 2
je end_get_cache
 
mov esi, cache_ide11
call get_cache_ide
 
jmp end_get_cache
;-----------------------------------------------------------------------------
get_cache_ide:
and [esi+IDE_CACHE.search_start], 0
and [esi+IDE_CACHE.appl_search_start], 0
 
and [esi+cache_ide0_search_start-cache_ide0], 0
and [esi+cache_ide0_appl_search_start-cache_ide0], 0
push ecx
; DEBUGF 1, "K : IDE_CACHE.size %x\n", [esi+IDE_CACHE.size]
stdcall kernel_alloc, [esi+IDE_CACHE.size]
mov [esi+IDE_CACHE.pointer], eax
stdcall kernel_alloc, [esi+cache_ide0_size-cache_ide0]
mov [esi+cache_ide0_pointer-cache_ide0], eax
pop ecx
 
mov edx, eax
mov eax, [esi+IDE_CACHE.size]
mov eax, [esi+cache_ide0_size-cache_ide0]
shr eax, 3
; DEBUGF 1, "K : IDE_CACHE.system_data_size %x\n", eax
mov [esi+IDE_CACHE.system_data_size], eax
mov [esi+cache_ide0_system_data_size-cache_ide0], eax
mov ebx, eax
imul eax, 7
; DEBUGF 1, "K : IDE_CACHE.appl_data_size %x\n", eax
mov [esi+IDE_CACHE.appl_data_size], eax
mov [esi+cache_ide0_appl_data_size-cache_ide0], eax
add ebx, edx
mov [esi+IDE_CACHE.data_pointer], ebx
mov [esi+cache_ide0_data_pointer-cache_ide0], ebx
 
.cd:
push ecx
mov eax, [esi+IDE_CACHE.system_data_size]
mov eax, [esi+cache_ide0_system_data_size-cache_ide0]
call calculate_for_cd
add eax, [esi+IDE_CACHE.pointer]
mov [esi+IDE_CACHE.system_data], eax
mov [esi+IDE_CACHE.system_sad_size], ecx
add eax, [esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0], eax
mov [esi+cache_ide0_system_sad_size-cache_ide0], ecx
 
push edi
mov edi, [esi+IDE_CACHE.pointer]
mov edi, [esi+cache_ide0_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
mov eax, [esi+IDE_CACHE.appl_data_size]
mov eax, [esi+cache_ide0_appl_data_size-cache_ide0]
call calculate_for_cd
add eax, [esi+IDE_CACHE.data_pointer]
mov [esi+IDE_CACHE.appl_data], eax
mov [esi+IDE_CACHE.appl_sad_size], ecx
add eax, [esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0], eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0], ecx
 
push edi
mov edi, [esi+IDE_CACHE.data_pointer]
mov edi, [esi+cache_ide0_data_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
pop ecx
ret
;-----------------------------------------------------------------------------
 
calculate_for_cd:
push eax
mov ebx, eax
195,7 → 116,7
sub eax, ebx
dec ecx
ret
;-----------------------------------------------------------------------------
 
clear_ide_cache:
push eax
shl ecx, 1
204,6 → 125,6
rep stosd
pop eax
ret
;-----------------------------------------------------------------------------
 
end_get_cache:
popa
/kernel/branches/Kolibri-acpi/detect/sear_par.inc
8,42 → 8,21
$Revision$
 
search_partitions:
push ecx
; 1. Fill missing parameters in HD_DATA structures.
xor eax, eax
mov edx, IDE_controller_1
mov ax, [edx + IDE_DATA.BAR0_val]
mov [hd0_data.hdbase], eax
mov eax, [hd_address_table]
mov [hd0_data.hdbase], eax ;0x1f0
mov [hd1_data.hdbase], eax
mov ax, [edx + IDE_DATA.BAR2_val]
mov eax, [hd_address_table+16]
mov [hd2_data.hdbase], eax
mov [hd3_data.hdbase], eax
 
mov edx, IDE_controller_2
mov ax, [edx + IDE_DATA.BAR0_val]
mov [hd4_data.hdbase], eax
mov [hd5_data.hdbase], eax
mov ax, [edx + IDE_DATA.BAR2_val]
mov [hd6_data.hdbase], eax
mov [hd7_data.hdbase], eax
 
mov edx, IDE_controller_3
mov ax, [edx + IDE_DATA.BAR0_val]
mov [hd8_data.hdbase], eax
mov [hd9_data.hdbase], eax
mov ax, [edx + IDE_DATA.BAR2_val]
mov [hd10_data.hdbase], eax
mov [hd11_data.hdbase], eax
; 2. Notify the system about /hd* disks.
; For every existing disk, call ide_disk_add with correct parameters.
; Generate name "hdN" on the stack; this is 4 bytes including terminating zero.
;-----------------------------------------------------------------------------
; 2a. /hd0: exists if mask 0x40 in [DRIVE_DATA+1] is set,
; data: hd0_data,
; number of partitions: [DRIVE_DATA+2]
test [DRIVE_DATA+1], byte 0x40
jz @f
 
push 'hd0'
mov eax, esp ; name
mov edx, hd0_data
50,7 → 29,6
call ide_disk_add
mov [DRIVE_DATA+2], al
pop ecx ; restore the stack
;-----------------------------------------------------------------------------
@@:
; 2b. /hd1: exists if mask 0x10 in [DRIVE_DATA+1] is set,
; data: hd1_data,
57,7 → 35,6
; number of partitions: [DRIVE_DATA+3]
test [DRIVE_DATA+1], byte 0x10
jz @f
 
push 'hd1'
mov eax, esp
mov edx, hd1_data
64,7 → 41,6
call ide_disk_add
mov [DRIVE_DATA+3], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2c. /hd2: exists if mask 4 in [DRIVE_DATA+1] is set,
; data: hd2_data,
71,7 → 47,6
; number of partitions: [DRIVE_DATA+4]
test [DRIVE_DATA+1], byte 4
jz @f
 
push 'hd2'
mov eax, esp
mov edx, hd2_data
78,7 → 53,6
call ide_disk_add
mov [DRIVE_DATA+4], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2d. /hd3: exists if mask 1 in [DRIVE_DATA+1] is set,
; data: hd3_data,
85,7 → 59,6
; number of partitions: [DRIVE_DATA+5]
test [DRIVE_DATA+1], byte 1
jz @f
 
push 'hd3'
mov eax, esp
mov edx, hd3_data
92,120 → 65,7
call ide_disk_add
mov [DRIVE_DATA+5], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2e. /hd4: exists if mask 0x40 in [DRIVE_DATA+6] is set,
; data: hd4_data,
; number of partitions: [DRIVE_DATA+7]
test [DRIVE_DATA+6], byte 0x40
jz @f
 
push 'hd4'
mov eax, esp ; name
mov edx, hd4_data
call ide_disk_add
mov [DRIVE_DATA+7], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2f. /hd5: exists if mask 0x10 in [DRIVE_DATA+6] is set,
; data: hd5_data,
; number of partitions: [DRIVE_DATA+8]
test [DRIVE_DATA+6], byte 0x10
jz @f
 
push 'hd5'
mov eax, esp
mov edx, hd5_data
call ide_disk_add
mov [DRIVE_DATA+8], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2g. /hd6: exists if mask 4 in [DRIVE_DATA+6] is set,
; data: hd6_data,
; number of partitions: [DRIVE_DATA+9]
test [DRIVE_DATA+6], byte 4
jz @f
 
push 'hd6'
mov eax, esp
mov edx, hd6_data
call ide_disk_add
mov [DRIVE_DATA+9], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2h. /hd7: exists if mask 1 in [DRIVE_DATA+6] is set,
; data: hd7_data,
; number of partitions: [DRIVE_DATA+10]
test [DRIVE_DATA+6], byte 1
jz @f
 
push 'hd7'
mov eax, esp
mov edx, hd7_data
call ide_disk_add
mov [DRIVE_DATA+10], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2i. /hd8: exists if mask 0x40 in [DRIVE_DATA+11] is set,
; data: hd8_data,
; number of partitions: [DRIVE_DATA+12]
test [DRIVE_DATA+11], byte 0x40
jz @f
 
push 'hd8'
mov eax, esp ; name
mov edx, hd8_data
call ide_disk_add
mov [DRIVE_DATA+12], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2j. /hd9: exists if mask 0x10 in [DRIVE_DATA+11] is set,
; data: hd9_data,
; number of partitions: [DRIVE_DATA+13]
test [DRIVE_DATA+11], byte 0x10
jz @f
 
push 'hd9'
mov eax, esp
mov edx, hd9_data
call ide_disk_add
mov [DRIVE_DATA+13], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2k. /hd10: exists if mask 4 in [DRIVE_DATA+11] is set,
; data: hd10_data,
; number of partitions: [DRIVE_DATA+14]
test [DRIVE_DATA+14], byte 4
jz @f
 
push 'hd10'
mov eax, esp
mov edx, hd10_data
call ide_disk_add
mov [DRIVE_DATA+9], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 2l. /hd11: exists if mask 1 in [DRIVE_DATA+11] is set,
; data: hd11_data,
; number of partitions: [DRIVE_DATA+15]
test [DRIVE_DATA+11], byte 1
jz @f
 
push 'hd11'
mov eax, esp
mov edx, hd11_data
call ide_disk_add
mov [DRIVE_DATA+15], al
pop ecx
;-----------------------------------------------------------------------------
@@:
; 3. Notify the system about /bd* disks.
; 3a. Check whether there are BIOS disks. If no, skip step 3.
xor esi, esi
255,10 → 115,10
pop ecx ecx ; restore stack after name
.nobd:
jmp end_search_partitions
;-----------------------------------------------------------------------------
 
; Helper procedure for search_partitions, adds one IDE disk.
; For compatibility, number of partitions for IDE disks is kept in a separate
; variable, so the procedure returns number of partitions.
; For compatibility, number of partitions for IDE disks is kept in a separate variable,
; so the procedure returns number of partitions.
; eax -> name, edx -> disk data
proc ide_disk_add
stdcall disk_add, ide_callbacks, eax, edx, 0
274,6 → 134,6
@@:
ret
endp
;-----------------------------------------------------------------------------
 
end_search_partitions:
pop ecx
 
/kernel/branches/Kolibri-acpi/detect/biosdisk.inc
1,13 → 1,10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2008-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2008-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; Detect all BIOS hard drives.
; diamond, 2008
; Do not include USB mass storages. CleverMouse, 2013
/kernel/branches/Kolibri-acpi/detect/biosmem.inc
1,13 → 1,10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2009-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2009-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; Query physical memory map from BIOS.
; diamond, 2009
 
/kernel/branches/Kolibri-acpi/gui/window.inc
26,7 → 26,7
}
 
uglobal
common_colours rd 48
common_colours rd 32
draw_limits RECT
endg
 
34,7 → 34,7
;------------------------------------------------------------------------------
syscall_draw_window: ;///// system function 0 /////////////////////////////////
;------------------------------------------------------------------------------
;? <description>.
;? <description>
;------------------------------------------------------------------------------
mov eax, edx
shr eax, 24
173,10 → 173,7
syscall_display_settings.02:
dec ebx
mov esi, ecx
cmp edx, 192
jnae @f
mov edx, 192 ; max size
@@:
and edx, 127
mov edi, common_colours
mov ecx, edx
rep movsb
186,10 → 183,7
align 4
syscall_display_settings.03:
mov edi, ecx
cmp edx, 192
jnae @f
mov edx, 192 ; max size
@@:
and edx, 127
mov esi, common_colours
mov ecx, edx
rep movsb
215,7 → 209,7
syscall_display_settings.06:
xor esi, esi
 
mov edi, [Screen_Max_X]
mov edi, [_display.width]
mov eax, ecx
movsx ebx, ax
sar eax, 16
239,7 → 233,7
;--------------------------------------
align 4
.check_horizontal:
mov edi, [Screen_Max_Y]
mov edi, [_display.height]
mov eax, edx
movsx ebx, ax
sar eax, 16
300,8 → 294,8
syscall_display_settings._.calculate_whole_screen:
xor eax, eax
xor ebx, ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
mov ecx, [_display.width]
mov edx, [_display.height]
jmp calculatescreen
;------------------------------------------------------------------------------
align 4
309,9 → 303,11
xor eax, eax
mov [draw_limits.left], eax
mov [draw_limits.top], eax
mov eax, [Screen_Max_X]
mov eax, [_display.width]
dec eax
mov [draw_limits.right], eax
mov eax, [Screen_Max_Y]
mov eax, [_display.height]
dec eax
mov [draw_limits.bottom], eax
mov eax, window_data
jmp redrawscreen
590,9 → 586,9
 
mov eax, [edi + WDATA.box.left]
add eax, [edi + WDATA.box.width]
mov ebx, [Screen_Max_X]
mov ebx, [_display.width]
cmp eax, ebx
jle .fix_vertical
jl .fix_vertical
mov eax, [edi + WDATA.box.width]
sub eax, ebx
jle @f
607,9 → 603,9
.fix_vertical:
mov eax, [edi + WDATA.box.top]
add eax, [edi + WDATA.box.height]
mov ebx, [Screen_Max_Y]
mov ebx, [_display.height]
cmp eax, ebx
jle .fix_client_box
jl .fix_client_box
mov eax, [edi + WDATA.box.height]
sub eax, ebx
jle @f
823,8 → 819,12
jnz .exit
 
; does client area have a positive size on screen?
cmp [esi + WDATA.box.height], 21
jle .exit
mov edx, [esi + WDATA.box.top]
add edx, 21 + 5
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
 
; okay, let's draw it
mov eax, 1
1718,9 → 1718,9
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
 
mov esi, [Screen_Max_X]
mov esi, [_display.width]
cmp ecx, esi
ja .fix_width_high
jae .fix_width_high
;--------------------------------------
align 4
.check_left:
1732,9 → 1732,9
;--------------------------------------
align 4
.check_height:
mov esi, [Screen_Max_Y]
mov esi, [_display.height]
cmp edx, esi
ja .fix_height_high
jae .fix_height_high
;--------------------------------------
align 4
.check_top:
1992,7 → 1992,7
 
sub ebp, [ff_xsz]
add ebp, [ff_x]
add ebp, [Screen_Max_X] ; screen.x
add ebp, [_display.width] ; screen.x
inc ebp
inc ebx
cmp ebx, [ff_ysz]
/kernel/branches/Kolibri-acpi/gui/skincode.inc
11,7 → 11,7
include "skindata.inc"
 
;skin_data = 0x00778000
;-----------------------------------------------------------------
;------------------------------------------------------------------------------
align 4
read_skin_file:
stdcall load_file, ebx
121,7 → 121,7
lea esi, [ebx+SKIN_PARAMS.dtp.data]
mov edi, common_colours
mov ecx, [ebx+SKIN_PARAMS.dtp.size]
and ecx, 255
and ecx, 127
rep movsb
mov eax, dword[ebx+SKIN_PARAMS.margin.right]
mov dword[_skinmargins+0], eax
/kernel/branches/Kolibri-acpi/gui/event.inc
454,11 → 454,7
cmp al, 120
jae .result ;overflow
inc byte[KEY_COUNT]
mov [KEY_BUFF+eax], dl
; store empty scancode
add eax, 120+2
mov [KEY_BUFF+eax], byte 0
sub eax, 120+2
mov [KEY_COUNT+1+eax], dl
;--------------------------------------
align 4
.result:
/kernel/branches/Kolibri-acpi/gui/skindata.inc
9,7 → 9,7
 
 
;
; WINDOW SKIN DATA.
; WINDOW SKIN DATA
;
 
iglobal
/kernel/branches/Kolibri-acpi/init.inc
128,12 → 128,12
mov [pg_data.kernel_tables-OS_BASE], edx
 
xor eax, eax
mov edi, sys_proc-OS_BASE
mov ecx, 8192/4
mov edi, sys_pgdir-OS_BASE
mov ecx, 4096/4
cld
rep stosd
 
mov edx, (sys_proc-OS_BASE+PROC.pdt_0)+ 0x800; (OS_BASE shr 20)
mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20)
bt [cpu_caps-OS_BASE], CAPS_PSE
jnc .no_PSE
 
177,9 → 177,9
dec ecx
jnz .map_kernel_tabs
 
mov dword [sys_proc-OS_BASE+PROC.pdt_0+(page_tabs shr 20)], sys_proc+PROC.pdt_0+PG_SW-OS_BASE
mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE
 
mov edi, (sys_proc+PROC.pdt_0-OS_BASE)
mov edi, (sys_pgdir-OS_BASE)
lea esi, [edi+(OS_BASE shr 20)]
movsd
movsd
345,6 → 345,9
proc test_cpu
locals
cpu_type dd ?
cpu_id dd ?
cpu_Intel dd ?
cpu_AMD dd ?
endl
 
xor eax, eax
351,7 → 354,6
mov [cpu_type], eax
mov [cpu_caps-OS_BASE], eax
mov [cpu_caps+4-OS_BASE], eax
mov [cpu_phys_addr_width-OS_BASE], 32
 
pushfd
pop eax
376,6 → 378,7
pop eax
xor eax, ecx
je .end_cpuid
mov [cpu_id], 1
 
xor eax, eax
cpuid
383,7 → 386,13
mov [cpu_vendor-OS_BASE], ebx
mov [cpu_vendor+4-OS_BASE], edx
mov [cpu_vendor+8-OS_BASE], ecx
 
cmp ebx, dword [intel_str-OS_BASE]
jne .check_AMD
cmp edx, dword [intel_str+4-OS_BASE]
jne .check_AMD
cmp ecx, dword [intel_str+8-OS_BASE]
jne .check_AMD
mov [cpu_Intel], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
393,20 → 402,6
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
 
bt edx, CAPS_PAE
jnc @f
mov [cpu_phys_addr_width-OS_BASE], 36
@@:
mov eax, 0x80000000
cpuid
cmp eax, 0x80000008
jb @f
mov eax, 0x80000008
cpuid
mov [cpu_phys_addr_width-OS_BASE], al
@@:
 
mov eax, [cpu_sign-OS_BASE]
shr eax, 8
and eax, 0x0f
ret
413,6 → 408,36
.end_cpuid:
mov eax, [cpu_type]
ret
 
.check_AMD:
cmp ebx, dword [AMD_str-OS_BASE]
jne .unknown
cmp edx, dword [AMD_str+4-OS_BASE]
jne .unknown
cmp ecx, dword [AMD_str+8-OS_BASE]
jne .unknown
mov [cpu_AMD], 1
cmp eax, 1
jl .unknown
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
shr eax, 8
and eax, 0x0f
ret
.unknown:
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
shr eax, 8
and eax, 0x0f
ret
endp
 
iglobal
/kernel/branches/Kolibri-acpi/kernel.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.
;; PROGRAMMING:
;; Ivan Poddubny
;; Marat Zakiyanov (Mario79)
291,7 → 291,7
 
; ENABLE PAGING
 
mov eax, sys_proc-OS_BASE+PROC.pdt_0
mov eax, sys_pgdir-OS_BASE
mov cr3, eax
 
mov eax, cr0
309,25 → 309,6
org $-0x10000
include "boot/shutdown.inc" ; shutdown or restart
org $+0x10000
 
ap_init16:
cli
lgdt [cs:gdts_ap-ap_init16]
mov eax, [cs:cr3_ap-ap_init16]
mov cr3, eax
mov eax, [cs:cr4_ap-ap_init16]
mov cr4, eax
mov eax, CR0_PE+CR0_PG+CR0_WP
mov cr0, eax
jmp pword os_code:ap_init_high
align 16
gdts_ap:
dw gdte-gdts-1
dd gdts
dw 0
cr3_ap dd ?
cr4_ap dd ?
ap_init16_size = $ - ap_init16
use32
 
__DEBUG__ fix 1
354,7 → 335,7
bt [cpu_caps], CAPS_PGE
jnc @F
 
or dword [sys_proc+PROC.pdt_0+(OS_BASE shr 20)], PG_GLOBAL
or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL
 
mov ebx, cr4
or ebx, CR4_PGE
361,8 → 342,8
mov cr4, ebx
@@:
xor eax, eax
mov dword [sys_proc+PROC.pdt_0], eax
mov dword [sys_proc+PROC.pdt_0+4], eax
mov dword [sys_pgdir], eax
mov dword [sys_pgdir+4], eax
 
mov eax, cr3
mov cr3, eax ; flush TLB
388,17 → 369,78
call mutex_init
mov ecx, ide_channel2_mutex
call mutex_init
mov ecx, ide_channel3_mutex
call mutex_init
mov ecx, ide_channel4_mutex
call mutex_init
mov ecx, ide_channel5_mutex
call mutex_init
mov ecx, ide_channel6_mutex
call mutex_init
;-----------------------------------------------------------------------------
; SAVE REAL MODE VARIABLES
;-----------------------------------------------------------------------------
save_variables_IDE_controller:
xor eax, eax
mov ax, [BOOT_VARS + BOOT_IDE_INTERR_16]
mov [IDE_Interrupt], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_PI_16]
mov [IDEContrProgrammingInterface], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BASE_ADDR]
mov [IDEContrRegsBaseAddr], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BAR0_16]
cmp ax, 0
je @f
cmp ax, 1
jne .no_PATA_BAR0
@@:
mov ax, 0x1F0
jmp @f
.no_PATA_BAR0:
and ax, 0xFFFC
@@:
mov [StandardATABases], ax
mov [hd_address_table], eax
mov [hd_address_table+8], eax
mov [IDE_BAR0_val], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BAR1_16]
cmp ax, 0
je @f
cmp ax, 1
jne .no_PATA_BAR1
@@:
mov ax, 0x3F4
jmp @f
.no_PATA_BAR1:
and ax, 0xFFFC
@@:
mov [IDE_BAR1_val], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BAR2_16]
cmp ax, 0
je @f
cmp ax, 1
jne .no_PATA_BAR2
@@:
mov ax, 0x170
jmp @f
.no_PATA_BAR2:
and ax, 0xFFFC
@@:
mov [StandardATABases+2], ax
mov [hd_address_table+16], eax
mov [hd_address_table+24], eax
mov [IDE_BAR2_val], ax
;--------------------------------------
mov ax, [BOOT_VARS + BOOT_IDE_BAR3_16]
cmp ax, 0
je @f
cmp ax, 1
jne .no_PATA_BAR3
@@:
mov ax, 0x374
jmp @f
.no_PATA_BAR3:
and ax, 0xFFFC
@@:
mov [IDE_BAR3_val], ax
 
; --------------- APM ---------------------
 
; init selectors
434,7 → 476,7
mov al, [BOOT_VARS+BOOT_DMA] ; DMA access
mov [allow_dma_access], al
movzx eax, byte [BOOT_VARS+BOOT_BPP] ; bpp
mov [_display.bits_per_pixel], eax
mov [_display.bpp], eax
mov [_display.vrefresh], 60
mov al, [BOOT_VARS+BOOT_DEBUG_PRINT] ; If nonzero, duplicates debug output to the screen
mov [debug_direct_print], al
444,13 → 486,11
mov [_display.width], eax
mov [display_width_standard], eax
dec eax
mov [Screen_Max_X], eax
mov [screen_workarea.right], eax
movzx eax, word [BOOT_VARS+BOOT_Y_RES]; Y max
mov [_display.height], eax
mov [display_height_standard], eax
dec eax
mov [Screen_Max_Y], eax
mov [screen_workarea.bottom], eax
movzx eax, word [BOOT_VARS+BOOT_VESA_MODE] ; screen mode
mov dword [SCR_MODE], eax
480,56 → 520,34
mov edi, BiosDisksData
rep movsd
 
setvideomode:
; GRAPHICS ADDRESSES
 
mov eax, [BOOT_VARS+BOOT_LFB]
mov [LFBAddress], eax
 
cmp word [SCR_MODE], 0x0012 ; VGA (640x480 16 colors)
je .vga
cmp word [SCR_MODE], 0x0013 ; MCGA (320*200 256 colors)
je .32bpp
cmp byte [_display.bits_per_pixel], 32
je .32bpp
cmp byte [_display.bits_per_pixel], 24
je .24bpp
cmp byte [_display.bits_per_pixel], 16
je .16bpp
; cmp byte [_display.bits_per_pixel], 15
; je .15bpp
cmp [SCR_MODE], word 0100000000000000b
jge setvesa20
cmp [SCR_MODE], word 0x13 ; EGA 320*200 256 colors
je v20ga32
jmp v20ga24
 
.vga:
mov [PUTPIXEL], VGA_putpixel
mov [GETPIXEL], Vesa20_getpixel32 ; Conversion buffer is 32 bpp
mov [_display.bytes_per_pixel], 4 ; Conversion buffer is 32 bpp
jmp .finish
setvesa20:
mov [PUTPIXEL], dword Vesa20_putpixel24 ; Vesa 2.0
mov [GETPIXEL], dword Vesa20_getpixel24
cmp byte [_display.bpp], 24
jz v20ga24
v20ga32:
mov [PUTPIXEL], dword Vesa20_putpixel32
mov [GETPIXEL], dword Vesa20_getpixel32
jmp no_mode_0x12
v20ga24:
cmp [SCR_MODE], word 0x12 ; 16 C VGA 640x480
jne no_mode_0x12
mov [PUTPIXEL], dword VGA_putpixel
mov [GETPIXEL], dword Vesa20_getpixel32
no_mode_0x12:
 
; .15bpp:
; mov [PUTPIXEL], Vesa20_putpixel15
; mov [GETPIXEL], Vesa20_getpixel15
; mov [_display.bytes_per_pixel], 2
; jmp .finish
 
.16bpp:
mov [PUTPIXEL], Vesa20_putpixel16
mov [GETPIXEL], Vesa20_getpixel16
mov [_display.bytes_per_pixel], 2
jmp .finish
 
.24bpp:
mov [PUTPIXEL], Vesa20_putpixel24
mov [GETPIXEL], Vesa20_getpixel24
mov [_display.bytes_per_pixel], 3
jmp .finish
 
.32bpp:
mov [PUTPIXEL], Vesa20_putpixel32
mov [GETPIXEL], Vesa20_getpixel32
mov [_display.bytes_per_pixel], 4
; jmp .finish
 
.finish:
mov [MOUSE_PICTURE], mousepointer
mov [MOUSE_PICTURE], dword mousepointer
mov [_display.check_mouse], check_mouse_area_for_putpixel
mov [_display.check_m_pixel], check_mouse_area_for_getpixel
 
619,7 → 637,7
call init_fpu
call init_malloc
 
stdcall alloc_kernel_space, 0x50000 ; FIXME check size
stdcall alloc_kernel_space, 0x51000
mov [default_io_map], eax
 
add eax, 0x2000
636,6 → 654,9
mov [proc_mem_tab], eax
 
add eax, ebx
mov [tmp_task_pdir], eax
 
add eax, ebx
mov [tmp_task_ptab], eax
 
add eax, ebx
693,26 → 714,7
mov esi, boot_setostask
call boot_log
 
mov edi, sys_proc
list_init edi
lea ecx, [edi+PROC.thr_list]
list_init ecx
mov [edi+PROC.pdt_0_phys], sys_proc-OS_BASE+PROC.pdt_0
 
mov eax, -1
mov edi, thr_slot_map+4
mov [edi-4], dword 0xFFFFFFF8
stosd
stosd
stosd
stosd
stosd
stosd
stosd
 
mov [current_process], sys_proc
 
mov edx, SLOT_BASE+256*1
mov edx, SLOT_BASE+256
mov ebx, [os_stack_seg]
add ebx, 0x2000
call setup_os_slot
735,70 → 737,7
mov dword [current_slot], SLOT_BASE + 256*2
mov dword [TASK_BASE], CURRENT_TASK + 32*2
 
; Move other CPUs to deep sleep, if it is useful
uglobal
use_mwait_for_idle db 0
endg
cmp [cpu_vendor+8], 'ntel'
jnz .no_wake_cpus
bt [cpu_caps+4], CAPS_MONITOR-32
jnc .no_wake_cpus
dbgstr 'using mwait for idle loop'
inc [use_mwait_for_idle]
mov ebx, [cpu_count]
cmp ebx, 1
jbe .no_wake_cpus
call create_trampoline_pgmap
mov [cr3_ap+OS_BASE], eax
mov eax, cr4
mov [cr4_ap+OS_BASE], eax
mov esi, OS_BASE + ap_init16
mov edi, OS_BASE + 8000h
mov ecx, (ap_init16_size + 3) / 4
rep movsd
stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW+PG_NOCACHE
mov [LAPIC_BASE], eax
lea edi, [eax+300h]
mov esi, smpt+4
dec ebx
.wake_cpus_loop:
lodsd
push esi
xor esi, esi
inc esi
shl eax, 24
mov [edi+10h], eax
; assert INIT IPI
mov dword [edi], 0C500h
call delay_ms
@@:
test dword [edi], 1000h
jnz @b
; deassert INIT IPI
mov dword [edi], 8500h
call delay_ms
@@:
test dword [edi], 1000h
jnz @b
; send STARTUP IPI
mov dword [edi], 600h + (8000h shr 12)
call delay_ms
@@:
test dword [edi], 1000h
jnz @b
pop esi
dec ebx
jnz .wake_cpus_loop
mov eax, [cpu_count]
dec eax
@@:
cmp [ap_initialized], eax
jnz @b
mov eax, [cr3_ap+OS_BASE]
call free_page
.no_wake_cpus:
 
 
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f
mov esi, boot_initirq
call boot_log
819,12 → 758,10
call PIT_init
 
; Register ramdisk file system
cmp [boot_dev+OS_BASE+0x10000], 1
je @f
mov esi, boot_initramdisk
call boot_log
call ramdisk_init
 
call register_ramdisk
;--------------------------------------
@@:
mov esi, boot_initapic
call boot_log
; Try to Initialize APIC
838,77 → 775,58
stdcall enable_irq, 2 ; @#$%! PIC
stdcall enable_irq, 13 ; co-processor
 
; Setup serial output console (if enabled)
if defined debug_com_base
cmp [IDEContrProgrammingInterface], 0
je @f
 
; reserve port so nobody else will use it
xor ebx, ebx
mov ecx, debug_com_base
mov edx, debug_com_base+7
call r_f_port_area
 
; enable Divisor latch
mov dx, debug_com_base+3
mov al, 1 shl 7
mov esi, boot_disabling_ide
call boot_log
;--------------------------------------
; Disable IDE interrupts, because the search
; for IDE partitions is in the PIO mode.
;--------------------------------------
.disable_IDE_interrupt:
; Disable interrupts in IDE controller for PIO
mov al, 2
mov dx, [IDE_BAR1_val] ;0x3F4
add dx, 2 ;0x3F6
out dx, al
 
; Set speed to 115200 baud (max speed)
mov dx, debug_com_base
mov al, 0x01
mov dx, [IDE_BAR3_val] ;0x374
add dx, 2 ;0x376
out dx, al
@@:
;-----------------------------------------------------------------------------
;!!!!!!!!!!!!!!!!!!!!!!!!!!
; mov esi, boot_detectdisks
; call boot_log
;include 'detect/disks.inc'
mov esi, boot_detectfloppy
call boot_log
include 'detect/dev_fd.inc'
mov esi, boot_detecthdcd
call boot_log
include 'detect/dev_hdcd.inc'
mov esi, boot_getcache
call boot_log
include 'detect/getcache.inc'
mov esi, boot_detectpart
call boot_log
include 'detect/sear_par.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!
 
mov dx, debug_com_base+1
mov al, 0x00
out dx, al
mov esi, boot_init_sys
call boot_log
call Parser_params
 
; No parity, 8bits words, one stop bit, dlab bit back to 0
mov dx, debug_com_base+3
mov al, 3
out dx, al
if ~ defined extended_primary_loader
; ramdisk image should be loaded by extended primary loader if it exists
; READ RAMDISK IMAGE FROM HD
 
; disable interrupts
mov dx, debug_com_base+1
mov al, 0
out dx, al
 
; clear + enable fifo (64 bits)
mov dx, debug_com_base+2
mov al, 0x7 + 1 shl 5
out dx, al
 
;!!!!!!!!!!!!!!!!!!!!!!!
include 'boot/rdload.inc'
;!!!!!!!!!!!!!!!!!!!!!!!
end if
; mov [dma_hdd],1
 
 
;-----------------------------------------------------------------------------
; show SVN version of kernel on the message board
;-----------------------------------------------------------------------------
mov eax, [version_inf.rev]
DEBUGF 1, "K : kernel SVN r%d\n", eax
;-----------------------------------------------------------------------------
; show CPU count on the message board
;-----------------------------------------------------------------------------
mov eax, [cpu_count]
test eax, eax
jnz @F
mov al, 1 ; at least one CPU
@@:
DEBUGF 1, "K : %d CPU detected\n", eax
;-----------------------------------------------------------------------------
; detect Floppy drives
;-----------------------------------------------------------------------------
mov esi, boot_detectfloppy
call boot_log
include 'detect/dev_fd.inc'
;-----------------------------------------------------------------------------
; create pci-devices list
;-----------------------------------------------------------------------------
mov [pci_access_enabled], 1
call pci_enum
;-----------------------------------------------------------------------------
; initialisation IDE ATA code
;-----------------------------------------------------------------------------
include 'detect/init_ata.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}
959,12 → 877,11
; mov esi, boot_devices
; call boot_log
 
call clear_pci_ide_interrupts
mov [pci_access_enabled], 1
call pci_enum
 
include "detect/vortex86.inc" ; Vortex86 SoC detection code
stdcall load_driver, szVidintel
 
stdcall load_pe_driver, szVidintel, 0
 
call usb_init
 
; SET PRELIMINARY WINDOW STACK AND POSITIONS
1002,7 → 919,6
mov esi, 250 ; wait 1/4 a second
call delay_ms
rdtsc
sti
 
sub eax, ecx
xor edx, edx
1070,12 → 986,39
stdcall map_page, tss._io_map_1, \
[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP
 
; LOAD FIRST APPLICATION
cmp byte [launcher_start], 1 ; Check if starting LAUNCHER is selected on blue screen (1 = yes)
jnz first_app_found
 
cli
mov ebp, firstapp
call fs_execute_from_sysdir
test eax, eax
jns first_app_found
 
mov esi, boot_failed
call boot_log
 
mov eax, 0xDEADBEEF ; otherwise halt
hlt
 
first_app_found:
 
cli
 
; SET KEYBOARD PARAMETERS
mov al, 0xf6 ; reset keyboard, scan enabled
call kb_write_wait_ack
call kb_write
test ah, ah
jnz .no_keyboard
 
; wait until 8042 is ready
xor ecx, ecx
@@:
in al, 64h
and al, 00000010b
loopnz @b
 
iglobal
align 4
ps2_keyboard_functions:
1086,47 → 1029,94
endg
stdcall register_keyboard, ps2_keyboard_functions, 0
; mov al, 0xED ; Keyboard LEDs - only for testing!
; call kb_write_wait_ack
; call kb_write
; call kb_read
; mov al, 111b
; call kb_write_wait_ack
; call kb_write
; call kb_read
 
mov al, 0xF3 ; set repeat rate & delay
call kb_write_wait_ack
call kb_write
; call kb_read
mov al, 0; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500
call kb_write_wait_ack
call kb_write
; call kb_read
;// mike.dld [
call set_lights
;// mike.dld ]
stdcall attach_int_handler, 1, irq1, 0
DEBUGF 1, "K : IRQ1 return code %x\n", eax
DEBUGF 1, "K : IRQ1 error code %x\n", eax
.no_keyboard:
 
; Load PS/2 mouse driver
; SET MOUSE
 
stdcall load_pe_driver, szPS2MDriver, 0
stdcall load_driver, szPS2MDriver
; stdcall load_driver, szCOM_MDriver
 
mov esi, boot_setmouse
call boot_log
call setmouse
 
; LOAD FIRST APPLICATION
cmp byte [launcher_start], 1 ; Check if starting LAUNCHER is selected on blue screen (1 = yes)
jnz first_app_found
; Setup serial output console (if enabled)
 
cli
mov ebp, firstapp
call fs_execute_from_sysdir
if defined debug_com_base
 
; enable Divisor latch
 
mov dx, debug_com_base+3
mov al, 1 shl 7
out dx, al
 
; Set speed to 115200 baud (max speed)
 
mov dx, debug_com_base
mov al, 0x01
out dx, al
 
mov dx, debug_com_base+1
mov al, 0x00
out dx, al
 
; No parity, 8bits words, one stop bit, dlab bit back to 0
 
mov dx, debug_com_base+3
mov al, 3
out dx, al
 
; disable interrupts
 
mov dx, debug_com_base+1
mov al, 0
out dx, al
 
; clear + enable fifo (64 bits)
 
mov dx, debug_com_base+2
mov al, 0x7 + 1 shl 5
out dx, al
 
 
end if
mov eax, [version_inf.rev]
DEBUGF 1, "K : kernel SVN r%d\n", eax
 
mov eax, [cpu_count]
test eax, eax
jns first_app_found
jnz @F
mov al, 1 ; at least one CPU
@@:
DEBUGF 1, "K : %d CPU detected\n", eax
 
mov esi, boot_failed
call boot_log
include "detect/vortex86.inc" ; Vortex86 SoC detection code
 
mov eax, 0xDEADBEEF ; otherwise halt
hlt
DEBUGF 1, "K : BAR0 %x \n", [IDE_BAR0_val]:4
DEBUGF 1, "K : BAR1 %x \n", [IDE_BAR1_val]:4
DEBUGF 1, "K : BAR2 %x \n", [IDE_BAR2_val]:4
DEBUGF 1, "K : BAR3 %x \n", [IDE_BAR3_val]:4
DEBUGF 1, "K : BAR4 %x \n", [IDEContrRegsBaseAddr]:4
DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", [IDEContrProgrammingInterface]:4
DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4
 
first_app_found:
 
; START MULTITASKING
 
; A 'All set - press ESC to start' messages if need
1139,38 → 1129,104
jne .bll1
end if
 
push eax edx
mov dx, [IDEContrRegsBaseAddr]
xor eax, eax
add dx, 2
in al, dx
DEBUGF 1, "K : Primary Bus Master IDE Status Register %x\n", eax
 
add dx, 8
in al, dx
DEBUGF 1, "K : Secondary Bus Master IDE Status Register %x\n", eax
pop edx eax
 
cmp [IDEContrRegsBaseAddr], 0
setnz [dma_hdd]
 
cmp [IDEContrProgrammingInterface], 0
je set_interrupts_for_IDE_controllers.continue
 
mov ax, [IDE_Interrupt]
cmp al, 0xff
jne @f
 
mov [dma_hdd], 0
jmp set_interrupts_for_IDE_controllers.end_set_interrupts
@@:
;-----------------------------------------------------------------------------
; set interrupts for IDE Controller
;-----------------------------------------------------------------------------
mov esi, boot_set_int_IDE
call boot_log
set_interrupts_for_IDE_controllers:
mov ax, [IDEContrProgrammingInterface]
cmp ax, 0x0180
je .pata_ide
 
cmp ax, 0x018a
jne .sata_ide
;--------------------------------------
.pata_ide:
cmp [IDEContrRegsBaseAddr], 0
je .end_set_interrupts
 
stdcall attach_int_handler, 14, IDE_irq_14_handler, 0
DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax
stdcall attach_int_handler, 15, IDE_irq_15_handler, 0
DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax
jmp .enable_IDE_interrupt
;--------------------------------------
.sata_ide:
cmp ax, 0x0185
je .sata_ide_1
 
cmp ax, 0x018f
jne .end_set_interrupts
;--------------------------------------
.sata_ide_1:
cmp [IDEContrRegsBaseAddr], 0
je .end_set_interrupts
 
mov ax, [IDE_Interrupt]
movzx eax, al
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [IDE_Interrupt]:1, eax
;--------------------------------------
.enable_IDE_interrupt:
mov esi, boot_enabling_ide
call boot_log
; Enable interrupts in IDE controller for DMA
mov al, 0
mov dx, [IDE_BAR1_val] ;0x3F4
add dx, 2 ;0x3F6
out dx, al
mov dx, [IDE_BAR3_val] ;0x374
add dx, 2 ;0x376
out dx, al
;--------------------------------------
.end_set_interrupts:
;-----------------------------------------------------------------------------
cmp [dma_hdd], 0
je .print_pio
.print_dma:
DEBUGF 1, "K : IDE DMA mode\n"
jmp .continue
 
.print_pio:
DEBUGF 1, "K : IDE PIO mode\n"
.continue:
 
mov [timer_ticks_enable], 1 ; for cd driver
 
sti
; call change_task
 
call mtrr_validate
 
jmp osloop
 
 
; Fly :)
 
uglobal
align 4
ap_initialized dd 0
endg
 
ap_init_high:
mov ax, os_stack
mov bx, app_data
mov cx, app_tls
mov ss, ax
mov ds, bx
mov es, bx
mov fs, cx
mov gs, bx
xor esp, esp
mov eax, sys_proc-OS_BASE+PROC.pdt_0
mov cr3, eax
lock inc [ap_initialized]
jmp idle_loop
 
 
include 'unpacker.inc'
 
align 4
1228,12 → 1284,8
 
mov dword [edx+APPDATA.cur_dir], sysdir_path
 
mov [edx + APPDATA.process], sys_proc
mov [edx + APPDATA.dir_table], sys_pgdir - OS_BASE
 
lea ebx, [edx+APPDATA.list]
lea ecx, [sys_proc+PROC.thr_list]
list_add_tail ebx, ecx
 
mov eax, edx
shr eax, 3
add eax, CURRENT_TASK - (SLOT_BASE shr 3)
1257,13 → 1309,12
xchg eax, [osloop_nonperiodic_work]
test eax, eax
jz .no_periodic
 
; call [draw_pointer]
call __sys_draw_pointer
call window_check_events
call mouse_check_events
call checkmisc
call checkVga_N13
;--------------------------------------
.no_periodic:
call stack_handler
call check_fdd_motor_status
1270,7 → 1321,6
call check_ATAPI_device_event
call check_lights_state
call check_timers
 
jmp osloop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
1309,35 → 1359,13
osloop_nonperiodic_work dd ?
endg
 
uglobal
align 64
idle_addr rb 64
endg
 
align 4
idle_thread:
sti
 
; The following code can be executed by all CPUs in the system.
; All other parts of the kernel do not expect multi-CPU.
; Also, APs don't even have a stack here.
; Beware. Don't do anything here. Anything at all.
idle_loop:
cmp [use_mwait_for_idle], 0
jnz idle_loop_mwait
 
idle_loop_hlt:
hlt
jmp idle_loop_hlt
jmp idle_loop
 
idle_loop_mwait:
mov eax, idle_addr
xor ecx, ecx
xor edx, edx
monitor
xor ecx, ecx
mov eax, 20h ; or 10h
mwait
jmp idle_loop_mwait
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1660,231 → 1688,280
mov eax, [esp+64+8] ; background color (if given)
mov edi, [esp+64+4]
jmp dtext
;-----------------------------------------------------------------------------
iglobal
midi_base dw 0
endg
;-----------------------------------------------------------------------------
 
align 4
 
sys_setup:
 
; 1 = roland mpu midi base , base io address
; 2 = keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus
; 3 = not used
; 4 = not used
; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave
; 5 = system language, 1eng 2fi 3ger 4rus
; 6 = not used
; 7 = not used
; 8 = not used
; 9 = not used
; 10 = not used
; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave
; 8=fat32 partition in hd
; 9
; 10 = sound dma channel
; 11 = enable lba read
; 12 = enable pci access
;-----------------------------------------------------------------------------
 
 
and [esp+32], dword 0
; F.21.1 - set MPU MIDI base port
dec ebx
jnz @f
 
dec ebx ; MIDI
jnz nsyse1
cmp ecx, 0x100
jb @f
 
jb nsyse1
mov esi, 65535
cmp esi, ecx
jb @f
 
mov [midi_base], cx
mov word [mididp], cx
inc cx
mov word [midisp], cx
jb nsyse1
mov [midi_base], cx ;bx
mov word [mididp], cx;bx
inc cx ;bx
mov word [midisp], cx;bx
ret
;--------------------------------------
@@:
; F.21.2 - set keyboard layout
dec ebx
jnz @f
 
iglobal
midi_base dw 0
endg
 
nsyse1:
dec ebx ; KEYBOARD
jnz nsyse2
mov edi, [TASK_BASE]
mov eax, [edi+TASKDATA.mem_start]
add eax, edx
; 1 = normal layout
 
dec ecx
jnz .shift
 
jnz kbnobase
mov ebx, keymap
mov ecx, 128
call memmove
ret
;--------------------------------------
.shift:
; 2 = layout at pressed Shift
kbnobase:
dec ecx
jnz .alt
jnz kbnoshift
 
mov ebx, keymap_shift
mov ecx, 128
call memmove
ret
;--------------------------------------
.alt:
; 3 = layout at pressed Alt
kbnoshift:
dec ecx
jnz .country
 
jnz kbnoalt
mov ebx, keymap_alt
mov ecx, 128
call memmove
ret
;--------------------------------------
.country:
; country identifier
kbnoalt:
sub ecx, 6
jnz .error
 
jnz kbnocountry
mov word [keyboard], dx
ret
;--------------------------------------
@@:
; F.21.5 - set system language
sub ebx, 3
jnz @f
kbnocountry:
mov [esp+32], dword 1
ret
nsyse2:
dec ebx ; CD
jnz nsyse4
 
test ecx, ecx
jz nosesl
 
cmp ecx, 4
ja nosesl
mov [cd_base], cl
 
dec ecx
jnz noprma
mov eax, [hd_address_table]
mov [cdbase], eax ;0x1f0
mov [cdid], 0xa0
noprma:
 
dec ecx
jnz noprsl
mov eax, [hd_address_table]
mov [cdbase], eax ;0x1f0
mov [cdid], 0xb0
noprsl:
dec ecx
jnz nosema
mov eax, [hd_address_table+16]
mov [cdbase], eax ;0x170
mov [cdid], 0xa0
nosema:
dec ecx
jnz nosesl
mov eax, [hd_address_table+16]
mov [cdbase], eax ;0x170
mov [cdid], 0xb0
nosesl:
ret
 
iglobal
cd_base db 0
 
endg
nsyse4:
 
sub ebx, 2 ; SYSTEM LANGUAGE
jnz nsyse5
mov [syslang], ecx
ret
;--------------------------------------
@@:
; F.21.11 - enable/disable low-level access to HD
nsyse5:
 
sub ebx, 2 ; HD BASE - obsolete
jnz nsyse7
 
nosethd:
ret
 
nsyse7:
 
; cmp eax,8 ; HD PARTITION - obsolete
dec ebx
jnz nsyse8
ret
 
nsyse8:
; cmp eax,11 ; ENABLE LBA READ
and ecx, 1
sub ebx, 6
jnz @f
 
sub ebx, 3
jnz no_set_lba_read
mov [lba_read_enabled], ecx
ret
;--------------------------------------
@@:
; F.21.12 - enable/disable low-level access to PCI
 
no_set_lba_read:
; cmp eax,12 ; ENABLE PCI ACCESS
dec ebx
jnz .error
 
jnz sys_setup_err
mov [pci_access_enabled], ecx
ret
;--------------------------------------
.error:
 
sys_setup_err:
or [esp+32], dword -1
ret
;-----------------------------------------------------------------------------
 
align 4
 
sys_getsetup:
 
; 1 = roland mpu midi base , base io address
; 2 = keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus
; 3 = not used
; 4 = not used
; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave
; 5 = system language, 1eng 2fi 3ger 4rus
; 6 = not used
; 7 = not used
; 8 = not used
; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave
; 8=fat32 partition in hd
; 9 = get hs timer tic
; 10 = not used
; 11 = get the state "lba read"
; 12 = get the state "pci access"
;-----------------------------------------------------------------------------
; F.26.1 - get MPU MIDI base port
 
; cmp eax,1
dec ebx
jnz @f
 
jnz ngsyse1
movzx eax, [midi_base]
mov [esp+32], eax
ret
;--------------------------------------
@@:
; F.26.2 - get keyboard layout
ngsyse1:
; cmp eax,2
dec ebx
jnz @f
jnz ngsyse2
 
mov edi, [TASK_BASE]
mov ebx, [edi+TASKDATA.mem_start]
add ebx, edx
; 1 = normal layout
 
; cmp ebx,1
dec ecx
jnz .shift
 
jnz kbnobaseret
mov eax, keymap
mov ecx, 128
call memmove
ret
;--------------------------------------
.shift:
; 2 = layout with pressed Shift
kbnobaseret:
; cmp ebx,2
dec ecx
jnz .alt
jnz kbnoshiftret
 
mov eax, keymap_shift
mov ecx, 128
call memmove
ret
;--------------------------------------
.alt:
; 3 = layout with pressed Alt
kbnoshiftret:
; cmp ebx,3
dec ecx
jne .country
jne kbnoaltret
 
mov eax, keymap_alt
mov ecx, 128
call memmove
ret
;--------------------------------------
.country:
; 9 = country identifier
kbnoaltret:
; cmp ebx,9
sub ecx, 6
jnz .error
 
jnz ngsyse2
movzx eax, word [keyboard]
mov [esp+32], eax
ret
;--------------------------------------
@@:
; F.26.5 - get system language
sub ebx, 3
jnz @f
 
 
ngsyse2:
; cmp eax,3
dec ebx
jnz ngsyse3
movzx eax, [cd_base]
mov [esp+32], eax
ret
ngsyse3:
; cmp eax,5
sub ebx, 2
jnz ngsyse5
mov eax, [syslang]
mov [esp+32], eax
ret
;--------------------------------------
@@:
; F.26.9 - get the value of the time counter
sub ebx, 4
jnz @f
 
mov eax, [timer_ticks]
ngsyse5:
; cmp eax,7
sub ebx, 2
jnz ngsyse7
xor eax, eax
mov [esp+32], eax
ret
;--------------------------------------
@@:
; F.26.11 - Find out whether low-level HD access is enabled
ngsyse7:
; cmp eax,8
dec ebx
jnz ngsyse8
mov eax, [fat32part]
mov [esp+32], eax
ret
ngsyse8:
; cmp eax,9
dec ebx
jnz ngsyse9
mov eax, [timer_ticks];[0xfdf0]
mov [esp+32], eax
ret
ngsyse9:
; cmp eax,11
sub ebx, 2
jnz @f
 
jnz ngsyse11
mov eax, [lba_read_enabled]
mov [esp+32], eax
ret
;--------------------------------------
@@:
; F.26.12 - Find out whether low-level PCI access is enabled
ngsyse11:
; cmp eax,12
dec ebx
jnz .error
 
jnz ngsyse12
mov eax, [pci_access_enabled]
mov [esp+32], eax
ret
;--------------------------------------
.error:
or [esp+32], dword -1
ngsyse12:
mov [esp+32], dword 1
ret
;-----------------------------------------------------------------------------
 
 
get_timer_ticks:
mov eax, [timer_ticks]
ret
;-----------------------------------------------------------------------------
 
iglobal
align 4
mousefn dd msscreen, mswin, msbutton, msset
1893,7 → 1970,7
dd app_delete_cursor
dd msz
endg
;-----------------------------------------------------------------------------
 
readmousepos:
 
; eax=0 screen relative
2366,15 → 2443,27
;------------------------------------------------------------------------------
align 4
sysfn_getdiskinfo: ; 18.11 = get disk info table
; cmp ecx,1
dec ecx
jnz .exit
.small_table:
jnz full_table
small_table:
call for_all_tables
mov ecx, 10
cld
rep movsb
ret
for_all_tables:
mov edi, edx
mov esi, DRIVE_DATA
mov ecx, DRIVE_DATA_SIZE ;10
ret
full_table:
; cmp ecx,2
dec ecx
jnz exit_for_anyone
call for_all_tables
mov ecx, DRIVE_DATA_SIZE/4
cld
rep movsb
.exit:
rep movsd
ret
;------------------------------------------------------------------------------
sysfn_lastkey: ; 18.12 = return 0 (backward compatibility)
2406,10 → 2495,10
;* mouse centered - start code- Mario79
;mouse_centered:
; push eax
mov eax, [Screen_Max_X]
mov eax, [_display.width]
shr eax, 1
mov [MOUSE_X], ax
mov eax, [Screen_Max_Y]
mov eax, [_display.height]
shr eax, 1
mov [MOUSE_Y], ax
call wakeup_osloop
2451,13 → 2540,12
; cmp ecx,4 ; set mouse pointer position
dec ecx
jnz .set_mouse_button
cmp dx, word[Screen_Max_Y]
ja .end
cmp dx, word[_display.height]
jae .end
rol edx, 16
cmp dx, word[Screen_Max_X]
ja .end
cmp dx, word[_display.width]
jae .end
mov [MOUSE_X], edx
mov [mouse_active], 1
call wakeup_osloop
ret
.set_mouse_button:
2543,9 → 2631,7
mov eax, ecx
mov ecx, [_display.pitch]
mov [_display.width], eax
dec eax
mov [_display.height], edx
dec edx
; eax - new Screen_Max_X
; edx - new Screen_Max_Y
mov [do_not_touch_winmap], 1
2882,22 → 2968,22
jnz nosb9
; ecx = [left]*65536 + [right]
; edx = [top]*65536 + [bottom]
mov eax, [Screen_Max_X]
mov ebx, [Screen_Max_Y]
mov eax, [_display.width]
mov ebx, [_display.height]
; check [right]
cmp cx, ax
ja .exit
jae .exit
; check [left]
ror ecx, 16
cmp cx, ax
ja .exit
jae .exit
; check [bottom]
cmp dx, bx
ja .exit
jae .exit
; check [top]
ror edx, 16
cmp dx, bx
ja .exit
jae .exit
 
movzx eax, cx ; [left]
movzx ebx, dx ; [top]
2935,8 → 3021,8
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]
mov eax, [_display.width]
mov ebx, [_display.height]
mov [draw_data+32 + RECT.right], eax
mov [draw_data+32 + RECT.bottom], ebx
pop ebx eax
3010,10 → 3096,8
jne .finish
cmp [KEY_COUNT], byte 0
je .finish
movzx ax, byte [KEY_BUFF + 120 + 2]
movzx eax, byte [KEY_BUFF]
shl eax, 8
mov al, byte [KEY_BUFF]
shl eax, 8
push eax
dec byte [KEY_COUNT]
and byte [KEY_COUNT], 127
3022,9 → 3106,6
mov eax, KEY_BUFF + 1
mov ebx, KEY_BUFF
call memmove
add eax, 120 + 2
add ebx, 120 + 2
call memmove
pop eax
;--------------------------------------
align 4
3126,8 → 3207,7
mov edx, 0x100000*16
cmp ecx, 1 shl 5
je .os_mem
mov edx, [SLOT_BASE+ecx*8+APPDATA.process]
mov edx, [edx+PROC.mem_used]
mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size]
mov eax, std_application_base_address
.os_mem:
stosd
3298,9 → 3378,9
add edx, draw_data - CURRENT_TASK
mov [edx + RECT.left], 0
mov [edx + RECT.top], 0
mov eax, [Screen_Max_X]
mov eax, [_display.width]
mov [edx + RECT.right], eax
mov eax, [Screen_Max_Y]
mov eax, [_display.height]
mov [edx + RECT.bottom], eax
 
srl1:
3599,7 → 3679,7
cmp [edx+TASKDATA.state], 9
jz .nokill
lea edx, [(edx-(CURRENT_TASK and 1FFFFFFFh))*8+SLOT_BASE]
cmp [edx+APPDATA.process], sys_proc
cmp [edx+APPDATA.dir_table], sys_pgdir - OS_BASE
jz .nokill
call request_terminate
jmp .common
4623,40 → 4703,114
; ret
;-----------------------------------------------------------------------------
align 4
kb_write_wait_ack:
kb_read:
 
push ecx edx
 
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
kr_loop:
in al, 0x64
test al, 1
jnz kr_ready
loop kr_loop
mov ah, 1
jmp kr_exit
kr_ready:
push ecx
mov ecx, 32
kr_delay:
loop kr_delay
pop ecx
in al, 0x60
xor ah, ah
kr_exit:
 
pop edx ecx
 
ret
;-----------------------------------------------------------------------------
align 4
kb_write:
 
push ecx edx
 
mov dl, al
; mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
; kw_loop1:
; in al,0x64
; test al,0x20
; jz kw_ok1
; loop kw_loop1
; mov ah,1
; jmp kw_exit
; kw_ok1:
in al, 0x60
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
.wait_output_ready:
kw_loop:
in al, 0x64
test al, 2
jz @f
loop .wait_output_ready
jz kw_ok
loop kw_loop
mov ah, 1
jmp .nothing
@@:
jmp kw_exit
kw_ok:
mov al, dl
out 0x60, al
mov ecx, 0xfffff; last 0xffff, new value in view of fast CPU's
.wait_ack:
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
kw_loop3:
in al, 0x64
test al, 2
jz kw_ok3
loop kw_loop3
mov ah, 1
jmp kw_exit
kw_ok3:
mov ah, 8
kw_loop4:
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
kw_loop5:
in al, 0x64
test al, 1
jnz @f
loop .wait_ack
mov ah, 1
jmp .nothing
@@:
in al, 0x60
jnz kw_ok4
loop kw_loop5
dec ah
jnz kw_loop4
kw_ok4:
xor ah, ah
kw_exit:
 
.nothing:
pop edx ecx
 
ret
;-----------------------------------------------------------------------------
align 4
kb_cmd:
 
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
c_wait:
in al, 0x64
test al, 2
jz c_send
loop c_wait
jmp c_error
c_send:
mov al, bl
out 0x64, al
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
c_accept:
in al, 0x64
test al, 2
jz c_ok
loop c_accept
c_error:
mov ah, 1
jmp c_exit
c_ok:
xor ah, ah
c_exit:
ret
 
 
setmouse: ; set mousepicture -pointer
; ps2 mouse enable
 
4793,9 → 4947,9
jnz @f
mov word [msg_board_pos+2], (42*6)
add word [msg_board_pos], 10
mov ax, word [Screen_Max_Y]
mov ax, word [_display.height]
cmp word [msg_board_pos], ax
jbe @f
jb @f
mov word [msg_board_pos], 10
@@:
; // end if
5012,14 → 5166,14
 
 
.1: ; resolution
mov eax, [Screen_Max_X]
mov eax, [_display.width]
shl eax, 16
mov ax, word [Screen_Max_Y]
mov ax, word [_display.height]
add eax, 0x00010001
mov [esp+32], eax
ret
.2: ; bits per pixel
mov eax, [_display.bits_per_pixel]
mov eax, [_display.bpp]
mov [esp+32], eax
ret
.3: ; bytes per scanline
5100,66 → 5254,43
 
align 4
syscall_getscreensize: ; GetScreenSize
mov ax, word [Screen_Max_X]
mov ax, word [_display.width]
shl eax, 16
mov ax, word [Screen_Max_Y]
mov ax, word [_display.height]
mov [esp + 32], eax
ret
;-----------------------------------------------------------------------------
 
align 4
syscall_cdaudio:
; ECX - position of CD/DVD-drive
; from 0=Primary Master to 3=Secondary Slave for first IDE contr.
; from 4=Primary Master to 7=Secondary Slave for second IDE contr.
; from 8=Primary Master to 11=Secondary Slave for third IDE contr.
cmp ecx, 11
ja .exit
 
mov eax, ecx
shr eax, 2
lea eax, [eax*5]
mov al, [eax+DRIVE_DATA+1]
syscall_cdaudio: ; CD
 
push ecx ebx
mov ebx, ecx
and ebx, 11b
shl ebx, 1
mov cl, 6
sub cl, bl
shr al, cl
test al, 2 ; it's not an ATAPI device
pop ebx ecx
 
jz .exit
 
cmp ebx, 4
je .eject
 
jb .audio
jz .eject
cmp ebx, 5
je .load
;--------------------------------------
.exit:
ret
;--------------------------------------
jnz .ret
.load:
call .reserve
call LoadMedium
;call .free
jmp .free
;--------------------------------------
; ret
.eject:
call .reserve
call clear_CD_cache
call allow_medium_removal
call EjectMedium
; call .free
jmp .free
;--------------------------------------
; ret
.audio:
call sys_cd_audio
mov [esp+36-4], eax
.ret:
ret
 
.reserve:
call reserve_cd
 
mov ebx, ecx
inc ebx
mov [cdpos], ebx
 
mov eax, ecx
shr eax, 1
and eax, 1
5169,19 → 5300,32
and eax, 1
mov [DiskNumber], al
call reserve_cd_channel
and ebx, 3
inc ebx
mov [cdpos], ebx
add ebx, ebx
mov cl, 8
sub cl, bl
mov al, [DRIVE_DATA+1]
shr al, cl
test al, 2
jz .free;.err
ret
;--------------------------------------
.free:
call free_cd_channel
and [cd_status], 0
ret
.err:
call .free
; pop eax
ret
;-----------------------------------------------------------------------------
align 4
syscall_getpixel_WinMap: ; GetPixel WinMap
cmp ebx, [Screen_Max_X]
jbe @f
cmp ecx, [Screen_Max_Y]
jbe @f
cmp ebx, [_display.width]
jb @f
cmp ecx, [_display.height]
jb @f
xor eax, eax
jmp .store
;--------------------------------------
5198,8 → 5342,7
;-----------------------------------------------------------------------------
align 4
syscall_getpixel: ; GetPixel
mov ecx, [Screen_Max_X]
inc ecx
mov ecx, [_display.width]
xor edx, edx
mov eax, ebx
div ecx
5444,8 → 5587,6
pushfd
cli
 
mov [Screen_Max_X], eax
mov [Screen_Max_Y], edx
mov [_display.pitch], ecx
 
mov [screen_workarea.right], eax
5487,8 → 5628,8
call repos_windows
xor eax, eax
xor ebx, ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
mov ecx, [_display.width]
mov edx, [_display.height]
call calculatescreen
pop edi
pop esi
5572,41 → 5713,10
ret
@@:
call stop_all_services
movi eax, 3
call sys_cd_audio
 
yes_shutdown_param:
; Shutdown other CPUs, if initialized
cmp [ap_initialized], 0
jz .no_shutdown_cpus
mov edi, [LAPIC_BASE]
add edi, 300h
mov esi, smpt+4
mov ebx, [cpu_count]
dec ebx
.shutdown_cpus_loop:
lodsd
push esi
xor esi, esi
inc esi
shl eax, 24
mov [edi+10h], eax
; assert INIT IPI
mov dword [edi], 0C500h
call delay_ms
@@:
test dword [edi], 1000h
jnz @b
; deassert INIT IPI
mov dword [edi], 8500h
call delay_ms
@@:
test dword [edi], 1000h
jnz @b
; don't send STARTUP IPI: let other CPUs be in wait-for-startup state
pop esi
dec ebx
jnz .shutdown_cpus_loop
.no_shutdown_cpus:
 
cli
 
if ~ defined extended_primary_loader
5630,6 → 5740,22
 
call IRQ_mask_all
 
if 0
mov word [OS_BASE+0x467+0], pr_mode_exit
mov word [OS_BASE+0x467+2], 0x1000
 
mov al, 0x0F
out 0x70, al
mov al, 0x05
out 0x71, al
 
mov al, 0xFE
out 0x64, al
 
hlt
jmp $-1
 
else
cmp byte [OS_BASE + 0x9030], 2
jnz no_acpi_power_off
 
5775,6 → 5901,21
jmp $
 
 
no_acpi_power_off:
mov word [OS_BASE+0x467+0], pr_mode_exit
mov word [OS_BASE+0x467+2], 0x1000
 
mov al, 0x0F
out 0x70, al
mov al, 0x05
out 0x71, al
 
mov al, 0xFE
out 0x64, al
 
hlt
jmp $-1
 
scan_rsdp:
add eax, OS_BASE
.s:
5797,34 → 5938,8
stc
.ok:
ret
end if
 
no_acpi_power_off:
call create_trampoline_pgmap
mov cr3, eax
jmp become_real+0x10000
iglobal
align 4
realmode_gdt:
; selector 0 - not used
dw 23
dd realmode_gdt-OS_BASE
dw 0
; selector 8 - code from 1000:0000 to 1000:FFFF
dw 0FFFFh
dw 0
db 1
db 10011011b
db 00000000b
db 0
; selector 10h - data from 1000:0000 to 1000:FFFF
dw 0FFFFh
dw 0
db 1
db 10010011b
db 00000000b
db 0
endg
 
if ~ lang eq sp
diff16 "end of .text segment",0,$
end if
/kernel/branches/Kolibri-acpi/kernel32.inc
98,35 → 98,17
dr7 dd ?
ends
 
struct PROC
list LHEAD
thr_list LHEAD
heap_lock MUTEX
heap_base rd 1
heap_top rd 1
mem_used rd 1
dlls_list_ptr rd 1
pdt_0_phys rd 1
pdt_1_phys rd 1
io_map_0 rd 1
io_map_1 rd 1
 
ht_lock rd 1
ht_next rd 1
htab rd (4096-$)/4
pdt_0 rd 1024
ends
 
struct APPDATA
app_name rb 11
rb 5
 
list LHEAD ;+16
process dd ? ;+24
fpu_state dd ? ;+28
exc_handler dd ? ;+32
except_mask dd ? ;+36
pl0_stack dd ? ;+40
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
142,7 → 124,7
wait_test dd ? ;+96 +++
wait_param dd ? ;+100 +++
tls_base dd ? ;+104
dd ? ;+108
dlls_list_ptr dd ? ;+108
event_filter dd ? ;+112
draw_bgr_x dd ? ;+116
draw_bgr_y dd ? ;+120
151,7 → 133,7
wnd_shape dd ? ;+128
wnd_shape_scale dd ? ;+132
dd ? ;+136
dd ? ;+140
mem_size dd ? ;+140
saved_box BOX ;+144
ipc_start dd ? ;+160
ipc_size dd ? ;+164
160,7 → 142,7
terminate_protection dd ? ;+176
keyboard_mode db ? ;+180
rb 3
dd ? ;+184
dir_table dd ? ;+184
dbg_event_mem dd ? ;+188
dbg_regs DBG_REGS ;+192
wnd_caption dd ? ;+212
170,37 → 152,7
 
ends
 
struct IDE_DATA
ProgrammingInterface dd ?
Interrupt dw ?
RegsBaseAddres dw ?
BAR0_val dw ?
BAR1_val dw ?
BAR2_val dw ?
BAR3_val dw ?
dma_hdd_channel_1 db ?
dma_hdd_channel_2 db ?
ends
 
struct IDE_CACHE
pointer dd ?
size dd ? ; not use
data_pointer dd ?
system_data_size dd ? ; not use
appl_data_size dd ? ; not use
system_data dd ?
appl_data dd ?
system_sad_size dd ?
appl_sad_size dd ?
search_start dd ?
appl_search_start dd ?
ends
 
struct IDE_DEVICE
UDMA_possible_modes db ?
UDMA_set_mode db ?
ends
 
; Core functions
include "core/sync.inc" ; macros for synhronization objects
include "core/sys32.inc" ; process management
208,7 → 160,6
include "core/syscall.inc" ; system call
include "core/fpu.inc" ; all fpu/sse support
include "core/memory.inc"
include "core/mtrr.inc"
include "core/heap.inc" ; kernel and app heap
include "core/malloc.inc" ; small kernel heap
include "core/taskman.inc"
291,6 → 242,7
 
; CD drive controller
 
include "blkdev/cdrom.inc"
include "blkdev/cd_drv.inc"
 
; Character devices
/kernel/branches/Kolibri-acpi/network/IPv4.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; IPv4.INC ;;
267,9 → 267,10
cmp eax, 224
je .ip_ok
 
; maybe we just dont have an IP yet and should accept everything on the IP level
; or a loopback address (127.0.0.0/8)
 
cmp [IP_LIST + edi], 0
and eax, 0x00ffffff
cmp eax, 127
je .ip_ok
 
; or it's just not meant for us.. :(
576,11 → 577,11
; edx = Source IP
; di = TTL shl 8 + protocol
;
; OUT: eax = pointer to buffer start / 0 on error
; ebx = device ptr (send packet through this device)
; ecx = data length
; edx = size of complete frame
; edi = start of IPv4 payload
; OUT: eax = pointer to buffer start
; ebx = pointer to device struct (needed for sending procedure)
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer
; edi = pointer to start of data (0 on error)
;
;------------------------------------------------------------------
align 4
594,6 → 595,7
push ecx di eax
call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
push edx
 
test edi, edi
jz .loopback
 
605,11 → 607,12
 
inc [IPv4_packets_tx + edi] ; update stats
 
mov ax, ETHER_PROTO_IPv4
mov ebx, [NET_DRV_LIST + edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6 + 8 + 2]
add ecx, sizeof.IPv4_header
mov edx, esp
mov di, ETHER_PROTO_IPv4
call ETH_output
jz .eth_error
add esp, 6 ; pop the mac out of the stack
639,18 → 642,18
.eth_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ethernet error\n"
add esp, 3*4+2+6
xor eax, eax
xor edi, edi
ret
 
.arp_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
add esp, 3*4+2
xor eax, eax
xor edi, edi
ret
 
.too_large:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: Packet too large!\n"
xor eax, eax
xor edi, edi
ret
 
.loopback:
672,7 → 675,7
; ecx = data length
; esi = data ptr
;
; OUT: eax = -1 on error
; OUT: /
;
;------------------------------------------------------------------
align 4
696,13 → 699,15
push ax
 
inc [IPv4_packets_tx + 4*edi]
mov ax, ETHER_PROTO_IPv4
mov ebx, [NET_DRV_LIST + 4*edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6 + 4]
add ecx, sizeof.IPv4_header
mov edx, esp
mov di, ETHER_PROTO_IPv4
call ETH_output
jz .error
 
add esp, 6 ; pop the mac
 
mov dword[esp+4+4], edx
741,7 → 746,7
add esp, 8+4+4
.too_large:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n"
or eax, -1
sub edi, edi
ret
 
 
790,9 → 795,13
.new_fragment:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
 
mov ax, ETHER_PROTO_IPv4
 
mov eax, [esp + 3*4]
lea ebx, [esp + 4*4]
mov di , ETHER_PROTO_IPv4
call ETH_output
 
cmp edi, -1
jz .err
 
; copy header
/kernel/branches/Kolibri-acpi/network/icmp.inc
294,12 → 294,12
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: no socket found\n"
jmp .dump
 
 
.checksum_mismatch:
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n"
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
/kernel/branches/Kolibri-acpi/network/socket.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;;
293,7 → 293,6
push ecx edx esi
call SOCKET_alloc
pop esi edx ecx
test eax, eax
jz .nobuffs
 
mov [esp+32], edi ; return socketnumber
698,7 → 697,7
 
test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state?
jz @f
call SOCKET_notify ; Unblock it.
call SOCKET_notify.unblock ; Unblock it.
@@:
 
cmp [eax + SOCKET.Domain], AF_INET4
1193,7 → 1192,6
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n"
 
call SOCKET_alloc
test eax, eax
jz .nomem1
mov [esp+32], edi ; application's eax
 
1206,7 → 1204,6
mov ebx, eax
 
call SOCKET_alloc
test eax, eax
jz .nomem2
mov [esp+20], edi ; application's ebx
 
1223,13 → 1220,10
 
lea eax, [eax + STREAM_SOCKET.rcv]
call SOCKET_ring_create
test eax, eax
jz .nomem1
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
test eax, eax
jz .nomem2
pop eax
 
ret
 
1471,8 → 1465,7
 
;--------------------------
;
; IN: eax = ptr to ring struct (just a buffer of the right size)
; OUT: eax = unchanged / 0 on error
; eax = ptr to ring struct (just a buffer of the right size)
;
align 4
SOCKET_ring_create:
1483,8 → 1476,6
push edx
stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
pop edx
test eax, eax
jz .fail
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax
 
1502,7 → 1493,6
mov eax, esi
pop esi
 
.fail:
ret
 
;-----------------------------------------------------------------
1546,7 → 1536,6
jb @f
sub edi, SOCKET_MAXDATA ; WRAP
@@:
 
mov [eax + RING_BUFFER.write_ptr], edi
pop edi
 
1718,9 → 1707,8
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
 
pushf
push eax
 
pushf
cli
 
; Set the 'socket is blocked' flag
1736,12 → 1724,12
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx
mov [eax + SOCKET.TID], edx
pop edx
popf
 
call change_task
pop eax
popf
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continuing\n"
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n"
 
ret
 
1764,54 → 1752,70
call SOCKET_check
jz .error
 
; Find the associated thread's TASK_DATA
push ebx ecx esi
mov ebx, [eax + SOCKET.TID]
test ebx, ebx
jz .error2
test [eax + SOCKET.state], SS_BLOCKED
jnz .unblock
 
; test [eax + SOCKET.options], SO_NONBLOCK
; jz .error
 
push eax ecx esi
 
; socket exists and is of non blocking type.
; We'll try to flag an event to the thread
 
mov eax, [eax + SOCKET.TID]
test eax, eax
jz .done
mov ecx, 1
mov esi, TASK_DATA + TASKDATA.pid
 
.next_pid:
cmp [esi], eax
je .found_pid
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
; PID not found, TODO: close socket!
jmp .done
 
.found_pid:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax
jmp .done
 
.unblock:
push eax ecx esi
; Clear the 'socket is blocked' flag
and [eax + SOCKET.state], not SS_BLOCKED
 
; Find the thread's TASK_DATA
mov eax, [eax + SOCKET.TID]
test eax, eax
jz .error
xor ecx, ecx
inc ecx
mov esi, TASK_DATA
.next:
cmp [esi + TASKDATA.pid], ebx
cmp [esi + TASKDATA.pid], eax
je .found
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next
 
.error2:
; PID not found, TODO: close socket!
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: error finding thread 0x%x !\n", ebx
pop esi ecx ebx
ret
 
.error:
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: invalid socket ptr: 0x%x !\n", eax
ret
 
jmp .error
.found:
test [eax + SOCKET.state], SS_BLOCKED
jnz .un_block
 
; socket and thread exists and socket is of non blocking type.
; We'll try to flag an event to the thread.
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
; Run the thread
mov [esi + TASKDATA.state], 0 ; Running
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n"
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax
pop esi ecx ebx
ret
.done:
pop esi ecx eax
 
 
.un_block:
; socket and thread exists and socket is of blocking type
; We'll try to unblock it.
and [eax + SOCKET.state], not SS_BLOCKED ; Clear the 'socket is blocked' flag
mov [esi + TASKDATA.state], 0 ; Run the thread
 
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n"
pop esi ecx ebx
.error:
ret
 
 
1826,6 → 1830,7
; IN: /
; OUT: eax = 0 on error, socket ptr otherwise
; edi = socket number
; ZF = cleared on error
;
;--------------------------------------------------------------------
align 4
1912,6 → 1917,7
@@:
 
mov [net_sockets + SOCKET.NextPtr], eax
or eax, eax ; used to clear zero flag
 
pusha
mov ecx, socket_mutex
1962,14 → 1968,8
jnz .no_tcp
 
mov ebx, eax
cmp [ebx + STREAM_SOCKET.rcv.start_ptr], 0
je @f
stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr]
@@:
cmp [ebx + STREAM_SOCKET.snd.start_ptr], 0
je @f
stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
@@:
mov eax, ebx
.no_tcp:
 
2022,7 → 2022,6
push ebx
call SOCKET_alloc
pop ebx
test eax, eax
jz .fail
 
push eax
2102,8 → 2101,7
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: socket %u not found!\n", eax
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: caller = 0x%x\n", [esp]
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: not found\n", eax
ret
 
 
2212,8 → 2210,6
align 4
SOCKET_process_end:
 
ret ; FIXME
 
cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all?
je .quickret ; nope, exit immediately
 
/kernel/branches/Kolibri-acpi/network/stack.inc
110,7 → 110,7
SS_BLOCKED = 0x8000
 
 
SOCKET_MAXDATA = 4096*64 ; must be 4096*(power of 2) where 'power of 2' is at least 8
SOCKET_MAXDATA = 4096*8 ; must be 4096*(power of 2) where 'power of 2' is at least 8
MAX_backlog = 20 ; maximum backlog for stream sockets
 
; Error Codes
313,15 → 313,10
test [net_10ms], 0x3f ; 640ms
jnz .exit
 
TCP_timer_640ms
ARP_decrease_entry_ttls
IPv4_decrease_fragment_ttls
 
xor edx, edx
mov eax, [TCP_timer1_event]
mov ebx, [eax + EVENT.id]
xor esi, esi
call raise_event
 
.exit:
ret
 
/kernel/branches/Kolibri-acpi/network/tcp.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;;
96,7 → 96,6
TCP_BIT_NEEDOUTPUT = 1 shl 0
TCP_BIT_TIMESTAMP = 1 shl 1
TCP_BIT_DROPSOCKET = 1 shl 2
TCP_BIT_FIN_IS_ACKED = 1 shl 3
 
TCP_BIT_SENDALOT = 1 shl 0
 
142,7 → 141,6
TCP_sequence_num dd ?
TCP_queue rd (TCP_QUEUE_SIZE*sizeof.TCP_queue_entry + sizeof.queue)/4
TCP_input_event dd ?
TCP_timer1_event dd ?
endg
 
uglobal
226,17 → 224,9
call new_sys_threads
test eax, eax
jns @f
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP input, error %d\n', eax
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP, error %d\n', eax
@@:
 
movi ebx, 1
mov ecx, TCP_timer_640ms
call new_sys_threads
test eax, eax
jns @f
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP timer, error %d\n', eax
@@:
 
}
 
 
274,8 → 264,6
jz .packets_missed ; 2
dec bl
jz .packets_dumped ; 3
dec bl
jz .packets_queued ; 4
 
.error:
mov eax, -1
296,7 → 284,3
.packets_dumped:
mov eax, [TCP_segments_dumped + eax]
ret
 
.packets_queued:
mov eax, [TCP_queue + queue.size]
ret
/kernel/branches/Kolibri-acpi/network/tcp_input.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;;
7,7 → 7,7
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; Based on the algorithms used in 4.4BSD ;;
;; Based on the code of 4.4BSD ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
14,7 → 14,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5155 $
$Revision: 3407 $
 
;-----------------------------------------------------------------
;
43,7 → 43,11
push ebx ecx esi edi ; mind the order
mov esi, esp
 
pushf
cli
add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail
popf
 
add esp, sizeof.TCP_queue_entry
 
call NET_ptr_to_num4
58,6 → 62,7
ret
 
.fail:
popf
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
 
call NET_ptr_to_num4
531,10 → 536,12
cmp eax, [ebx + TCP_SOCKET.SND_UNA]
jne .not_uni_xfer
 
; - The reassembly list of out-of-order segments for the connection is empty.
cmp [ebx + TCP_SOCKET.seg_next], 0
jne .not_uni_xfer
; - The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp).
 
;;; TODO
 
; jnz .not_uni_xfer
 
; Complete processing of received data
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are receiving %u bytes\n", ecx
838,7 → 845,7
pop word [ebx + TCP_SOCKET.SND_SCALE]
@@:
 
call TCP_reassemble
;;; TODO: call TCP_reassemble
 
mov eax, [edx + TCP_header.SequenceNumber]
dec eax
1092,7 → 1099,8
pop ebx edx ecx
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is acked\n"
or [temp_bits], TCP_BIT_FIN_IS_ACKED
stc
 
jmp .wakeup
 
.finiacked:
1106,15 → 1114,19
pop edx ecx
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is not acked\n"
clc
 
;----------------------------------------
; Wake up process waiting on send buffer
 
.wakeup:
 
pushf ; Keep the flags (Carry flag)
mov eax, ebx
call SOCKET_notify
 
; Update TCPS
 
mov eax, [edx + TCP_header.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax
cmp eax, [ebx + TCP_SOCKET.SND_NXT]
1122,6 → 1134,8
mov [ebx + TCP_SOCKET.SND_NXT], eax
@@:
 
popf
 
; General ACK handling complete
; Now do the state-specific ones
; Carry flag is set when our FIN is acked
1144,8 → 1158,7
 
 
.ack_fw1:
test [temp_bits], TCP_BIT_FIN_IS_ACKED
jz .ack_processed
jnc .ack_processed
 
test [ebx + SOCKET.state], SS_CANTRCVMORE
jnz @f
1158,8 → 1171,7
jmp .ack_processed
 
.ack_c:
test [temp_bits], TCP_BIT_FIN_IS_ACKED
jz .ack_processed
jnc .ack_processed
 
mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
mov eax, ebx
1171,8 → 1183,7
jmp .ack_processed
 
.ack_la:
test [temp_bits], TCP_BIT_FIN_IS_ACKED
jz .ack_processed
jnc .ack_processed
 
push ebx
lea ecx, [ebx + SOCKET.mutex]
1235,13 → 1246,9
 
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create
test eax, eax
jz .drop
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
test eax, eax
jz .drop
 
and [temp_bits], not TCP_BIT_DROPSOCKET
 
1250,7 → 1257,7
call SOCKET_notify
popa
 
jmp .trim
jmp .trim_then_step6
 
;------------
; Active Open
1343,9 → 1350,9
 
mov eax, [ebx + TCP_SOCKET.t_rtt]
test eax, eax
je .trim
je .trim_then_step6
call TCP_xmit_timer
jmp .trim
jmp .trim_then_step6
 
.simultaneous_open:
 
1356,7 → 1363,8
;-------------------------------------
; Common processing for receipt of SYN
 
.trim:
.trim_then_step6:
 
inc [edx + TCP_header.SequenceNumber]
 
; Drop any received data that doesnt fit in the receive window.
1369,12 → 1377,17
;;; TODO: update stats
 
.dont_trim:
 
mov eax, [edx + TCP_header.SequenceNumber]
mov [ebx + TCP_SOCKET.RCV_UP], eax
dec eax
mov [ebx + TCP_SOCKET.SND_WL1], eax
 
;-------
; step 6
 
.ack_processed:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK processed\n"
 
;----------------------------------------------
1579,7 → 1592,7
jnz .need_output
 
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jz .done
jz .dumpit
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n"
 
.need_output:
1586,7 → 1599,7
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n"
call TCP_output
 
.done:
.dumpit:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
 
call NET_packet_free
1606,7 → 1619,7
pop eax edx
 
test [edx + TCP_header.Flags], TH_RST
jnz .done
jnz .dumpit
 
or [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jmp .need_output
1620,7 → 1633,7
pop edx ebx
 
test [edx + TCP_header.Flags], TH_RST
jnz .done
jnz .dumpit
 
;;; if its a multicast/broadcast, also drop
 
1629,7 → 1642,7
 
test [edx + TCP_header.Flags], TH_SYN
jnz .respond_syn
jmp .done
jmp .dumpit
 
;---------
; Respond
1648,10 → 1661,8
pop ebx
jmp .destroy_new_socket
 
;-----------------------------------------
; The connection has no associated socket
.no_socket:
 
.no_socket:
pusha
mov ecx, socket_mutex
call mutex_unlock
1681,8 → 1692,8
call TCP_respond_segment
jmp .drop_no_socket
 
;------------------------------------------------
; Unlock socket mutex and prepare to drop segment
;-----
; Drop
 
.drop:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Dropping segment\n"
1692,9 → 1703,6
call mutex_unlock
popa
 
;--------------------------------------------
; Destroy the newly created socket if needed
 
.destroy_new_socket:
test [temp_bits], TCP_BIT_DROPSOCKET
jz .drop_no_socket
1702,9 → 1710,6
mov eax, ebx
call SOCKET_free
 
;------------------
; Drop the segment
 
.drop_no_socket:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n"
 
/kernel/branches/Kolibri-acpi/network/tcp_subr.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;;
14,7 → 14,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5015 $
$Revision: 3514 $
 
align 4
iglobal
143,7 → 143,7
;
;-------------------------
align 4
TCP_drop: ; FIXME CHECKME TODO
TCP_drop:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_drop: %x\n", eax
 
290,6 → 290,7
mov ecx, sizeof.TCP_header
mov di, IP_PROTO_TCP shl 8 + 128
call IPv4_output
test edi, edi
jz .error
pop esi cx
push edx eax
/kernel/branches/Kolibri-acpi/network/tcp_usreq.inc
14,9 → 14,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
;-------------------------
;
; TCP_usrclose
188,7 → 186,7
mov eax, [esp+4]
mov [eax + SOCKET.errorcode], ETIMEDOUT
and [eax + SOCKET.state], not SS_ISCONNECTING
call SOCKET_notify
call SOCKET_notify.unblock
ret 4
 
.fail:
/kernel/branches/Kolibri-acpi/network/ethernet.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ETHERNET.INC ;;
86,7 → 86,11
push ebx
mov esi, esp
 
pushf
cli
add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
popf
 
add esp, sizeof.ETH_queue_entry
 
xor edx, edx
98,9 → 102,10
ret
 
.fail:
DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
popf
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
 
pop ebx
add esp, sizeof.ETH_queue_entry - 8
call NET_packet_free
add esp, 4
 
145,14 → 150,14
cmp ax, ETHER_PROTO_ARP
je ARP_input
 
; cmp ax, ETHER_PROTO_IPv6
; je IPv6_input
cmp ax, ETHER_PROTO_IPv6
je IPv6_input
 
; cmp ax, ETHER_PROTO_PPP_DISCOVERY
; je PPPoE_discovery_input
cmp ax, ETHER_PROTO_PPP_DISCOVERY
je PPPoE_discovery_input
 
; cmp ax, ETHER_PROTO_PPP_SESSION
; je PPPoE_session_input
cmp ax, ETHER_PROTO_PPP_SESSION
je PPPoE_session_input
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
 
166,16 → 171,17
;
; ETH_output
;
; IN: ax = protocol
; IN: eax = pointer to source mac
; ebx = device ptr
; ecx = payload size
; ecx = packet size
; edx = pointer to destination mac
; di = protocol
;
; OUT: eax = start of ethernet frame / 0 on error
; ebx = device ptr
; ecx = payload size
; edx = ethernet frame size
; edi = start of ethernet payload
; OUT: edi = 0 on error, pointer to buffer otherwise
; eax = buffer start
; ebx = to device structure
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer
;
;-----------------------------------------------------------------
align 4
183,11 → 189,11
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
 
cmp ecx, [ebx + ETH_DEVICE.mtu]
cmp ecx, [ebx + NET_DEVICE.mtu]
ja .exit
 
push ecx
push ax edx
push di eax edx
 
add ecx, sizeof.ETH_header
stdcall kernel_alloc, ecx
198,7 → 204,7
pop esi
movsd
movsw
lea esi, [ebx + ETH_DEVICE.mac]
pop esi
movsd
movsw
pop ax
221,13 → 227,13
 
.out_of_ram:
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
add esp, 4+2+4
xor eax, eax
add esp, 4+4+2+4
sub edi, edi
ret
 
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
xor eax, eax
sub edi, edi
ret
 
 
/kernel/branches/Kolibri-acpi/network/udp.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; UDP.INC ;;
245,8 → 245,6
; ecx = number of bytes to send
; esi = pointer to data
;
; OUT: eax = -1 on error
;
;-----------------------------------------------------------------
 
align 4
/kernel/branches/Kolibri-acpi/network/ARP.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ARP.INC ;;
318,9 → 318,10
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\
[esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
 
mov ax, ETHER_PROTO_ARP
lea eax, [ebx + ETH_DEVICE.mac] ; local device mac
mov edx, ETH_BROADCAST ; broadcast mac
mov ecx, sizeof.ARP_header
mov edx, ETH_BROADCAST ; broadcast mac
mov di, ETHER_PROTO_ARP
call ETH_output
jz .exit
 
/kernel/branches/Kolibri-acpi/network/PPPoE.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2012-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2012-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; PPPoE.INC ;;
14,9 → 14,6
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5015 $
 
 
struct PPPoE_frame
VersionAndType db ?
Code db ?
243,15 → 240,17
;
; PPPoE_output
;
; IN: ax = protocol
; IN:
; ebx = device ptr
; ecx = packet size
;
; OUT: eax = buffer start / 0 on error
; ebx = device ptr
; ecx = packet size
; di = protocol
;
; OUT: edi = 0 on error, pointer to buffer otherwise
; eax = buffer start
; ebx = to device structure
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer
; edi = start of PPP payload
;
;-----------------------------------------------------------------
align 4
259,12 → 258,13
 
DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: size=%u device=%x\n", ecx, ebx
 
pushw ax
pushw di
pushw [PPPoE_SID]
 
mov ax, ETHER_PROTO_PPP_SESSION
lea eax, [ebx + ETH_DEVICE.mac]
lea edx, [PPPoE_MAC]
add ecx, PPPoE_frame.Payload + 2
lea edx, [PPPoE_MAC]
mov di, ETHER_PROTO_PPP_SESSION
call ETH_output
jz .eth_error
 
287,7 → 287,8
 
.eth_error:
add esp, 4
xor eax, eax
xor edi, edi
 
ret
 
 
/kernel/branches/Kolibri-acpi/network/queue.inc
28,6 → 28,7
size dd ? ; number of queued packets in this queue
w_ptr dd ? ; current writing pointer in queue
r_ptr dd ? ; current reading pointer
mutex MUTEX
 
ends
 
46,12 → 47,18
 
local .ok, .no_wrap
 
spin_lock_irqsave
pusha
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
 
cmp [ptr + queue.size], size ; Check if queue isnt full
jb .ok
 
spin_unlock_irqrestore
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr
 
.ok:
69,7 → 76,10
.no_wrap:
mov [ptr + queue.w_ptr], edi
 
spin_unlock_irqrestore
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
 
}
 
79,12 → 89,18
 
local .ok, .no_wrap
 
spin_lock_irqsave
pusha
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
 
cmp [ptr + queue.size], 0 ; any packets queued?
ja .ok
 
spin_unlock_irqrestore
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr
 
.ok:
106,7 → 122,10
 
pop esi
 
spin_unlock_irqrestore
pusha
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
 
}
 
117,4 → 136,6
mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi
 
lea ecx, [ptr + queue.mutex]
call mutex_init
}
/kernel/branches/Kolibri-acpi/network/tcp_timer.inc
14,7 → 14,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5013 $
$Revision: 3143 $
 
timer_flag_retransmission = 1 shl 0
timer_flag_keepalive = 1 shl 1
61,19 → 61,14
}
 
 
align 4
proc TCP_timer_640ms ; TODO: implement timed wait timer!
;----------------------
; 640 ms timer
;----------------------
macro TCP_timer_640ms { ; TODO: implement timed wait timer!
 
xor esi, esi
mov ecx, MANUAL_DESTROY
call create_event
mov [TCP_timer1_event], eax
local .loop
local .exit
 
.wait:
mov eax, [TCP_timer1_event]
mov ebx, [eax + EVENT.id]
call wait_event
 
; Update TCP sequence number
 
add [TCP_sequence_num], 64000
86,7 → 81,7
mov eax, [eax + SOCKET.NextPtr]
.check_only:
or eax, eax
jz .wait
jz .exit
 
cmp [eax + SOCKET.Domain], AF_INET4
jne .loop
162,8 → 157,9
mov [eax + TCP_SOCKET.t_force], 0
 
jmp .loop
.exit:
 
endp
}
 
 
 
/kernel/branches/Kolibri-acpi/video/cursors.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
295,7 → 295,9
; jne .fail
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
jmp .end
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
ret
;--------------------------------------
align 4
.fail:
302,10 → 304,6
mov eax, [def_cursor]
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
align 4
.end:
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
ret
endp
;------------------------------------------------------------------------------
580,40 → 578,6
endp
;------------------------------------------------------------------------------
align 4
proc restore_16 stdcall, x:dword, y:dword
 
push ebx
 
mov ebx, [cur_saved_base]
mov edx, [cur.h]
test edx, edx
jz .ret
 
push esi
push edi
 
mov esi, cur_saved_data
;--------------------------------------
align 4
@@:
mov edi, ebx
add ebx, [_display.pitch]
 
mov ecx, [cur.w]
rep movsw
dec edx
jnz @B
 
pop edi
;--------------------------------------
align 4
.ret:
pop esi
pop ebx
ret
endp
;------------------------------------------------------------------------------
align 4
proc move_cursor_24 stdcall, hcursor:dword, x:dword, y:dword
locals
h dd ?
853,129 → 817,6
endp
;------------------------------------------------------------------------------
align 4
proc move_cursor_16 stdcall, hcursor:dword, x:dword, y:dword
locals
h dd ?
_dx dd ?
_dy dd ?
endl
 
mov esi, [hcursor]
mov ecx, [x]
mov eax, [y]
 
xor edx, edx
sub ecx, [esi+CURSOR.hot_x]
lea ebx, [ecx+32-1]
mov [x], ecx
sets dl
dec edx
and ecx, edx ;clip x to 0<=x
mov [cur.left], ecx
mov edi, ecx
sub edi, [x]
mov [_dx], edi
 
xor edx, edx
sub eax, [esi+CURSOR.hot_y]
lea edi, [eax+32-1]
mov [y], eax
sets dl
dec edx
and eax, edx ;clip y to 0<=y
mov [cur.top], eax
mov edx, eax
sub edx, [y]
mov [_dy], edx
 
; mul dword [BytesPerScanLine]
mov eax, [BPSLine_calc_area+eax*4]
lea edx, [LFB_BASE+eax+ecx*2]
mov [cur_saved_base], edx
 
cmp ebx, [Screen_Max_X]
jbe @F
mov ebx, [Screen_Max_X]
;--------------------------------------
align 4
@@:
cmp edi, [Screen_Max_Y]
jbe @F
mov edi, [Screen_Max_Y]
;--------------------------------------
align 4
@@:
mov [cur.right], ebx
mov [cur.bottom], edi
 
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
sub ebx, [_dx]
sub edi, [_dy]
 
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
 
mov eax, edi
mov edi, cur_saved_data
;--------------------------------------
align 4
@@:
mov esi, edx
add edx, [_display.pitch]
mov ecx, [cur.w]
 
rep movsw
dec eax
jnz @B
 
;draw cursor
mov ebx, [cur_saved_base]
mov eax, [_dy]
shl eax, 5
add eax, [_dx]
 
mov esi, [hcursor]
mov esi, [esi+CURSOR.base]
lea edx, [esi+eax*4]
;--------------------------------------
align 4
.row:
mov ecx, [cur.w]
mov esi, edx
mov edi, ebx
add edx, 32*4
add ebx, [_display.pitch]
;--------------------------------------
align 4
.pix:
lodsd
test eax, 0xFF000000
jz @F
; convert to 16 bpp and store to real LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edi], ax
;--------------------------------------
align 4
@@:
add edi, 2
dec ecx
jnz .pix
 
dec [h]
jnz .row
ret
endp
;------------------------------------------------------------------------------
align 4
check_mouse_area_for_getpixel_new:
; in:
; eax = x
1011,12 → 852,9
add eax, ebx
mov ebx, eax
shl eax, 2
cmp byte [_display.bits_per_pixel], 32
cmp byte [_display.bpp], 32
je @f
sub eax, ebx
cmp byte [_display.bits_per_pixel], 24
je @f
sub eax, ebx
;--------------------------------------
align 4
@@:
1089,9 → 927,7
add ecx, ebx
mov ebx, ecx
shl ecx, 2
cmp byte [_display.bits_per_pixel], 16
je .16
cmp byte [_display.bits_per_pixel], 24
cmp byte [_display.bpp], 24
je .24
and eax, 0xFFFFFF
mov [ecx + cur_saved_data], eax ;store new color to
1098,20 → 934,6
jmp @f
;--------------------------------------
align 4
.16:
sub ecx, ebx
sub ecx, ebx
; convert to 16 bpp and store to real LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [ecx + cur_saved_data], ax ;store new color to
jmp @f
;--------------------------------------
align 4
.24:
sub ecx, ebx
mov [ecx + cur_saved_data], ax ;store new color to
1179,9 → 1001,9
mov ebx, restore_32
mov ecx, move_cursor_32
mov edx, Vesa20_putpixel32_new
mov eax, [_display.bits_per_pixel]
mov eax, [_display.bpp]
cmp al, 32
jne .not_32bpp
jne .24
 
.set:
mov [_display.select_cursor], select_cursor
1200,31 → 1022,13
mov [def_cursor], eax
ret
 
.not_32bpp:
cmp al, 24
jne .not_24bpp
 
.24:
mov ebx, restore_24
mov ecx, move_cursor_24
mov edx, Vesa20_putpixel24_new
jmp .set
cmp al, 24
je .set
 
.not_24bpp:
cmp al, 16
jne .not_16bpp
mov ebx, restore_16
mov ecx, move_cursor_16
mov edx, Vesa20_putpixel16_new
jmp .set
 
.not_16bpp:
; cmp al, 15
; jne .fail
; mov ebx, restore_15
; mov ecx, move_cursor_15
; mov edx, Vesa20_putpixel15_new
; jmp .set
 
.fail:
xor eax, eax
mov [_display.select_cursor], eax
/kernel/branches/Kolibri-acpi/video/vesa20.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; VESA20.INC ;;
19,70 → 19,41
 
$Revision$
 
uglobal
align 4
bgr_cur_line rd 1920 ; maximum width of screen
bgr_next_line rd 1920
endg
 
iglobal
align 4
overlapping_of_points_ptr dd overlapping_of_points
endg
; If you're planning to write your own video driver I suggest
; you replace the VESA12.INC file and see those instructions.
 
 
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
 
; getpixel
;
; in:
; eax = x coordinate
; ebx = y coordinate
;
; ret:
; ecx = 00 RR GG BB
;-----------------------------------------------------------------------------
align 4
Vesa20_getpixel16:
 
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
@@:
 
; check mouse area for putpixel
test ecx, 0x04000000 ; don't load to mouseunder area
jnz .no_mouseunder
call [_display.check_m_pixel]
test ecx, ecx ; 0xff000000
jnz @f
 
.no_mouseunder:
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax*2] ; edi = x*2
add edi, ebx ; edi = x*2+(y*y multiplier)
 
movzx ecx, word[LFB_BASE+edi]
shl ecx, 3
ror ecx, 8
shl cx, 2
ror ecx, 8
shl cl, 3
rol ecx, 16
@@:
and ecx, 0x00ffffff
getpixel:
push eax ebx edx edi
call dword [GETPIXEL]
pop edi edx ebx eax
ret
 
;-----------------------------------------------------------------------------
align 4
Vesa20_getpixel24:
; eax = x
; ebx = y
 
align 4
Vesa20_getpixel24:
 
;--------------------------------------
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
;--------------------------------------
align 4
@@:
 
; check mouse area for putpixel
test ecx, 0x04000000 ; don't load to mouseunder area
jnz .no_mouseunder
89,32 → 60,32
call [_display.check_m_pixel]
test ecx, ecx ; 0xff000000
jnz @f
 
;--------------------------------------
align 4
.no_mouseunder:
;--------------------------------------
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax+eax*2] ; edi = x*3
add edi, ebx ; edi = x*3+(y*y multiplier)
 
mov ecx, [LFB_BASE+edi]
;--------------------------------------
align 4
@@:
and ecx, 0x00ffffff
and ecx, 0xffffff
ret
 
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
 
align 4
Vesa20_getpixel32:
 
;--------------------------------------
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
;--------------------------------------
align 4
@@:
 
; check mouse area for putpixel
test ecx, 0x04000000 ; don't load to mouseunder area
jnz .no_mouseunder
121,28 → 92,20
call [_display.check_m_pixel]
test ecx, ecx ; 0xff000000
jnz @f
 
;--------------------------------------
align 4
.no_mouseunder:
;--------------------------------------
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
 
mov ecx, [LFB_BASE+edi]
;--------------------------------------
align 4
@@:
and ecx, 0x00ffffff
and ecx, 0xffffff
ret
 
;-----------------------------------------------------------------------------
; ebx = pointer
; ecx = size [x|y]
; edx = coordinates [x|y]
; ebp = pointer to 'get' function
; esi = pointer to 'init' function
; edi = parameter for 'get' function
 
align 16
vesa20_putimage:
 
virtual at esp
putimg:
.real_sx dd ?
171,7 → 134,15
.ret_addr dd ?
.arg_0 dd ?
end virtual
 
;-----------------------------------------------------------------------------
align 16
; ebx = pointer
; ecx = size [x|y]
; edx = coordinates [x|y]
; ebp = pointer to 'get' function
; esi = pointer to 'init' function
; edi = parameter for 'get' function
vesa20_putimage:
pushad
sub esp, putimg.stack_data
; save pointer to image
198,32 → 169,43
mov [putimg.abs_cy], ebx
; real_sx = MIN(wnd_sx-image_cx, image_sx);
mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx
inc ebx ; WDATA.box.width is one pixel less than real window x-size
; \begin{diamond}[20.08.2006]
; note that WDATA.box.width is one pixel less than real window x-size
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [putimg.image_cx]
ja @f
add esp, putimg.stack_data
popad
ret
 
;--------------------------------------
align 4
@@:
cmp ebx, [putimg.image_sx]
jbe .end_x
mov ebx, [putimg.image_sx]
;--------------------------------------
align 4
.end_x:
mov [putimg.real_sx], ebx
; init real_sy
mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy
; \begin{diamond}[20.08.2006]
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [putimg.image_cy]
ja @f
add esp, putimg.stack_data
popad
ret
 
;--------------------------------------
align 4
@@:
cmp ebx, [putimg.image_sy]
jbe .end_y
mov ebx, [putimg.image_sy]
;--------------------------------------
align 4
.end_y:
mov [putimg.real_sy], ebx
; line increment
236,13 → 218,13
add eax, [putimg.arg_0]
mov [putimg.line_increment], eax
; winmap new line increment
mov eax, [Screen_Max_X]
inc eax
mov eax, [_display.width]
sub eax, [putimg.real_sx]
mov [putimg.winmap_newline], eax
; screen new line increment
mov eax, [_display.pitch]
mov ebx, [_display.bytes_per_pixel]
mov ebx, [_display.bpp]
shr ebx, 3
imul ecx, ebx
sub eax, ecx
mov [putimg.screen_newline], eax
253,18 → 235,18
; imul edx, [BytesPerScanLine]
mov edx, [BPSLine_calc_area+edx*4]
mov eax, [putimg.abs_cx]
; movzx ebx, byte [ScreenBPP]
; shr ebx, 3
imul eax, ebx
add edx, eax
; pointer to pixel map
mov eax, [putimg.abs_cy]
; imul eax, [Screen_Max_X]
; add eax, [putimg.abs_cy]
mov eax, [d_width_calc_area + eax*4]
 
add eax, [putimg.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
 
;--------------------------------------
mov ecx, [putimg.real_sx]
add ecx, [putimg.abs_cx]
mov [putimg.real_sx_and_abs_cx], ecx
271,221 → 253,15
mov ecx, [putimg.real_sy]
add ecx, [putimg.abs_cy]
mov [putimg.real_sy_and_abs_cy], ecx
 
;--------------------------------------
; get process number
mov ebx, [CURRENT_TASK]
 
cmp byte [_display.bits_per_pixel], 16
je put_image_end_16
cmp byte [_display.bits_per_pixel], 24
je put_image_end_24
cmp byte [_display.bits_per_pixel], 32
cmp byte [_display.bpp], 32
je put_image_end_32
 
;------------------------------------------------------------------------------
 
put_image_end_16:
 
mov edi, [putimg.real_sy]
 
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
je put_image_end_16_new
cmp ecx, 0
je put_image_end_16_old
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [LFB_BASE+edx], ax
.skip:
add edx, 2
inc ebp
dec ecx
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
ret
 
;------------------------------------------------------------------------------
 
align 4
put_image_end_16_old:
 
.new_line:
mov ecx, [putimg.real_sx]
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
 
push ecx
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
shl ecx, 16
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
 
; check mouse area for putpixel
call check_mouse_area_for_putpixel
pop ecx
 
; convert to 16 bpp and store to LFB
;; and eax, 00000000111110001111110011111000b
;; shr ah, 2
;; shr ax, 3
;; ror eax, 8
;; add al, ah
;; rol eax, 8
mov [LFB_BASE+edx], ax
.skip:
inc edx
inc edx
inc ebp
dec ecx
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
jmp put_image_end_16.finish
 
;------------------------------------------------------------------------------
 
align 4
put_image_end_16_new:
 
.new_line:
mov ecx, [putimg.real_sx]
 
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
 
cmp [ebp], bl
jne .skip
 
push ecx
.sh:
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
 
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
shl ecx, 16
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
 
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
cmp ecx, -1 ; SHIT HAPPENS?
jne .no_mouse_area
 
mov ecx, [esp]
jmp .sh
 
.no_mouse_area:
pop ecx
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [LFB_BASE+edx], ax
 
.skip:
add edx, 2
inc ebp
dec ecx
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
 
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
 
@@:
dec edi
jnz .new_line
jmp put_image_end_16.finish
 
;------------------------------------------------------------------------------
 
align 4
;--------------------------------------
put_image_end_24:
 
mov edi, [putimg.real_sy]
 
;--------------------------------------
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
492,8 → 268,12
je put_image_end_24_new
cmp ecx, 0
je put_image_end_24_old
;--------------------------------------
align 4
.new_line:
mov ecx, [putimg.real_sx]
;--------------------------------------
align 4
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
500,12 → 280,13
call eax
cmp [ebp], bl
jne .skip
 
; store to LFB
;--------------------------------------
; store to real LFB
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
 
;--------------------------------------
align 4
.skip:
add edx, 3
inc ebp
513,8 → 294,8
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
add edx, [putimg.screen_newline];[BytesPerScanLine]
add ebp, [putimg.winmap_newline];[Screen_Max_X]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
522,22 → 303,27
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
;--------------------------------------
align 4
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
;--------------------------------------
align 4
@@:
dec edi
jnz .new_line
;--------------------------------------
align 4
.finish:
add esp, putimg.stack_data
popad
ret
 
;------------------------------------------------------------------------------
 
align 4
put_image_end_24_old:
 
;--------------------------------------
align 4
.new_line:
mov ecx, [putimg.real_sx]
;--------------------------------------
548,8 → 334,9
call eax
cmp [ebp], bl
jne .skip
;--------------------------------------
push ecx
 
push ecx
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
shl ecx, 16
559,11 → 346,12
; check mouse area for putpixel
call check_mouse_area_for_putpixel
pop ecx
; store to LFB
; store to real LFB
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
 
;--------------------------------------
align 4
.skip:
add edx, 3
inc ebp
571,8 → 359,8
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
add edx, [putimg.screen_newline];[BytesPerScanLine]
add ebp, [putimg.winmap_newline];[Screen_Max_X]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
580,24 → 368,26
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
 
;--------------------------------------
align 4
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
 
;--------------------------------------
align 4
@@:
dec edi
jnz .new_line
jmp put_image_end_24.finish
 
;------------------------------------------------------------------------------
 
align 4
put_image_end_24_new:
 
;--------------------------------------
align 4
.new_line:
mov ecx, [putimg.real_sx]
 
;--------------------------------------
align 4
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
604,12 → 394,14
call eax
cmp [ebp], bl
jne .skip
 
;--------------------------------------
push ecx
;--------------------------------------
align 4
.sh:
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
 
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
621,7 → 413,7
 
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
 
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
628,7 → 420,7
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
;--------------------------------------
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
cmp ecx, -1 ; SHIT HAPPENS?
636,15 → 428,16
 
mov ecx, [esp]
jmp .sh
 
;--------------------------------------
align 4
.no_mouse_area:
pop ecx
 
; store to LFB
; store to real LFB
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
 
;--------------------------------------
align 4
.skip:
add edx, 3
inc ebp
652,8 → 445,8
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
add edx, [putimg.screen_newline];[BytesPerScanLine]
add ebp, [putimg.winmap_newline];[Screen_Max_X]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
661,23 → 454,22
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
 
;--------------------------------------
align 4
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
 
;--------------------------------------
align 4
@@:
dec edi
jnz .new_line
jmp put_image_end_24.finish
 
;------------------------------------------------------------------------------
 
align 4
put_image_end_32:
 
mov edi, [putimg.real_sy]
 
;--------------------------------------
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
684,10 → 476,12
je put_image_end_32_new
cmp ecx, 0
je put_image_end_32_old
 
;--------------------------------------
align 4
.new_line:
mov ecx, [putimg.real_sx]
 
;--------------------------------------
align 4
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
694,10 → 488,11
call eax
cmp [ebp], bl
jne .skip
 
; store to LFB
;--------------------------------------
; store to real LFB
mov [LFB_BASE+edx], eax
 
;--------------------------------------
align 4
.skip:
add edx, 4
inc ebp
705,8 → 500,8
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
add edx, [putimg.screen_newline];[BytesPerScanLine]
add ebp, [putimg.winmap_newline];[Screen_Max_X]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
714,15 → 509,18
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
 
;--------------------------------------
align 4
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
 
;--------------------------------------
align 4
@@:
dec edi
jnz .new_line
 
;--------------------------------------
align 4
.finish:
add esp, putimg.stack_data
popad
729,17 → 527,20
cmp [SCR_MODE], 0x12
jne @f
call VGA__putimage
;--------------------------------------
align 4
@@:
mov [EGA_counter], 1
ret
 
;------------------------------------------------------------------------------
 
align 4
put_image_end_32_old:
 
;--------------------------------------
align 4
.new_line:
mov ecx, [putimg.real_sx]
;--------------------------------------
align 4
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
746,8 → 547,9
call eax
cmp [ebp], bl
jne .skip
;--------------------------------------
push ecx
 
push ecx
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
shl ecx, 16
757,9 → 559,10
; check mouse area for putpixel
call check_mouse_area_for_putpixel
pop ecx
; store to LFB
; store to real LFB
mov [LFB_BASE+edx], eax
 
;--------------------------------------
align 4
.skip:
add edx, 4
inc ebp
767,8 → 570,8
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
add edx, [putimg.screen_newline];[BytesPerScanLine]
add ebp, [putimg.winmap_newline];[Screen_Max_X]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
776,24 → 579,26
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
 
;--------------------------------------
align 4
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
 
;--------------------------------------
align 4
@@:
dec edi
jnz .new_line
jmp put_image_end_32.finish
 
;------------------------------------------------------------------------------
 
align 4
put_image_end_32_new:
 
;--------------------------------------
align 4
.new_line:
mov ecx, [putimg.real_sx]
 
;--------------------------------------
align 4
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
800,29 → 605,33
call eax
cmp [ebp], bl
jne .skip
 
;--------------------------------------
push ecx
 
;--------------------------------------
align 4
.sh:
neg ecx
add ecx, [putimg.real_sx_and_abs_cx + 4]
 
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
shl ecx, 16
 
add ecx, [putimg.real_sy_and_abs_cy + 4]
sub ecx, edi
 
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
;--------------------------------------
; check mouse area for putpixel
call check_mouse_area_for_putpixel_new.1
cmp ecx, -1 ; SHIT HAPPENS?
830,13 → 639,14
 
mov ecx, [esp]
jmp .sh
 
;--------------------------------------
align 4
.no_mouse_area:
pop ecx
 
; store to LFB
; store to real LFB
mov [LFB_BASE+edx], eax
 
;--------------------------------------
align 4
.skip:
add edx, 4
inc ebp
844,8 → 654,8
jnz .new_x
 
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline]
add ebp, [putimg.winmap_newline]
add edx, [putimg.screen_newline];[BytesPerScanLine]
add ebp, [putimg.winmap_newline];[Screen_Max_X]
 
cmp [putimg.ebp], putimage_get1bpp
jz .correct
853,105 → 663,71
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
 
;--------------------------------------
align 4
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
 
;--------------------------------------
align 4
@@:
dec edi
jnz .new_line
jmp put_image_end_32.finish
;------------------------------------------------------------------------------
align 4
__sys_putpixel:
 
;------------------------------------------------------------------------------
; eax = x coordinate
; ebx = y coordinate
; ecx = xx RR GG BB
; xx flags:
; 0x01000000 color inversion
; 0x02000000 used for draw_rectangle without top line (for drawwindow_III and drawwindow_IV)
; ecx = ?? RR GG BB ; 0x01000000 negation
; 0x02000000 used for draw_rectangle without top line
; for example drawwindow_III and drawwindow_IV
; edi = 0x00000001 force
 
align 4
__sys_putpixel:
 
pushad
cmp [Screen_Max_X], eax
jb .exit
cmp [Screen_Max_Y], ebx
jb .exit
cmp eax, [_display.width]
jae .exit
cmp ebx, [_display.height]
jae .exit
test edi, 1 ; force ?
jnz .forced
 
; not forced
; not forced:
mov edx, [d_width_calc_area + ebx*4]
add edx, [_WinMapAddress]
movzx edx, byte [eax+edx]
cmp edx, [CURRENT_TASK]
jne .exit
 
;--------------------------------------
align 4
.forced:
; check for color inversion
; check if negation
test ecx, 0x01000000
jz .no_inv
jz .noneg
 
push eax ebx edx edi
call [GETPIXEL]
pop edi edx ebx eax
call getpixel
not ecx
 
not ecx
rol ecx, 8
mov cl, [esp+32-8+3]
ror ecx, 8
mov [esp+32-8], ecx
.no_inv:
call [PUTPIXEL] ; call the real put_pixel function
;--------------------------------------
align 4
.noneg:
; OK to set pixel
call dword [PUTPIXEL]; call the real put_pixel function
;--------------------------------------
align 4
.exit:
popad
ret
 
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
 
align 4
Vesa20_putpixel16:
 
mov ecx, eax
shl ecx, 16
mov cx, bx
 
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax*2]; edi = x*2
mov eax, [esp+32-8+4]
 
; check for hardware cursor
cmp [_display.select_cursor], 0
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
call check_mouse_area_for_putpixel
@@:
; store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
 
mov [LFB_BASE+ebx+edi], ax
ret
 
;-----------------------------------------------------------------------------
Vesa20_putpixel24:
; eax = x
; ebx = y
 
align 4
Vesa20_putpixel16_new:
 
mov ecx, eax
shl ecx, 16
mov cx, bx
958,59 → 734,9
 
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax*2]; edi = x*2
mov eax, [esp+32-8+4]
 
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
jne @f
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
 
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
rol ecx, 16
 
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
ror ecx, 16
 
call check_mouse_area_for_putpixel_new.1
@@:
; store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
 
mov [LFB_BASE+ebx+edi], ax
ret
 
;-----------------------------------------------------------------------------
; eax = x
; ebx = y
 
align 4
Vesa20_putpixel24:
 
mov ecx, eax
shl ecx, 16
mov cx, bx
 
; imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax+eax*2]; edi = x*3
mov eax, [esp+32-8+4]
 
;--------------------------------------
; check for hardware cursor
cmp [_display.select_cursor], 0
jne @f
1018,21 → 744,19
test eax, 0x04000000
jnz @f
call check_mouse_area_for_putpixel
;--------------------------------------
align 4
@@:
 
; store to LFB
; store to real LFB
mov [LFB_BASE+ebx+edi], ax
shr eax, 16
mov [LFB_BASE+ebx+edi+2], al
ret
 
;-----------------------------------------------------------------------------
align 4
Vesa20_putpixel24_new:
; eax = x
; ebx = y
 
align 4
Vesa20_putpixel24_new:
 
mov ecx, eax
shl ecx, 16
mov cx, bx
1041,7 → 765,7
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [eax+eax*2]; edi = x*3
mov eax, [esp+32-8+4]
 
;--------------------------------------
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
jne @f
1048,36 → 772,39
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
 
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
 
rol ecx, 16
 
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
 
ror ecx, 16
 
call check_mouse_area_for_putpixel_new.1
;--------------------------------------
align 4
@@:
; store to LFB
; store to real LFB
mov [LFB_BASE+ebx+edi], ax
shr eax, 16
mov [LFB_BASE+ebx+edi+2], al
ret
 
;-----------------------------------------------------------------------------
align 4
Vesa20_putpixel32:
; eax = x
; ebx = y
 
align 4
Vesa20_putpixel32:
 
mov ecx, eax
shl ecx, 16
mov cx, bx
1086,7 → 813,7
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov eax, [esp+32-8+4] ; eax = color
 
;--------------------------------------
; check for hardware cursor
cmp [_display.select_cursor], 0
jne @f
1094,19 → 821,18
test eax, 0x04000000
jnz @f
call check_mouse_area_for_putpixel
;--------------------------------------
align 4
@@:
and eax, 0xffffff
; store to LFB
; store to real LFB
mov [LFB_BASE+edi], eax
ret
 
;-----------------------------------------------------------------------------
align 4
Vesa20_putpixel32_new:
; eax = x
; ebx = y
 
align 4
Vesa20_putpixel32_new:
 
mov ecx, eax
shl ecx, 16
mov cx, bx
1115,7 → 841,7
mov ebx, [BPSLine_calc_area+ebx*4]
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov eax, [esp+32-8+4] ; eax = color
 
;--------------------------------------
; check for hardware cursor
cmp [_display.select_cursor], select_cursor
jne @f
1122,51 → 848,53
; check mouse area for putpixel
test eax, 0x04000000
jnz @f
 
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae @f
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb @f
 
rol ecx, 16
 
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae @f
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb @f
 
ror ecx, 16
 
call check_mouse_area_for_putpixel_new.1
;--------------------------------------
align 4
@@:
and eax, 0x00ffffff
; store to LFB
and eax, 0xffffff
; store to real LFB
mov [LFB_BASE+edi], eax
ret
 
;-----------------------------------------------------------------------------
 
align 4
calculate_edi:
; mov edi, ebx
; imul edi, [Screen_Max_X]
; add edi, ebx
mov edi, [d_width_calc_area + ebx*4]
add edi, eax
ret
 
 
;-----------------------------------------------------------------------------
; DRAWLINE
;-----------------------------------------------------------------------------
; eax = x1 shl 16 + x2
; ebx = y1 shl 16 + y2
align 4
__sys_draw_line:
; draw a line
; eax = HIWORD = x1
; LOWORD = x2
; ebx = HIWORD = y1
; LOWORD = y2
; ecx = color
; edi = force ?
pusha
 
align 4
__sys_draw_line:
 
dl_x1 equ esp+20
dl_y1 equ esp+16
dl_x2 equ esp+12
1174,8 → 902,6
dl_dx equ esp+4
dl_dy equ esp+0
 
pusha
 
xor edx, edx ; clear edx
xor esi, esi ; unpack arguments
xor ebp, ebp
1196,10 → 922,12
call vline
push edx ; necessary to rightly restore stack frame at .exit
jmp .exit
 
;--------------------------------------
align 4
.x2lx1:
neg esi ; get esi absolute value
 
;--------------------------------------
align 4
.no_vline:
; checking y-axis...
sub ebp, ebx ; ebp = y2-y1
1209,10 → 937,12
mov edx, [dl_x2] ; else (if y1=y2)
call hline
jmp .exit
 
;--------------------------------------
align 4
.y2ly1:
neg ebp ; get ebp absolute value
 
;--------------------------------------
align 4
.no_hline:
cmp ebp, esi
jle .x_rules ; |y2-y1| < |x2-x1| ?
1225,23 → 955,29
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
 
;--------------------------------------
align 4
.no_reverse1:
mov eax, [dl_dx]
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
;--------------------------------------
align 4
@@:
;--------------------------------------
mov edx, ebp ; edx = counter (number of pixels to draw)
mov ebp, 1 shl 16 ; ebp = dy = 1.0
mov ebp, 1 *65536; <<16 ; ebp = dy = 1.0
mov esi, eax ; esi = dx
jmp .y_rules
;--------------------------------------
align 4
.x_rules:
cmp [dl_x2], eax ; make sure x1 is at the begining
jge .no_reverse2
1252,6 → 988,8
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
;--------------------------------------
align 4
.no_reverse2:
xor edx, edx
mov eax, [dl_dy]
1258,16 → 996,21
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
;--------------------------------------
align 4
@@:
;--------------------------------------
mov edx, esi ; edx = counter (number of pixels to draw)
mov esi, 1 shl 16 ; esi = dx = 1.0
mov esi, 1 *65536;<< 16 ; esi = dx = 1.0
mov ebp, eax ; ebp = dy
 
;--------------------------------------
align 4
.y_rules:
mov eax, [dl_x1]
mov ebx, [dl_y1]
1275,20 → 1018,29
shl ebx, 16
 
and ecx, 0xFBFFFFFF ; negate 0x04000000 save to mouseunder area
;-----------------------------------------------------------------------------
align 4
.draw:
push eax ebx
 
;--------------------------------------
; correction for the remainder of the division
test ah, 0x80
jz @f
add eax, 1 shl 16
;--------------------------------------
align 4
@@:
;--------------------------------------
shr eax, 16
;--------------------------------------
; correction for the remainder of the division
test bh, 0x80
jz @f
add ebx, 1 shl 16
;--------------------------------------
align 4
@@:
;--------------------------------------
shr ebx, 16
; and ecx, 0xFBFFFFFF ; negate 0x04000000 save to mouseunder area
; call [putpixel]
1304,14 → 1056,16
; and ecx, 0xFBFFFFFF ;n egate 0x04000000 save to mouseunder area
; call [putpixel]
call __sys_putpixel
 
;--------------------------------------
align 4
.exit:
add esp, 6*4
popa
; call [draw_pointer]
ret
 
;------------------------------------------------------------------------------
align 4
hline:
; draw an horizontal line
; eax = x1
; edx = x2
1318,16 → 1072,16
; ebx = y
; ecx = color
; edi = force ?
 
align 4
hline:
 
push eax edx
cmp edx, eax ; make sure x2 is above x1
jge @f
xchg eax, edx
;--------------------------------------
align 4
@@:
and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area
;--------------------------------------
align 4
@@:
; call [putpixel]
call __sys_putpixel
1336,8 → 1090,9
jle @b
pop edx eax
ret
 
;------------------------------------------------------------------------------
align 4
vline:
; draw a vertical line
; eax = x
; ebx = y1
1344,16 → 1099,16
; edx = y2
; ecx = color
; edi = force ?
 
align 4
vline:
 
push ebx edx
cmp edx, ebx ; make sure y2 is above y1
jge @f
xchg ebx, edx
;--------------------------------------
align 4
@@:
and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area
;--------------------------------------
align 4
@@:
; call [putpixel]
call __sys_putpixel
1362,17 → 1117,8
jle @b
pop edx ebx
ret
 
;------------------------------------------------------------------------------
; eax cx
; ebx cy
; ecx xe
; edx ye
; edi color
 
align 4
vesa20_drawbar:
 
virtual at esp
drbar:
.bar_sx dd ?
1390,14 → 1136,21
.real_sy_and_abs_cy dd ?
.stack_data = 4*13
end virtual
 
;--------------------------------------
align 4
; eax cx
; ebx cy
; ecx xe
; edx ye
; edi color
vesa20_drawbar:
pushad
sub esp, drbar.stack_data
mov [drbar.color], edi
sub edx, ebx
jle .exit
jle .exit ;// mike.dld, 2005-01-29
sub ecx, eax
jle .exit
jle .exit ;// mike.dld, 2005-01-29
mov [drbar.bar_sy], edx
mov [drbar.bar_sx], ecx
mov [drbar.bar_cx], eax
1409,24 → 1162,35
mov [drbar.abs_cy], ebx
; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx
inc ebx ; WDATA.box.width is one pixel less than real window x-size
; \begin{diamond}[20.08.2006]
; note that WDATA.box.width is one pixel less than real window x-size
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [drbar.bar_cx]
ja @f
.exit:
;--------------------------------------
align 4
.exit: ;// mike.dld, 2005-01-29
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
;--------------------------------------
align 4
@@:
cmp ebx, [drbar.bar_sx]
jbe .end_x
mov ebx, [drbar.bar_sx]
;--------------------------------------
align 4
.end_x:
mov [drbar.real_sx], ebx
; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy
; \begin{diamond}[20.08.2006]
inc ebx
; \end{diamond}
sub ebx, [drbar.bar_cy]
ja @f
add esp, drbar.stack_data
1434,20 → 1198,24
xor eax, eax
inc eax
ret
;--------------------------------------
align 4
@@:
cmp ebx, [drbar.bar_sy]
jbe .end_y
mov ebx, [drbar.bar_sy]
;--------------------------------------
align 4
.end_y:
mov [drbar.real_sy], ebx
; line_inc_map
mov eax, [Screen_Max_X]
mov eax, [_display.width]
sub eax, [drbar.real_sx]
inc eax
mov [drbar.line_inc_map], eax
; line_inc_scr
mov eax, [drbar.real_sx]
mov ebx, [_display.bytes_per_pixel]
mov ebx, [_display.bpp]
shr ebx, 3
imul eax, ebx
neg eax
add eax, [_display.pitch]
1461,14 → 1229,12
add edx, eax
; pointer to pixel map
mov eax, [drbar.abs_cy]
; imul eax, [Screen_Max_X]
; add eax, [drbar.abs_cy]
mov eax, [d_width_calc_area + eax*4]
 
add eax, [drbar.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
 
;--------------------------------------
mov ebx, [drbar.real_sx]
add ebx, [drbar.abs_cx]
mov [drbar.real_sx_and_abs_cx], ebx
1477,7 → 1243,7
mov [drbar.real_sy_and_abs_cy], ebx
 
add edx, LFB_BASE
 
;--------------------------------------
; get process number
mov ebx, [CURRENT_TASK] ; bl - process num
mov esi, [drbar.real_sy]
1485,15 → 1251,11
rol eax, 8
mov bh, al ; 0x80 drawing gradient bars
ror eax, 8
 
cmp byte [_display.bits_per_pixel], 16
je draw_bar_end_16
cmp byte [_display.bits_per_pixel], 24
je draw_bar_end_24
cmp byte [_display.bits_per_pixel], 32
je draw_bar_end_32
 
cmp byte [_display.bpp], 24
jne draw_bar_end_32
;--------------------------------------
align 4
draw_bar_end_24:
; eax - color high RRGGBB
; bl - process num
; ecx - temp
1500,10 → 1262,7
; edx - pointer to screen
; esi - counter
; edi - counter
 
align 4
draw_bar_end_24:
 
;--------------------------------------
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
1510,16 → 1269,22
je draw_bar_end_24_new
cmp ecx, 0
je draw_bar_end_24_old
;--------------------------------------
align 4
.new_y:
mov edi, [drbar.real_sx]
;--------------------------------------
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
 
; store to LFB
;--------------------------------------
; store to real LFB
mov [edx], ax
shr eax, 16
mov [edx + 2], al
;--------------------------------------
align 4
.skip:
; add pixel
add edx, 3
1535,26 → 1300,31
test al, al
jz @f
dec al
;--------------------------------------
align 4
@@:
dec esi
jnz .new_y
;--------------------------------------
align 4
.end:
add esp, drbar.stack_data
popad
xor eax, eax
ret
 
;------------------------------------------------------------------------------
 
align 4
draw_bar_end_24_old:
 
;--------------------------------------
align 4
.new_y:
mov edi, [drbar.real_sx]
;--------------------------------------
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
 
;--------------------------------------
mov ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
shl ecx, 16
1562,11 → 1332,13
sub ecx, esi
; check mouse area for putpixel
call check_mouse_area_for_putpixel
; store to LFB
; store to real LFB
mov [edx], ax
shr eax, 16
mov [edx + 2], al
mov eax, [drbar.color]
;--------------------------------------
align 4
.skip:
; add pixel
add edx, 3
1582,41 → 1354,48
test al, al
jz @f
dec al
;--------------------------------------
align 4
@@:
dec esi
jnz .new_y
jmp draw_bar_end_24.end
 
;------------------------------------------------------------------------------
 
align 4
draw_bar_end_24_new:
 
;--------------------------------------
align 4
.new_y:
mov edi, [drbar.real_sx]
;--------------------------------------
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
 
;--------------------------------------
mov ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
 
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
 
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
ror ecx, 16
 
;--------------------------------------
; check mouse area for putpixel
push eax
call check_mouse_area_for_putpixel_new.1
1625,25 → 1404,25
mov [edx + 2], al
pop eax
jmp .skip
 
; store to real LFB
;--------------------------------------
align 4
.no_mouse_area:
; store to LFB
mov [edx], ax
ror eax, 16
mov [edx + 2], al
rol eax, 16
;--------------------------------------
align 4
.skip:
 
; add pixel
add edx, 3
inc ebp
dec edi
jnz .new_x
 
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
 
; drawing gradient bars
test bh, 0x80
jz @f
1650,12 → 1429,15
test al, al
jz @f
dec al
;--------------------------------------
align 4
@@:
dec esi
jnz .new_y
jmp draw_bar_end_24.end
 
;------------------------------------------------------------------------------
align 4
draw_bar_end_32:
; eax - color high RRGGBB
; bl - process num
; ecx - temp
1662,9 → 1444,7
; edx - pointer to screen
; esi - counter
; edi - counter
 
draw_bar_end_32:
 
;--------------------------------------
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
1671,28 → 1451,30
je draw_bar_end_32_new
cmp ecx, 0
je draw_bar_end_32_old
 
;--------------------------------------
align 4
.new_y:
mov edi, [drbar.real_sx]
;--------------------------------------
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
 
; store to LFB
;--------------------------------------
; store to real LFB
mov [edx], eax
mov eax, [drbar.color]
;--------------------------------------
align 4
.skip:
 
; add pixel
add edx, 4
inc ebp
dec edi
jnz .new_x
 
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
 
; drawing gradient bars
test bh, 0x80
jz @f
1699,9 → 1481,13
test al, al
jz @f
dec al
;--------------------------------------
align 4
@@:
dec esi
jnz .new_y
;--------------------------------------
align 4
.end:
add esp, drbar.stack_data
popad
1708,19 → 1494,25
cmp [SCR_MODE], 0x12
jne @f
call VGA_draw_bar
;--------------------------------------
align 4
@@:
xor eax, eax
mov [EGA_counter], 1
ret
 
;------------------------------------------------------------------------------
align 4
draw_bar_end_32_old:
 
;--------------------------------------
align 4
.new_y:
mov edi, [drbar.real_sx]
;--------------------------------------
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
 
;--------------------------------------
mov ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
shl ecx, 16
1729,9 → 1521,11
 
; check mouse area for putpixel
call check_mouse_area_for_putpixel
; store to LFB
; store to real LFB
mov [edx], eax
mov eax, [drbar.color]
;--------------------------------------
align 4
.skip:
; add pixel
add edx, 4
1747,41 → 1541,48
test al, al
jz @f
dec al
;--------------------------------------
align 4
@@:
dec esi
jnz .new_y
jmp draw_bar_end_32.end
 
;------------------------------------------------------------------------------
 
align 4
draw_bar_end_32_new:
 
;--------------------------------------
align 4
.new_y:
mov edi, [drbar.real_sx]
;--------------------------------------
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
 
;--------------------------------------
mov ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
 
;--------------------------------------
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
 
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
 
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
 
;--------------------------------------
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
 
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
 
ror ecx, 16
 
;--------------------------------------
; check mouse area for putpixel
push eax
call check_mouse_area_for_putpixel_new.1
1788,22 → 1589,22
mov [edx], eax
pop eax
jmp .skip
; store to real LFB
;--------------------------------------
align 4
.no_mouse_area:
 
; store to LFB
mov [edx], eax
;--------------------------------------
align 4
.skip:
 
; add pixel
add edx, 4
inc ebp
dec edi
jnz .new_x
 
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
 
; drawing gradient bars
test bh, 0x80
jz @f
1810,210 → 1611,20
test al, al
jz @f
dec al
;--------------------------------------
align 4
@@:
dec esi
jnz .new_y
jmp draw_bar_end_32.end
 
;------------------------------------------------------------------------------
; eax - color high RRGGBB
; bl - process num
; ecx - temp
; edx - pointer to screen
; esi - counter
; edi - counter
 
align 4
draw_bar_end_16:
 
; check for hardware cursor
mov ecx, [_display.select_cursor]
cmp ecx, select_cursor
je draw_bar_end_16_new
cmp ecx, 0
je draw_bar_end_16_old
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edx], ax
mov eax, [drbar.color]
.skip:
 
; add pixel
add edx, 2
inc ebp
dec edi
jnz .new_x
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
.end:
add esp, drbar.stack_data
popad
cmp [SCR_MODE], 0x12
jne @f
call VGA_draw_bar
@@:
xor eax, eax
mov [EGA_counter], 1
ret
 
;------------------------------------------------------------------------------
 
align 4
draw_bar_end_16_old:
 
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
 
mov ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
shl ecx, 16
add ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
 
; check mouse area for putpixel
call check_mouse_area_for_putpixel
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edx], ax
mov eax, [drbar.color]
.skip:
 
; add pixel
add edx, 2
inc ebp
dec edi
jnz .new_x
 
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
 
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
jmp draw_bar_end_16.end
 
;------------------------------------------------------------------------------
 
align 4
draw_bar_end_16_new:
 
.new_y:
mov edi, [drbar.real_sx]
.new_x:
cmp byte [ebp], bl
jne .skip
 
mov ecx, [drbar.real_sy_and_abs_cy]
sub ecx, esi
 
; check for Y
cmp cx, [Y_UNDER_sub_CUR_hot_y_add_curh]
jae .no_mouse_area
sub cx, [Y_UNDER_subtraction_CUR_hot_y]
jb .no_mouse_area
rol ecx, 16
add ecx, [drbar.real_sx_and_abs_cx]
sub ecx, edi
 
; check for X
cmp cx, [X_UNDER_sub_CUR_hot_x_add_curh]
jae .no_mouse_area
sub cx, [X_UNDER_subtraction_CUR_hot_x]
jb .no_mouse_area
ror ecx, 16
 
; check mouse area for putpixel
push eax
call check_mouse_area_for_putpixel_new.1
push eax
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edx], ax
pop eax
pop eax
jmp .skip
 
.no_mouse_area:
; convert to 16 bpp and store to LFB
push eax
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edx], ax
pop eax
.skip:
 
; add pixel
add edx, 2
inc ebp
dec edi
jnz .new_x
 
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
 
; drawing gradient bars
test bh, 0x80
jz @f
test al, al
jz @f
dec al
@@:
dec esi
jnz .new_y
jmp draw_bar_end_16.end
 
;------------------------------------------------------------------------------
 
align 4
vesa20_drawbackground_tiled:
 
pushad
; External loop for all y from start to end
mov ebx, [draw_data+32+RECT.top] ; y start
;--------------------------------------
align 4
dp2:
mov ebp, [draw_data+32+RECT.left] ; x start
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
2024,13 → 1635,12
xchg ebp, eax
add ebp, eax
add ebp, eax
cmp byte [_display.bytes_per_pixel], 2
je @f
add ebp, eax
cmp byte [_display.bytes_per_pixel], 3
je @f
cmp byte [_display.bpp], 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp, eax
 
;--------------------------------------
align 4
@@:
add ebp, LFB_BASE
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
2064,11 → 1674,14
; edx = 1
; esi -> bgr memory, edi -> output
; ebp = offset in WinMapAddress
;--------------------------------------
align 4
dp3:
cmp [ebp], dl
jnz .next_pix
jnz nbgp
;--------------------------------------
push eax ecx
 
push eax ecx
mov ecx, eax
shl ecx, 16
add ecx, ebx
2080,37 → 1693,32
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
;--------------------------------------
align 4
@@:
and eax, 0xffffff
; check mouse area for putpixel
call [_display.check_mouse]
;--------------------------------------
align 4
.no_mouseunder:
 
cmp byte [_display.bits_per_pixel], 16
je .16bpp
; store to LFB
; store to real LFB
mov [edi], ax
shr eax, 16
mov [edi+2], al
pop ecx eax
jmp .next_pix
 
.16bpp:
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
mov [edi], ax
pop ecx eax
 
; Advance to next pixel
.next_pix:
;--------------------------------------
align 4
nbgp:
add esi, 3
add edi, [_display.bytes_per_pixel]
 
add edi, 3
;--------------------------------------
align 4
@@:
cmp byte [_display.bpp], 25 ; 24 or 32 bpp?
sbb edi, -1 ; +1 for 32 bpp
; I do not use 'inc eax' because this is slightly slower then 'add eax,1'
add ebp, edx
add eax, edx
cmp eax, [draw_data+32+RECT.right]
2117,7 → 1725,6
ja dp4
sub ecx, edx
jnz dp3
 
; next tile block on x-axis
mov ecx, [BgrDataWidth]
sub esi, ecx
2124,7 → 1731,8
sub esi, ecx
sub esi, ecx
jmp dp3
 
;--------------------------------------
align 4
dp4:
; next scan line
inc ebx
2135,36 → 1743,31
cmp [SCR_MODE], 0x12
jne @f
call VGA_drawbackground
;--------------------------------------
align 4
@@:
ret
 
;------------------------------------------------------------------------------
 
align 4
vesa20_drawbackground_stretch:
 
pushad
; Helper variables
; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
; calculate 2^32*(BgrDataWidth) mod (ScreenWidth)
mov eax, [BgrDataWidth]
dec eax
xor edx, edx
div dword [Screen_Max_X]
div dword [_display.width]
push eax ; high
xor eax, eax
div dword [Screen_Max_X]
div dword [_display.width]
push eax ; low
 
; the same for height
mov eax, [BgrDataHeight]
dec eax
xor edx, edx
div dword [Screen_Max_Y]
div dword [_display.height]
push eax ; high
xor eax, eax
div dword [Screen_Max_Y]
div dword [_display.height]
push eax ; low
 
; External loop for all y from start to end
mov ebx, [draw_data+32+RECT.top] ; y start
mov ebp, [draw_data+32+RECT.left] ; x start
2176,18 → 1779,16
xchg ebp, eax
add ebp, eax
add ebp, eax
cmp byte [_display.bytes_per_pixel], 2
jz @f
add ebp, eax
cmp byte [_display.bytes_per_pixel], 3
cmp byte [_display.bpp], 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp, eax
;--------------------------------------
align 4
@@:
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
call calculate_edi
xchg edi, ebp
 
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
push ebx
push eax
2213,8 → 1814,9
push eax
push edx
push esi
 
; 3) Smooth horizontal
;--------------------------------------
align 4
bgr_resmooth0:
mov ecx, [esp+8]
mov edx, [esp+4]
2222,7 → 1824,8
push edi
mov edi, bgr_cur_line
call smooth_line
 
;--------------------------------------
align 4
bgr_resmooth1:
mov eax, [esp+16+4]
inc eax
2236,14 → 1839,15
add esi, [BgrDataWidth]
mov edi, bgr_next_line
call smooth_line
 
;--------------------------------------
align 4
bgr.no2nd:
pop edi
 
;--------------------------------------
align 4
sdp3:
xor esi, esi
mov ecx, [esp+12]
 
; 4) Loop through redraw rectangle and copy background data
; Registers meaning:
; esi = offset in current line, edi -> output
2256,7 → 1860,8
; precalculated constants:
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
 
;--------------------------------------
align 4
sdp3a:
mov eax, [_WinMapAddress]
cmp [ebp+eax], byte 1
2266,7 → 1871,8
jz .novert
mov ebx, [bgr_next_line+esi]
call [overlapping_of_points_ptr]
 
;--------------------------------------
align 4
.novert:
push ecx
; check for hardware cursor
2274,6 → 1880,8
je @f
cmp [_display.select_cursor], 0
jne .no_mouseunder
;--------------------------------------
align 4
@@:
mov ecx, [esp+20+4] ;x
shl ecx, 16
2280,30 → 1888,19
add ecx, [esp+24+4] ;y
; check mouse area for putpixel
call [_display.check_mouse]
;--------------------------------------
align 4
.no_mouseunder:
 
cmp [_display.bits_per_pixel], 16
jne .not_16bpp
; convert to 16 bpp and store to LFB
and eax, 00000000111110001111110011111000b
shr ah, 2
shr ax, 3
ror eax, 8
add al, ah
rol eax, 8
; store to real LFB
mov [LFB_BASE+edi], ax
pop ecx
jmp snbgp
.not_16bpp:
 
; store to LFB
mov [LFB_BASE+edi], ax
shr eax, 16
mov [LFB_BASE+edi+2], al
pop ecx
 
;--------------------------------------
align 4
snbgp:
add edi, [_display.bytes_per_pixel]
cmp byte [_display.bpp], 25
sbb edi, -4
add ebp, 1
mov eax, [esp+20]
add eax, 1
2311,7 → 1908,8
add esi, 4
cmp eax, [draw_data+32+RECT.right]
jbe sdp3a
 
;--------------------------------------
align 4
sdp4:
; next y
mov ebx, [esp+24]
2319,21 → 1917,18
mov [esp+24], ebx
cmp ebx, [draw_data+32+RECT.bottom]
ja sdpdone
 
; advance edi, ebp to next scan line
sub eax, [draw_data+32+RECT.left]
sub ebp, eax
add ebp, [Screen_Max_X]
add ebp, 1
add ebp, [_display.width]
sub edi, eax
sub edi, eax
cmp byte [_display.bytes_per_pixel], 2
jz @f
sub edi, eax
cmp byte [_display.bytes_per_pixel], 3
cmp byte [_display.bpp], 24
jz @f
sub edi, eax
 
;--------------------------------------
align 4
@@:
add edi, [_display.pitch]
; restore ecx,edx; advance esi to next background line
2356,11 → 1951,11
push edi
mov esi, bgr_next_line
mov edi, bgr_cur_line
mov ecx, [Screen_Max_X]
inc ecx
mov ecx, [_display.width]
rep movsd
jmp bgr_resmooth1
 
;--------------------------------------
align 4
sdpdone:
add esp, 44
popad
2368,12 → 1963,20
cmp [SCR_MODE], 0x12
jne @f
call VGA_drawbackground
;--------------------------------------
align 4
@@:
ret
 
uglobal
;--------------------------------------
 
align 4
bgr_cur_line rd 1920 ; maximum width of screen
bgr_next_line rd 1920
;--------------------------------------
endg
;--------------------------------------
align 4
smooth_line:
mov al, [esi+2]
shl eax, 16
2383,6 → 1986,8
mov ebx, [esi+2]
shr ebx, 8
call [overlapping_of_points_ptr]
;--------------------------------------
align 4
@@:
stosd
mov eax, [esp+20+8]
2397,13 → 2002,13
lea eax, [eax*3]
sub esi, eax
jmp smooth_line
;--------------------------------------
align 4
@@:
mov eax, [draw_data+32+RECT.left]
mov [esp+20+8], eax
ret
 
;------------------------------------------------------------------------------
 
align 16
overlapping_of_points:
if 0
2467,21 → 2072,26
ret
end if
 
 
iglobal
;--------------------------------------
align 4
overlapping_of_points_ptr dd overlapping_of_points
;--------------------------------------
endg
;------------------------------------------------------------------------------
 
align 4
init_background:
 
mov edi, BgrAuxTable
xor edx, edx
 
;--------------------------------------
align 4
.loop2:
mov eax, edx
shl eax, 8
neg eax
mov ecx, 0x200
 
;--------------------------------------
align 4
.loop1:
mov byte [edi], ah
inc edi
2492,14 → 2102,13
test byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
jz @f
mov [overlapping_of_points_ptr], overlapping_of_points_mmx
;--------------------------------------
align 4
@@:
ret
 
;------------------------------------------------------------------------------
 
align 16
overlapping_of_points_mmx:
 
movd mm0, eax
movd mm4, eax
movd mm1, ebx
2516,7 → 2125,5
packuswb mm1, mm2
paddb mm4, mm1
movd eax, mm4
 
ret
 
;------------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/video/blitter.inc
1,13 → 1,10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5164 $
 
 
struct BLITTER_BLOCK
xmin dd ?
ymin dd ?
/kernel/branches/Kolibri-acpi/data32.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
140,20 → 140,24
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
 
msg_unresolved db 'unresolved ',0
;msg_module db 'in module ',0
;if ~ lang eq sp
;msg_version db 'incompatible driver version',13,10,0
;msg_www db 'please visit www.kolibrios.org',13,10,0
;end if
msg_module db 'in module ',0
if ~ lang eq sp
msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0
end if
msg_CR db 13,10,0
 
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
 
szHwMouse db 'ATI2D',0
szPS2MDriver db '/rd/1/drivers/PS2MOUSE.SYS',0
szPS2MDriver db 'PS2MOUSE',0
;szCOM_MDriver db 'COM_MOUSE',0
szVidintel db '/rd/1/drivers/vidintel.sys',0
szVidintel db 'vidintel',0
szUSB db 'USB',0
szAtiHW db '/rd/1/drivers/ati2d.drv',0
 
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0
sz_EXPORTS db '_EXPORTS',0
 
164,10 → 168,8
notifyapp db '@notify',0
if lang eq ru
ud_user_message cp866 'Ошибка: неподдерживаемая инструкция процессора',0
mtrr_user_message cp866 '"Обнаружена проблема с конфигурацией MTRR.\nПроизводительность может быть пониженной" -dW',0
else if ~ lang eq sp
ud_user_message db 'Error: unsupported processor instruction',0
mtrr_user_message db '"There is a problem with MTRR configuration.\nPerformance can be low" -dW',0
end if
 
vmode db '/sys/drivers/VMODE.MDR',0
177,7 → 179,7
dd 0 ; subfunction
dq 0 ; offset in file
dd 0x30000 ; number of bytes to read
dd OS_BASE + 0x71000 ; buffer for data
dd OS_BASE + 0x70000 ; buffer for data
db '/RD/1/KERNEL.MNT',0
 
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
345,8 → 347,6
mem_used_list rd 64*2
mem_hash_cnt rd 64
 
thr_slot_map rd 8
 
cpu_freq rq 1
 
heap_mutex MUTEX
378,14 → 378,12
_WinMapAddress rd 1
_WinMapSize rd 1
 
LFBAddress dd ?
Screen_Max_X dd ?
Screen_Max_Y dd ?
LFBAddress rd 1
 
SCR_MODE rw 2
 
PUTPIXEL dd ?
GETPIXEL dd ?
PUTPIXEL rd 1
GETPIXEL rd 1
 
if VESA_1_2_VIDEO
BANK_SWITCH rd 1 reserved for vesa 1.2
401,7 → 399,7
 
mouseunder rd 16*24
 
MOUSE_PICTURE dd ?
MOUSE_PICTURE rd 1
 
MOUSE_SCROLL_H rw 1
MOUSE_X: rw 1
438,6 → 436,7
proc_mem_pdir rd 1
proc_mem_tab rd 1
 
tmp_task_pdir rd 1
tmp_task_ptab rd 1
 
default_io_map rd 1
444,10 → 443,8
 
LFBSize rd 1
 
current_process rd 1
current_slot rd 1 ; i.e. cureent thread
current_slot rd 1
 
 
; status
hd1_status rd 1 ; 0 - free : other - pid
application_table_owner rd 1 ; 0 - free : other - pid
463,6 → 460,8
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
 
;CPUID information
495,12 → 494,63
 
skin_data rd 1
 
cache_ide0:
cache_ide0_pointer rd 1
cache_ide0_size rd 1 ; not use
cache_ide0_data_pointer rd 1
cache_ide0_system_data_size rd 1 ; not use
cache_ide0_appl_data_size rd 1 ; not use
cache_ide0_system_data rd 1
cache_ide0_appl_data rd 1
cache_ide0_system_sad_size rd 1
cache_ide0_appl_sad_size rd 1
cache_ide0_search_start rd 1
cache_ide0_appl_search_start rd 1
 
cache_ide1:
cache_ide1_pointer rd 1
cache_ide1_size rd 1 ; not use
cache_ide1_data_pointer rd 1
cache_ide1_system_data_size rd 1 ; not use
cache_ide1_appl_data_size rd 1 ; not use
cache_ide1_system_data rd 1
cache_ide1_appl_data rd 1
cache_ide1_system_sad_size rd 1
cache_ide1_appl_sad_size rd 1
cache_ide1_search_start rd 1
cache_ide1_appl_search_start rd 1
 
cache_ide2:
cache_ide2_pointer rd 1
cache_ide2_size rd 1 ; not use
cache_ide2_data_pointer rd 1
cache_ide2_system_data_size rd 1 ; not use
cache_ide2_appl_data_size rd 1 ; not use
cache_ide2_system_data rd 1
cache_ide2_appl_data rd 1
cache_ide2_system_sad_size rd 1
cache_ide2_appl_sad_size rd 1
cache_ide2_search_start rd 1
cache_ide2_appl_search_start rd 1
 
cache_ide3:
cache_ide3_pointer rd 1
cache_ide3_size rd 1 ; not use
cache_ide3_data_pointer rd 1
cache_ide3_system_data_size rd 1 ; not use
cache_ide3_appl_data_size rd 1 ; not use
cache_ide3_system_data rd 1
cache_ide3_appl_data rd 1
cache_ide3_system_sad_size rd 1
cache_ide3_appl_sad_size rd 1
cache_ide3_search_start rd 1
cache_ide3_appl_search_start rd 1
 
debug_step_pointer rd 1
 
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled
 
cpu_phys_addr_width rb 1 ; also known as MAXPHYADDR in Intel manuals
hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache
cd_appl_data rb 1 ; 0 = system cache, 1 - application cache
 
525,21 → 575,16
 
org (OS_BASE+0x0100000)
 
; Currently size of memory allocated for the ramdisk is fixed.
; This should be revisited when/if memory map would become more dynamic.
RAMDISK_CAPACITY = 2880 ; in sectors
RAMDISK: rb 2880*512
rb 2856*4 ; not used
 
RAMDISK: rb RAMDISK_CAPACITY*512
 
_CLEAN_ZONE:
 
BgrAuxTable rb 32768
align 65536
SB16Buffer rb 65536
 
align 4096
_IDE_DMA rb 16*512
BgrAuxTable rb 32768
BUTTON_INFO rb 64*1024
RESERVED_PORTS: rb 64*1024
FLOPPY_BUFF: rb 18*512 ;one track
 
sys_pgmap: rb 1024*1024/8
/kernel/branches/Kolibri-acpi/hid/mousedrv.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24,12 → 24,16
uglobal
;--------------------------------------
align 4
mousecount dd ?
mousedata dd ?
Y_UNDER_sub_CUR_hot_y_add_curh dw ?
Y_UNDER_subtraction_CUR_hot_y dw ?
X_UNDER_sub_CUR_hot_x_add_curh dw ?
X_UNDER_subtraction_CUR_hot_x dw ?
mousecount dd 0x0
mousedata dd 0x0
Y_UNDER_sub_CUR_hot_y_add_curh:
dw 0
Y_UNDER_subtraction_CUR_hot_y:
dw 0
X_UNDER_sub_CUR_hot_x_add_curh:
dw 0
X_UNDER_subtraction_CUR_hot_x:
dw 0
endg
 
iglobal
40,12 → 44,9
dd 3
mouse_timer_ticks dd 0
endg
 
;-----------------------------------------------------------------------------
 
align 4
draw_mouse_under:
 
; return old picture
cmp [_display.restore_cursor], 0
je @F
56,12 → 57,14
stdcall [_display.restore_cursor], eax, ebx
popad
ret
 
;--------------------------------------
align 4
@@:
pushad
xor ecx, ecx
xor edx, edx
 
;--------------------------------------
align 4
mres:
movzx eax, word [X_UNDER]
movzx ebx, word [Y_UNDER]
94,9 → 97,7
jnz mres
popad
ret
 
;-----------------------------------------------------------------------------
 
align 4
save_draw_mouse:
cmp [_display.move_cursor], 0
110,9 → 111,6
push eax
push ebx
 
; mov ecx, [Screen_Max_X]
; inc ecx
; mul ecx
mov eax, [d_width_calc_area + eax*4]
 
add eax, [_WinMapAddress]
176,9 → 174,7
add ebx, edx
push ecx
or ecx, 0x04000000 ; don't load to mouseunder area
push eax ebx edx edi
call [GETPIXEL]
pop edi edx ebx eax
call getpixel
mov [COLOR_TEMP], ecx
pop ecx
mov eax, edx
230,9 → 226,7
add esp, 8
popad
ret
 
;-----------------------------------------------------------------------------
 
align 4
combine_colors:
; in
247,7 → 241,7
push edx
push ecx
xor ecx, ecx
; byte 0
; byte 2
mov eax, 0xff
sub al, [esi+0]
mov ebx, [esp]
301,9 → 295,7
pop ebx
pop eax
ret
 
;-----------------------------------------------------------------------------
 
align 4
check_mouse_area_for_getpixel:
; in:
346,14 → 338,13
or ecx, 0xff000000
pop ebx eax
ret
 
;--------------------------------------
align 4
.no_mouse_area:
xor ecx, ecx
pop ebx eax
ret
 
;-----------------------------------------------------------------------------
 
align 4
check_mouse_area_for_putpixel:
; in:
373,7 → 364,7
sub cx, [Y_UNDER] ; [MOUSE_Y]
mov ax, cx
shl eax, 16
 
;--------------------------------------
; check for X
mov ax, [X_UNDER] ; [MOUSE_X]
shr ecx, 16
385,7 → 376,7
; offset X
sub cx, [X_UNDER] ; [MOUSE_X]
mov ax, cx
 
;--------------------------------------
; eax = (offset y) shl 16 + (offset x)
 
pop ecx
417,15 → 408,17
add esi, 16*24*3
call combine_colors
pop edi esi
;--------------------------------------
align 4
.end:
mov eax, ecx
ret
 
;--------------------------------------
align 4
.no_mouse_area:
pop eax
ret
 
;-----------------------------------------------------------------------------
 
align 4
__sys_draw_pointer:
pushad
437,14 → 430,14
je @f
mov [redrawmouse_unconditional], 0
jmp redrawmouse
;--------------------------------------
align 4
@@:
cmp eax, ecx
jne redrawmouse
cmp ebx, edx
je nodmp
 
;--------------------------------------
 
align 4
redrawmouse:
pushfd
472,62 → 465,62
mov [X_UNDER_subtraction_CUR_hot_x], ax
add eax, [cur.w]
mov [X_UNDER_sub_CUR_hot_x_add_curh], ax
;--------------------------------------
align 4
@@:
popfd
;--------------------------------------
align 4
nodmp:
popad
ret
 
;-----------------------------------------------------------------------------
 
align 4
proc set_mouse_data stdcall uses edx, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword
 
mov eax, [BtnState]
and eax, 0x3FFFFFFF ; Top 2 bits are used to flag absolute movements
mov [BTN_DOWN], eax
;--------------------------------------
 
mov eax, [XMoving]
test [BtnState], 0x80000000
jnz .absolute_x
call mouse_acceleration
add ax, [MOUSE_X]
add ax, [MOUSE_X];[XCoordinate]
cmp ax, 0
jge .check_x
jge @@M1
mov eax, 0
jmp .set_x
.absolute_x:
mov edx, [_display.width]
mul edx
shr eax, 15
.check_x:
cmp ax, word[Screen_Max_X]
jl .set_x
mov ax, word[Screen_Max_X]
.set_x:
mov [MOUSE_X], ax
jmp @@M2
;--------------------------------------
align 4
@@M1:
cmp ax, word [_display.width]
jl @@M2
mov ax, word [_display.width]
dec ax
;--------------------------------------
align 4
@@M2:
mov [MOUSE_X], ax;[XCoordinate]
 
mov eax, [YMoving]
test [BtnState], 0x40000000
jnz .absolute_y
neg eax
call mouse_acceleration
add ax, [MOUSE_Y]
 
add ax, [MOUSE_Y];[YCoordinate]
cmp ax, 0
jge .check_y
jge @@M3
mov ax, 0
jmp .set_y
.absolute_y:
mov edx, [_display.height]
mul edx
shr eax, 15
.check_y:
cmp ax, word[Screen_Max_Y]
jl .set_y
mov ax, word[Screen_Max_Y]
.set_y:
mov [MOUSE_Y], ax
jmp @@M4
;--------------------------------------
align 4
@@M3:
cmp ax, word [_display.height]
jl @@M4
mov ax, word [_display.height]
dec ax
;--------------------------------------
align 4
@@M4:
mov [MOUSE_Y], ax;[YCoordinate]
 
mov eax, [VScroll]
add [MOUSE_SCROLL_V], ax
 
540,9 → 533,7
call wakeup_osloop
ret
endp
 
;-----------------------------------------------------------------------------
 
align 4
mouse_acceleration:
push eax
554,5 → 545,8
;push edx
imul eax, [mouse_speed_factor]
;pop edx
;--------------------------------------
align 4
@@:
ret
;-----------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/hid/keyboard.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. 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 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25,6 → 25,8
VKEY_ALT = 0000000000110000b
 
uglobal
align 4
kb_state dd 0
ext_code db 0
 
keyboard_mode db 0
33,6 → 35,7
altmouseb db 0
ctrl_alt_del db 0
 
kb_lights db 0
old_kb_lights db 0
 
align 4
42,13 → 45,6
endg
 
iglobal
kb_lights db 2
align 4
kb_state dd VKEY_NUMLOCK
endg
 
iglobal
align 4
hotkey_tests dd hotkey_test0
dd hotkey_test1
dd hotkey_test2
461,40 → 457,19
test bl, bl
jz .exit.irq1
 
cmp cl, 0xE0 ; extended keycode
jne @f
test [kb_state], VKEY_NUMLOCK
jz .dowrite
 
cmp ch, 53
jne .dowrite
cmp cl, 0xE0
jz .dowrite
mov bl, '/'
jmp .dowrite
@@:
cmp ch, 55
jne @f
jnz @f
mov bl, '*'
mov bl, 0x2A ;*
jmp .dowrite
;--------------------------------------
@@:
 
cmp ch, 74
jne @f
mov bl, '-'
jmp .dowrite
@@:
 
cmp ch, 78
jne @f
mov bl, '+'
jmp .dowrite
@@:
 
test [kb_state], VKEY_NUMLOCK
jz .dowrite
 
cmp ch, 71
jb .dowrite
513,19 → 488,7
jae .exit.irq1
inc eax
mov [KEY_COUNT], al
; store ascii or scancode
mov [KEY_COUNT+eax], bl ; actually KEY_BUFF + EAX - 1
; store original scancode
add eax, 120+2
push ecx
cmp [keyboard_mode], 0; return from keymap
je @f
 
xor ch, ch
@@:
mov [KEY_COUNT+eax], ch ; actually KEY_BUFF + EAX - 1
pop ecx
sub eax, 120+2
mov [KEY_COUNT+eax], bl
.exit.irq1:
ret
;---------------------------------------------------------------------
555,9 → 518,9
ps2_set_lights:
stdcall disable_irq, 1
mov al, 0xED
call kb_write_wait_ack
call kb_write
mov al, [esp+8]
call kb_write_wait_ack
call kb_write
stdcall enable_irq, 1
ret 8
 
/kernel/branches/Kolibri-acpi/data32et.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
boot_initirq latin1 'Algväärtustan IRQ',0
boot_picinit latin1 'Algväärtustan PIC',0
boot_v86machine latin1 'Algväärtustan süsteemi V86 masinat',0
/kernel/branches/Kolibri-acpi/data32sp.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5088 $
 
 
boot_initirq: cp850 'Inicializar IRQ',0
boot_picinit: cp850 'Inicializar PIC',0
boot_v86machine: cp850 'Inicializar sistema V86',0
47,8 → 37,7
boot_tasking: cp850 'Todo configurado - presiona ESC para iniciar',0
end if
 
;msg_version: cp850 'versión incompatible del controlador',13,10,0
;msg_www: cp850 'por favor, visita www.kolibrios.org',13,10,0
msg_version: cp850 'versión incompatible del controlador',13,10,0
msg_www: cp850 'por favor, visita www.kolibrios.org',13,10,0
 
ud_user_message:cp850 'Error: instrucción no soportada por el procesador',0
mtrr_user_message cp850 '"There is a problem with MTRR configuration.\nPerformance can be low" -dW',0
/kernel/branches/Kolibri-acpi/fs/fat.inc
154,9 → 154,6
xor eax, eax
ret
fat_create_partition:
; sector size must be 512
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .return0
; bootsector must have been successfully read
cmp dword [esp+4], 0
jnz .return0
/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc
43,30 → 43,6
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
db 3,'cd4'
dd fs_OnCd4
dd fs_NextCd
db 3,'cd5'
dd fs_OnCd5
dd fs_NextCd
db 3,'cd6'
dd fs_OnCd6
dd fs_NextCd
db 3,'cd7'
dd fs_OnCd7
dd fs_NextCd
db 3,'cd8'
dd fs_OnCd8
dd fs_NextCd
db 3,'cd9'
dd fs_OnCd9
dd fs_NextCd
db 4,'cd10'
dd fs_OnCd10
dd fs_NextCd
db 4,'cd11'
dd fs_OnCd11
dd fs_NextCd
;***********************************************
db 0
 
81,22 → 57,6
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
dd fs_HasCd4
db 'cd4',0
dd fs_HasCd5
db 'cd5',0
dd fs_HasCd6
db 'cd6',0
dd fs_HasCd7
db 'cd7',0
dd fs_HasCd8
db 'cd8',0
dd fs_HasCd9
db 'cd9',0
dd fs_HasCd10
db 'cd10',0
dd fs_HasCd11
db 'cd11',0
;**********************************************
dd 0
endg
189,8 → 149,8
cmp dword [ebx], 1
jnz .access_denied
xor eax, eax
mov ebp, [ebx+12] ;the number of blocks to read
mov edx, [ebx+16] ;where to write the result
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
444,7 → 404,8
fs_NotImplemented:
mov eax, 2
ret
;-----------------------------------------------------------------------------
 
;*******************************************************
fs_OnCd0:
call reserve_cd
mov [ChannelNumber], 1
452,7 → 413,6
push 6
push 1
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd1:
call reserve_cd
mov [ChannelNumber], 1
460,7 → 420,6
push 4
push 2
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd2:
call reserve_cd
mov [ChannelNumber], 2
468,7 → 427,6
push 2
push 3
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd3:
call reserve_cd
mov [ChannelNumber], 2
475,89 → 433,16
mov [DiskNumber], 1
push 0
push 4
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd4:
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 0
push 6
push 5
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd5:
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 1
push 4
push 6
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd6:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 0
push 2
push 7
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd7:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 1
push 0
push 8
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd8:
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 0
push 6
push 9
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd9:
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 1
push 4
push 10
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd10:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 0
push 2
push 11
jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd11:
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 1
push 0
push 12
;-----------------------------------------------------------------------------
fs_OnCd:
call reserve_cd_channel
pop eax
mov [cdpos], eax
call reserve_cd_channel
pop eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl, al
 
push eax
mov eax, [cdpos]
dec eax
shr eax, 2
lea eax, [eax*5]
mov bl, [eax+DRIVE_DATA+1]
pop eax
 
mov bl, [DRIVE_DATA+1]
shr bl, cl
test bl, 2
pop ebx ecx
587,7 → 472,7
and [cd_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
;-----------------------------------------------------------------------------
 
fs_CdServices:
dd fs_CdRead
dd fs_CdReadFolder
600,74 → 485,32
dd fs_NotImplemented
dd fs_NotImplemented
fs_NumCdServices = ($ - fs_CdServices)/4
;-----------------------------------------------------------------------------
 
;*******************************************************
fs_HasCd0:
test byte [DRIVE_DATA+1], 10000000b
setnz al
ret
;--------------------------------------
fs_HasCd1:
test byte [DRIVE_DATA+1], 00100000b
setnz al
ret
;--------------------------------------
fs_HasCd2:
test byte [DRIVE_DATA+1], 00001000b
setnz al
ret
;--------------------------------------
fs_HasCd3:
test byte [DRIVE_DATA+1], 00000010b
setnz al
ret
;--------------------------------------
fs_HasCd4:
test byte [DRIVE_DATA+6], 10000000b
setnz al
ret
;--------------------------------------
fs_HasCd5:
test byte [DRIVE_DATA+6], 00100000b
setnz al
ret
;--------------------------------------
fs_HasCd6:
test byte [DRIVE_DATA+6], 00001000b
setnz al
ret
;--------------------------------------
fs_HasCd7:
test byte [DRIVE_DATA+6], 00000010b
setnz al
ret
;--------------------------------------
fs_HasCd8:
test byte [DRIVE_DATA+11], 10000000b
setnz al
ret
;--------------------------------------
fs_HasCd9:
test byte [DRIVE_DATA+11], 00100000b
setnz al
ret
;--------------------------------------
fs_HasCd10:
test byte [DRIVE_DATA+11], 00001000b
setnz al
ret
;--------------------------------------
fs_HasCd11:
test byte [DRIVE_DATA+11], 00000010b
setnz al
ret
;-----------------------------------------------------------------------------
;
;*******************************************************
 
; fs_NextXXX functions:
; in: eax = partition number, from which start to scan
; out: CF=1 => no more partitions
; CF=0 => eax=next partition number
;
;-----------------------------------------------------------------------------
 
;*******************************************************
fs_NextCd:
; we always have /cdX/1
test eax, eax
677,6 → 520,8
clc
@@:
ret
;*******************************************************
 
;-----------------------------------------------------------------------------
process_replace_file_name:
; in
/kernel/branches/Kolibri-acpi/fs/ext2/blocks.inc
2,14 → 2,11
;; ;;
;; Contains ext2 block handling code. ;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4891 $
 
 
;---------------------------------------------------------------------
; Write ext2 block from memory to disk.
; Input: eax = i_block (block number in ext2 terms);
/kernel/branches/Kolibri-acpi/fs/ext2/ext2.asm
2,14 → 2,11
;; ;;
;; Contains ext2 initialization, plus syscall handling code. ;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5089 $
 
 
include 'ext2.inc'
include 'blocks.inc'
include 'inode.inc'
59,8 → 56,6
;---------------------------------------------------------------------
proc ext2_create_partition
push ebx
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .fail
 
mov eax, 2 ; Superblock starts at 1024-bytes.
add ebx, 512 ; Get pointer to fs-specific buffer.
/kernel/branches/Kolibri-acpi/fs/ext2/ext2.inc
2,14 → 2,11
;; ;;
;; Contains ext2 structures, and macros. ;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4891 $
 
 
; Future jobs for driver, in order of preference:
; * clean up existing extents support.
; * add b-tree directories support.
/kernel/branches/Kolibri-acpi/fs/ext2/inode.inc
2,14 → 2,11
;; ;;
;; Contains ext2 inode handling code. ;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4891 $
 
 
;---------------------------------------------------------------------
; Receives block number from extent-based inode.
; Input: ecx = number of block in inode
/kernel/branches/Kolibri-acpi/fs/ext2/resource.inc
2,14 → 2,11
;; ;;
;; Contains common resource allocation + freeing code. ;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4891 $
 
 
;---------------------------------------------------------------------
; Frees a resource (block/inode).
; Input: eax = resource ID.
/kernel/branches/Kolibri-acpi/fs/xfs.asm
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5089 $
 
 
include 'xfs.inc'
 
;
25,8 → 15,6
; returns 0 (not XFS or invalid) / pointer to partition structure
xfs_create_partition:
push ebx ecx edx esi edi
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .error
cmp dword[ebx + xfs_sb.sb_magicnum], XFS_SB_MAGIC ; signature
jne .error
 
/kernel/branches/Kolibri-acpi/fs/xfs.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; from stat.h
; distinguish file types
S_IFMT = 0170000o ; These bits determine file type.
/kernel/branches/Kolibri-acpi/fs/iso9660.inc
7,15 → 7,18
 
$Revision$
 
;-----------------------------------------------------------------------------
 
uglobal
cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
endg
;-----------------------------------------------------------------------------
 
reserve_cd:
 
cli
cmp [cd_status], 0
je reserve_ok2
23,8 → 26,9
sti
call change_task
jmp reserve_cd
;-----------------------------------------------------------------------------
 
reserve_ok2:
 
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
33,105 → 37,48
pop eax
sti
ret
;-----------------------------------------------------------------------------
 
reserve_cd_channel:
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
pushad
mov eax, [cdpos]
dec eax
shr eax, 2
 
test eax, eax
jnz .1
 
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel1_mutex
jmp .mutex_lock
;--------------------------------------
@@:
call mutex_lock
mov [IDE_Channel_1], 1
popad
ret
.IDE_Channel_2:
pushad
mov ecx, ide_channel2_mutex
jmp .mutex_lock
;--------------------------------------
.1:
dec eax
jnz .2
 
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel3_mutex
jmp .mutex_lock
;--------------------------------------
@@:
mov ecx, ide_channel4_mutex
jmp .mutex_lock
;--------------------------------------
.2:
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel5_mutex
jmp .mutex_lock
;--------------------------------------
@@:
mov ecx, ide_channel6_mutex
.mutex_lock:
call mutex_lock
mov [IDE_Channel_2], 1
popad
ret
;-----------------------------------------------------------------------------
 
free_cd_channel:
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
pushad
mov eax, [cdpos]
dec eax
shr eax, 2
 
test eax, eax
jnz .1
 
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel1_mutex
jmp .mutex_unlock
;--------------------------------------
@@:
call mutex_unlock
popad
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
pushad
mov ecx, ide_channel2_mutex
jmp .mutex_unlock
;--------------------------------------
.1:
dec eax
jnz .2
 
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel3_mutex
jmp .mutex_unlock
;--------------------------------------
@@:
mov ecx, ide_channel4_mutex
jmp .mutex_unlock
;--------------------------------------
.2:
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel5_mutex
jmp .mutex_unlock
;--------------------------------------
@@:
mov ecx, ide_channel6_mutex
.mutex_unlock:
call mutex_unlock
popad
ret
;-----------------------------------------------------------------------------
 
uglobal
cd_status dd 0
endg
;-----------------------------------------------------------------------------
 
;----------------------------------------------------------------
;
; fs_CdRead - LFN variant for reading CD disk
;
144,114 → 91,91
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;-----------------------------------------------------------------------------
;--------------------------------------------------------------
fs_CdRead:
push edi
cmp byte [esi], 0
jnz @f
;--------------------------------------
.noaccess:
pop edi
;--------------------------------------
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
;--------------------------------------
 
.noaccess_3:
pop eax edx ecx edi
jmp .noaccess_2
;--------------------------------------
 
@@:
call cd_find_lfn
jnc .found
 
pop edi
cmp [DevErrorCode], 0
jne .noaccess_2
 
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
;--------------------------------------
 
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b; do not allow read directories
jnz .noaccess
 
test ebx, ebx
jz .l1
 
cmp dword [ebx+4], 0
jz @f
 
xor ebx, ebx
;--------------------------------------
.reteof:
mov eax, 6; end of file
pop edi
ret
;--------------------------------------
@@:
mov ebx, [ebx]
;--------------------------------------
.l1:
push ecx edx
push 0
mov eax, [edi+10] ; real size of the file section
mov eax, [edi+10] ; реальный размер файловой секции
sub eax, ebx
jb .eof
 
cmp eax, ecx
jae @f
 
mov ecx, eax
mov byte [esp], 6
;--------------------------------------
@@:
mov eax, [edi+2]
mov [CDSectorAddress], eax
;--------------------------------------
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector:
test ecx, ecx
jz .done
 
sub ebx, 2048
jae .next
 
add ebx, 2048
jnz .incomplete_sector
 
cmp ecx, 2048
jb .incomplete_sector
; we may read and memmove complete sector
mov [CDDataBuf_pointer], edx
call ReadCDWRetr ; read sector of file
call ReadCDWRetr; читаем сектор файла
cmp [DevErrorCode], 0
jne .noaccess_3
 
add edx, 2048
sub ecx, 2048
;--------------------------------------
.next:
inc dword [CDSectorAddress]
jmp .new_sector
;--------------------------------------
.incomplete_sector:
; we must read and memmove incomplete sector
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; read sector of file
call ReadCDWRetr; читаем сектор файла
cmp [DevErrorCode], 0
jne .noaccess_3
 
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
 
mov ecx, 2048
;--------------------------------------
@@:
sub ecx, ebx
push edi esi ecx
265,19 → 189,19
pop ecx
xor ebx, ebx
jmp .next
;--------------------------------------
 
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
;--------------------------------------
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
;-----------------------------------------------------------------------------
 
;----------------------------------------------------------------
;
; fs_CdReadFolder - LFN variant for reading CD disk folder
;
291,37 → 215,30
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;-----------------------------------------------------------------------------
;--------------------------------------------------------------
fs_CdReadFolder:
push edi
call cd_find_lfn
jnc .found
 
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
 
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
;--------------------------------------
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
 
pop edi
;--------------------------------------
.noaccess_1:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
;--------------------------------------
.found_dir:
mov eax, [edi+2] ; eax=cluster
mov [CDSectorAddress], eax
mov eax, [edi+10] ; directory size
;--------------------------------------
mov eax, [edi+10] ; размер директрории
.doit:
; init header
push eax ecx
333,23 → 250,21
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
; начинаем переброску БДВК в УСВК
;.mainloop:
mov [cd_counter_block], dword 0
dec dword [CDSectorAddress]
push ecx
;--------------------------------------
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; read sector of directory
call ReadCDWRetr ; читаем сектор директории
cmp [DevErrorCode], 0
jne .noaccess_1
 
call .get_names_from_buffer
sub eax, 2048
; directory is over?
; директория закончилась?
ja .read_to_buffer
 
mov edi, [cd_counter_block]
mov [edx+8], edi
mov edi, [ebx]
357,30 → 272,24
xor eax, eax
dec ecx
js @f
 
mov al, ERROR_END_OF_FILE
;--------------------------------------
@@:
pop ecx edi
mov ebx, [edx+4]
ret
;--------------------------------------
 
.get_names_from_buffer:
mov [cd_current_pointer_of_input_2], CDDataBuf
push eax esi edi edx
;--------------------------------------
.get_names_from_buffer_1:
call cd_get_name
jc .end_buffer
 
inc dword [cd_counter_block]
mov eax, [cd_counter_block]
cmp [ebx], eax
jae .get_names_from_buffer_1
 
test ecx, ecx
jz .get_names_from_buffer_1
 
mov edi, [cd_counter_block]
mov [edx+4], edi
dec ecx
389,11 → 298,10
add edi, 40
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode
;--------------------------------------
; jmp .unicode
.ansi:
cmp [cd_counter_block], 2
jbe .ansi_parent_directory
 
cld
lodsw
xchg ah, al
400,178 → 308,163
call uni2ansi_char
cld
stosb
; check end of file
; проверка конца файла
mov ax, [esi]
cmp ax, word 3B00h ; separator end of file ';'
cmp ax, word 3B00h; сепаратор конца файла ';'
je .cd_get_parameters_of_file_1
; check for files not ending with separator
; проверка для файлов не заканчивающихся сепаратором
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_1
; check the end of the directory
; проверка конца папки
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .ansi
;--------------------------------------
.cd_get_parameters_of_file_1:
mov [edi], byte 0
call cd_get_parameters_of_file
add [cd_mem_location], 304
jmp .get_names_from_buffer_1
;--------------------------------------
 
.ansi_parent_directory:
cmp [cd_counter_block], 2
je @f
 
mov [edi], byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
;--------------------------------------
@@:
mov [edi], word '..'
add edi, 2
jmp .cd_get_parameters_of_file_1
;--------------------------------------
 
.unicode:
cmp [cd_counter_block], 2
jbe .unicode_parent_directory
 
cld
movsw
; check end of file
; проверка конца файла
mov ax, [esi]
cmp ax, word 3B00h; separator end of file ';'
cmp ax, word 3B00h; сепаратор конца файла ';'
je .cd_get_parameters_of_file_2
; check for files not ending with separator
; проверка для файлов не заканчивающихся сепаратором
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_2
; check the end of the directory
; проверка конца папки
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .unicode
;--------------------------------------
.cd_get_parameters_of_file_2:
mov [edi], word 0
call cd_get_parameters_of_file
add [cd_mem_location], 560
jmp .get_names_from_buffer_1
;--------------------------------------
 
.unicode_parent_directory:
cmp [cd_counter_block], 2
je @f
 
mov [edi], word 2E00h; '.'
add edi, 2
jmp .cd_get_parameters_of_file_2
;--------------------------------------
@@:
mov [edi], dword 2E002E00h; '..'
add edi, 4
jmp .cd_get_parameters_of_file_2
;--------------------------------------
 
.end_buffer:
pop edx edi esi eax
ret
;-----------------------------------------------------------------------------
 
cd_get_parameters_of_file:
mov edi, [cd_mem_location]
cd_get_parameters_of_file_1:
; get file attributes
; получаем атрибуты файла
xor eax, eax
; file is not archived
; файл не архивировался
inc eax
shl eax, 1
; is a directory?
; это каталог?
test [ebp-8], byte 2
jz .file
 
inc eax
;--------------------------------------
.file:
; not as a volume label in the FAT, in this form not available
; file is not a system
; метка тома не как в FAT, в этом виде отсутсвует
; файл не является системным
shl eax, 3
; file is hidden? (attribute of existence)
; файл является скрытым? (атрибут существование)
test [ebp-8], byte 1
jz .hidden
 
inc eax
;--------------------------------------
.hidden:
shl eax, 1
; file is always read-only, as this CD
; файл всегда только для чтения, так как это CD
inc eax
mov [edi], eax
; get the time to file
; hour
; получаем время для файла
;час
movzx eax, byte [ebp-12]
shl eax, 8
; minute
;минута
mov al, [ebp-11]
shl eax, 8
; second
;секунда
mov al, [ebp-10]
; file creation time
;время создания файла
mov [edi+8], eax
; last access time
;время последнего доступа
mov [edi+16], eax
; last write time
;время последней записи
mov [edi+24], eax
; get date for file
; year
; получаем дату для файла
;год
movzx eax, byte [ebp-15]
add eax, 1900
shl eax, 8
; month
;месяц
mov al, [ebp-14]
shl eax, 8
; day
;день
mov al, [ebp-13]
; file creation date
;дата создания файла
mov [edi+12], eax
; last access date
;время последнего доступа
mov [edi+20], eax
; last write date
;время последней записи
mov [edi+28], eax
; get the data type of name
; получаем тип данных имени
xor eax, eax
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode_1
 
mov [edi+4], eax
jmp @f
;--------------------------------------
.unicode_1:
inc eax
mov [edi+4], eax
;--------------------------------------
@@:
; get the file size in bytes
; получаем размер файла в байтах
xor eax, eax
mov [edi+32+4], eax
mov eax, [ebp-23]
mov [edi+32], eax
ret
;-----------------------------------------------------------------------------
 
;----------------------------------------------------------------
;
; fs_CdGetFileInfo - LFN variant for CD
; get file/directory attributes structure
;
;-----------------------------------------------------------------------------
;----------------------------------------------------------------
fs_CdGetFileInfo:
cmp byte [esi], 0
jnz @f
 
mov eax, 2
ret
;--------------------------------------
@@:
push edi
call cd_find_lfn
578,20 → 471,16
pushfd
cmp [DevErrorCode], 0
jz @f
 
popfd
pop edi
mov eax, 11
ret
;--------------------------------------
@@:
popfd
jnc @f
 
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
;--------------------------------------
@@:
 
mov edi, edx
604,7 → 493,8
pop edi
xor eax, eax
ret
;-----------------------------------------------------------------------------
 
;----------------------------------------------------------------
cd_find_lfn:
mov [cd_appl_data], 0
; in: esi+ebp -> name
611,13 → 501,14
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
; Sector 16 - start set of volume descriptors
; 16 сектор начало набора дескрипторов томов
 
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
 
call prevent_medium_removal
; testing of reading
; тестовое чтение
mov [CDSectorAddress], dword 16
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr;_1
624,11 → 515,10
cmp [DevErrorCode], 0
jne .access_denied
 
; calculation of the last session
; вычисление последней сессии
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
 
call Read_TOC
mov ah, [CDDataBuf+4+4]
mov al, [CDDataBuf+4+5]
639,7 → 529,7
mov [CDSectorAddress], eax
; mov [CDSectorAddress],dword 15
mov [CDDataBuf_pointer], CDDataBuf
;--------------------------------------
 
.start:
inc dword [CDSectorAddress]
call ReadCDWRetr;_1
647,128 → 537,111
jne .access_denied
 
.start_check:
; checking for "lice"
; проверка на вшивость
cmp [CDDataBuf+1], dword 'CD00'
jne .access_denied
 
cmp [CDDataBuf+5], byte '1'
jne .access_denied
; sector is the terminator of set of descriptors volumes?
; сектор является терминатором набор дескрипторов томов?
cmp [CDDataBuf], byte 0xff
je .access_denied
; sector is an additional and improved descriptor of volume?
; сектор является дополнительным и улучшенным дескриптором тома?
cmp [CDDataBuf], byte 0x2
jne .start
; sector is an additional descriptor of volume?
; сектор является дополнительным дескриптором тома?
cmp [CDDataBuf+6], byte 0x1
jne .start
 
; parameters of root directory
mov eax, [CDDataBuf+0x9c+2]; start of root directory
; параметры root директрории
mov eax, [CDDataBuf+0x9c+2]; начало root директрории
mov [CDSectorAddress], eax
mov eax, [CDDataBuf+0x9c+10]; size of root directory
mov eax, [CDDataBuf+0x9c+10]; размер root директрории
cmp byte [esi], 0
jnz @f
 
mov [cd_current_pointer_of_input], CDDataBuf+0x9c
jmp .done
;--------------------------------------
@@:
; start the search
; начинаем поиск
.mainloop:
dec dword [CDSectorAddress]
;--------------------------------------
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; read sector of directory
call ReadCDWRetr ; читаем сектор директории
cmp [DevErrorCode], 0
jne .access_denied
 
push ebp
call cd_find_name_in_buffer
pop ebp
jnc .found
 
sub eax, 2048
; directory is over?
; директория закончилась?
cmp eax, 0
ja .read_to_buffer
; desired element of chain is not found
; нет искомого элемента цепочки
.access_denied:
pop esi eax
mov [cd_appl_data], 1
stc
ret
;--------------------------------------
; desired element of chain found
; искомый элемент цепочки найден
.found:
; the end of the file path
; конец пути файла
cmp byte [esi-1], 0
jz .done
.nested:
mov eax, [cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; beginning of the directory
mov eax, [eax+2+8] ; size of directory
pop dword [CDSectorAddress] ; начало директории
mov eax, [eax+2+8]; размер директории
jmp .mainloop
;--------------------------------------
; file pointer found
; указатель файла найден
.done:
test ebp, ebp
jz @f
 
mov esi, ebp
xor ebp, ebp
jmp .nested
;--------------------------------------
@@:
pop esi eax
mov [cd_appl_data], 1
clc
ret
;-----------------------------------------------------------------------------
 
cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2], CDDataBuf
;--------------------------------------
.start:
call cd_get_name
jc .not_found
 
call cd_compare_name
jc .start
;--------------------------------------
.found:
clc
ret
;--------------------------------------
.not_found:
stc
ret
;-----------------------------------------------------------------------------
 
cd_get_name:
push eax
mov ebp, [cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input], ebp
mov eax, [ebp]
test eax, eax ; entry's is over?
test eax, eax ; входы закончились?
jz .next_sector
 
cmp ebp, CDDataBuf+2048 ; buffer is over?
cmp ebp, CDDataBuf+2048 ; буфер закончился?
jae .next_sector
 
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2], eax ; next entry of directory
add ebp, 33; pointer is set to the beginning of the name
add [cd_current_pointer_of_input_2], eax; следующий вход каталога
add ebp, 33; указатель установлен на начало имени
pop eax
clc
ret
;--------------------------------------
.next_sector:
pop eax
stc
ret
;-----------------------------------------------------------------------------
 
cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
; in: esi->name, ebp->name
777,7 → 650,6
; destroys eax
push esi eax edi
mov edi, ebp
;--------------------------------------
.loop:
cld
lodsb
794,37 → 666,31
sub edi, 2
scasw
jne .name_not_coincide
;--------------------------------------
.coincides:
cmp [esi], byte '/' ; path separator is end of current element
cmp [esi], byte '/'; разделитель пути, конец имени текущего элемента
je .done
 
cmp [esi], byte 0 ; path separator end of name
cmp [esi], byte 0; разделитель пути, конец имени текущего элемента
je .done
 
jmp .loop
;--------------------------------------
.name_not_coincide:
pop edi eax esi
stc
ret
;--------------------------------------
.done:
; check end of file
cmp [edi], word 3B00h; separator end of file ';'
; проверка конца файла
cmp [edi], word 3B00h; сепаратор конца файла ';'
je .done_1
; check for files not ending with separator
; проверка для файлов не заканчивающихся сепаратором
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp edi, eax
je .done_1
; check the end of directory
; проверка конца папки
movzx eax, byte [ebp-1]
add eax, ebp
cmp edi, eax
jne .name_not_coincide
;--------------------------------------
.done_1:
pop edi eax
add esp, 4
831,7 → 697,7
inc esi
clc
ret
;-----------------------------------------------------------------------------
 
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
838,30 → 704,24
; out: al=converted symbol
cmp al, 'A'
jb .ret
 
cmp al, 'Z'
jbe .az
 
cmp al, 0x80 ; 'А'
jb .ret
 
cmp al, 0x90 ; 'Р'
jb .rus1
 
cmp al, 0x9F ; 'Я'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 0xE0-0x90
;--------------------------------------
.ret:
ret
;--------------------------------------
.rus1:
; 0x80-0x8F -> 0xA0-0xAF
.az:
add al, 0x20
ret
;-----------------------------------------------------------------------------
 
uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character
868,44 → 728,32
; out: al=converted ANSI character
cmp ax, 0x80
jb .ascii
 
cmp ax, 0x401
jz .yo1
 
cmp ax, 0x451
jz .yo2
 
cmp ax, 0x410
jb .unk
 
cmp ax, 0x440
jb .rus1
 
cmp ax, 0x450
jb .rus2
;--------------------------------------
.unk:
mov al, '_'
jmp .doit
;--------------------------------------
.yo1:
mov al, 0xF0 ; 'Ё' in cp866
jmp .doit
;--------------------------------------
.yo2:
mov al, 0xF1 ; 'ё' in cp866
jmp .doit
;--------------------------------------
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
;--------------------------------------
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
;--------------------------------------
.ascii:
.doit:
ret
;-----------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/fs/ntfs.inc
152,8 → 152,6
ret
 
proc ntfs_create_partition
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .nope
mov edx, dword [ebp+PARTITION.Length]
cmp dword [esp+4], 0
jz .boot_read_ok
/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt
86,9 → 86,9
* рисуется внешняя рамка цвета, указанного в edi,
шириной 1 пиксель
* рисуется заголовок - прямоугольник с левым верхним углом (1,1)
и правым нижним (xsize-1,min(20,ysize-1)) цвета, указанного в esi
и правым нижним (xsize-1,min(25,ysize)) цвета, указанного в esi
(с учетом градиента)
* если ysize>21, то закрашивается рабочая область окна -
* если ysize>=26, то закрашивается рабочая область окна -
прямоугольник с левым верхним углом (1,21) и правым нижним
(xsize-1,ysize-1) (размерами (xsize-1)*(ysize-21)) - цветом,
указанным в edx (с учетом градиента)
151,9 → 151,7
Возвращаемое значение:
* если буфер пуст, возвращается eax=1
* если буфер непуст, то возвращается al=0, ah=код нажатой клавиши,
биты 16-23 содержат сканкод нажатой клавиши в режиме ASCII,
в режме сканкодов биты обнулены.
биты 23-31 обнулены
старшее слово регистра eax обнулено
* если есть "горячая клавиша", то возвращается
al=2, ah=сканкод нажатой клавиши (0 для управляющих клавиш),
старшее слово регистра eax содержит состояние управляющих клавиш
818,9 → 816,9
вызове, оно может измениться в последующих версиях ядра.
 
======================================================================
========= Функция 18, подфункция 10 - свернуть активное окно. ========
======== Функция 18, подфункция 10 - свернуть окно приложения. =======
======================================================================
Сворачивает активное окно.
Сворачивает собственное окно.
Параметры:
* eax = 18 - номер функции
* ebx = 10 - номер подфункции
845,7 → 843,8
* eax = 18 - номер функции
* ebx = 11 - номер подфункции
* ecx = тип таблицы:
* 1 = короткая версия, 16 байт
* 1 = короткая версия, 10 байт
* 2 = полная версия, 65536 байт
* edx = указатель на буфер (в приложении) для таблицы
Возвращаемое значение:
* функция не возвращает значения
862,8 → 861,6
Например, для стандартной конфигурации из одного 1.44-дисковода
здесь будет 40h, а для случая 1.2Mb на A: и 1.44Mb на B:
значение оказывается 24h.
 
Первый контроллер IDE:
* +1: byte: информация о жёстких дисках и CD-приводах, AABBCCDD,
где AA соответствует контроллеру IDE0, ..., DD - IDE3:
* 0 = устройство отсутствует
872,36 → 869,31
Например, в случае HD на IDE0 и CD на IDE2 здесь будет 48h.
* +2: 4 db: число найденных разделов на жёстких дисках с
соответственно IDE0,...,IDE3.
 
Второй контроллер IDE:
* +6: byte: информация о жёстких дисках и CD-приводах, AABBCCDD
где AA соответствует контроллеру IDE4, ..., DD - IDE7:
* 0 = устройство отсутствует
* 1 = жёсткий диск
* 2 = CD-привод
Например, в случае HD на IDE4 и CD на IDE6 здесь будет 48h.
* +7: 4 db: число найденных разделов на жёстких дисках с
соответственно IDE4,...,IDE7.
 
Третий контроллер IDE:
* +11: byte: информация о жёстких дисках и CD-приводах, AABBCCDD
где AA соответствует контроллеру IDE8, ..., DD - IDE11:
* 0 = устройство отсутствует
* 1 = жёсткий диск
* 2 = CD-привод
Например, в случае HD на IDE8 и CD на IDE10 здесь будет 48h.
* +12: 4 db: число найденных разделов на жёстких дисках с
соответственно IDE8,...,IDE11.
 
При отсутствии жёсткого диска на IDEx соответствующий байт
нулевой, при наличии показывает число распознанных разделов,
которых может и не быть (если носитель не отформатирован или
если файловая система не поддерживается). В текущей версии ядра
для жёстких дисков поддерживаются только FAT12/16/32, NTFS,
ext2/3/4 и XFS.
 
для жёстких дисков поддерживаются только FAT16, FAT32 и NTFS.
* +6: 4 db: зарезервировано
Формат таблицы: полная версия:
* +0: 10 db: такие же, как и в короткой версии
* +10: 100 db: данные для первого раздела
* +110: 100 db: данные для второго раздела
* ...
* +10+100*(n-1): 100 db: данные для последнего раздела
Разделы расположены в следующем порядке: сначала последовательно все
распознанные разделы на HD на IDE0 (если есть),
затем на HD на IDE1 (если есть) и т.д. до IDE3.
Формат информации о разделе:
* +0: dword: начальный физический сектор раздела
* +4: dword: последний физический сектор раздела
(принадлежит разделу)
* +8: byte: тип файловой системы:
16=FAT16, 32=FAT32, 1=NTFS
* формат дальнейших данных зависит от файловой системы,
может меняться с изменениями в ядре и поэтому не описывается
Замечания:
* Таблица может быть использована для получения информации
* Короткая таблица может быть использована для получения информации
об имеющихся устройствах.
 
======================================================================
1217,6 → 1209,20
* Приложение @panel переключает раскладки по запросу пользователя.
 
======================================================================
=========== Функция 21, подфункция 3 - установить базу CD. ===========
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 3 - номер подфункции
* ecx = база CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Возвращаемое значение:
* eax = 0
Замечания:
* База CD используется функцией 24.
* Получить установленную базу CD можно вызовом
подфункции 3 функции 26.
 
======================================================================
========= Функция 21, подфункция 5 - установить язык системы. ========
======================================================================
Параметры:
1234,6 → 1240,52
* Получить язык системы можно вызовом подфункции 5 функции 26.
 
======================================================================
=========== Функция 21, подфункция 7 - установить базу HD. ===========
======================================================================
База HD нужна для определения, на какой жёсткий диск писать, при
использовании устаревшего синтаксиса /HD в устаревшей функции 58;
при использовании современного синтаксиса /HD0,/HD1,/HD2,/HD3
база устанавливается автоматически.
Параметры:
* eax = 21 - номер функции
* ebx = 7 - номер подфункции
* ecx = база HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Возвращаемое значение:
* eax = 0
Замечания:
* Любое приложение в любой момент времени может изменить базу.
* Не следует изменять базу, когда какое-нибудь приложение работает
с жёстким диском. Если не хотите глюков системы.
* Получить установленную базу можно вызовом подфункции 7 функции 26.
* Следует также определить используемый раздел жёсткого диска
подфункцией 8.
 
======================================================================
========== Функция 21, подфункция 8 - установить раздел HD. ==========
======================================================================
Раздел HD нужен для определения, на какой раздел жёсткого диска
писать, при использовании устаревшего синтаксиса /HD в устаревшей
функции 58; при использовании современного синтаксиса
/HD0,/HD1,/HD2,/HD3 база и раздел устанавливаются автоматически.
Параметры:
* eax = 21 - номер функции
* ebx = 8 - номер подфункции
* ecx = раздел HD (считая с 1)
Возвращаемое значение:
* eax = 0
Замечания:
* Любое приложение в любой момент времени может изменить раздел.
* Не следует изменять раздел, когда какое-нибудь приложение работает
с жёстким диском. Если не хотите глюков системы.
* Получить установленный раздел можно вызовом подфункции 8
функции 26.
* Проверок на корректность не делается.
* Узнать число разделов на жёстком диске можно вызовом
подфункции 11 функции 18.
* Следует также определить используемую базу жёсткого диска
подфункцией 7.
 
======================================================================
====================== Функция 21, подфункция 11 =====================
=========== Разрешить/запретить низкоуровневый доступ к HD. ==========
======================================================================
1264,6 → 1316,122
* Получить текущее состояние можно вызовом подфункции 12 функции 26.
 
======================================================================
============= Функция 21, подфункция 13, подподфункция 1 =============
==== Инициализировать + получить информацию о драйвере vmode.mdr. ====
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 1 - номер функции драйвера
* edx = указатель на буфер размера 512 байт
Возвращаемое значение:
* если драйвер не загружен (никогда не бывает в текущей реализации):
* eax = -1
* ebx, ecx разрушаются
* если драйвер загружен:
* eax = 'MDAZ' (в стиле fasm'а, т.е. 'M' - младший байт,
'Z' - старший) - сигнатура
* ebx = текущая частота развёртки (в Гц)
* ecx разрушается
* буфер, на который указывает edx, заполнен
Формат буфера:
* +0: 32*byte: имя драйвера, "Trans VideoDriver" (без кавычек,
дополнено пробелами)
* +32 = +0x20: dword: версия драйвера (версия x.y кодируется как
y*65536+x), для текущей реализации 1 (1.0)
* +36 = +0x24: 7*dword: зарезервировано (0 в текущей реализации)
* +64 = +0x40: 32*word: список поддерживаемых видеорежимов (каждое
слово - номер видеорежима, после собственно списка идут нули)
* +128 = +0x80: 32*(5*word): список поддерживаемых частот развёрток
для видеорежимов: для каждого видеорежима, указанного в предыдущем
поле, указано до 5 поддерживаемых частот
(в неиспользуемых позициях записаны нули)
Замечания:
* Функция инициализирует драйвер (если он ещё не инициализирован)
и должна вызываться первой, перед остальными (иначе они будут
возвращать -1, ничего не делая).
* В текущей реализации поддерживается только одна частота развёртки
на видеорежим.
 
======================================================================
============= Функция 21, подфункция 13, подподфункция 2 =============
============= Получить информацию о текущем видеорежиме. =============
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 2 - номер функции драйвера
Возвращаемое значение:
* eax = -1 - драйвер не загружен или не инициализирован;
ebx,ecx разрушаются
* eax = [ширина]*65536 + [высота]
* ebx = частота вертикальной развёртки (в Гц)
* ecx = номер текущего видеорежима
Замечания:
* Драйвер предварительно должен быть инициализирован вызовом
функции драйвера 1.
* Если нужны только размеры экрана, целесообразней использовать
функцию 14 с учётом того, что она возвращает размеры на 1 меньше.
 
======================================================================
= Функция 21, подфункция 13, подподфункция 3 - установить видеорежим.
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 3 - номер функции драйвера
* edx = [частота развёртки]*65536 + [номер видеорежима]
Возвращаемое значение:
* eax = -1 - драйвер не загружен, не инициализирован или
произошла ошибка
* eax = 0 - успешно
* ebx, ecx разрушаются
Замечания:
* Драйвер предварительно должен быть инициализирован вызовом
функции драйвера 1.
* Номер видеорежима и частота должны быть в таблице, возвращаемой
функцией драйвера 1.
 
======================================================================
============= Функция 21, подфункция 13, подподфункция 4 =============
================= Вернуться к начальному видеорежиму. ================
======================================================================
Возвращает экран в видеорежим, установленный при загрузке системы.
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 4 - номер функции драйвера
Возвращаемое значение:
* eax = -1 - драйвер не загружен или не инициализирован
* eax = 0 - успешно
* ebx, ecx разрушаются
Замечания:
* Драйвер предварительно должен быть инициализирован вызовом
функции драйвера 1.
 
======================================================================
============= Функция 21, подфункция 13, подподфункция 5 =============
======== Увеличить/уменьшить размер видимой области монитора. ========
======================================================================
Параметры:
* eax = 21 - номер функции
* ebx = 13 - номер подфункции
* ecx = 5 - номер функции драйвера
* edx = 0/1 - уменьшить/увеличить размер по горизонтали
на одну позицию
* edx = 2/3 - в текущей реализации не поддерживается; планируется
как уменьшение/увеличение размера по вертикали на одну позицию
Возвращаемое значение:
* eax = -1 - драйвер не загружен или не инициализирован
* eax = 0 - успешно
* ebx, ecx разрушаются
Замечания:
* Драйвер предварительно должен быть инициализирован вызовом
функции драйвера 1.
* Функция влияет только на физический размер изображения
на мониторе; логический размер (число пикселей) не меняется.
 
======================================================================
============ Функция 22 - установить системную дату/время. ===========
======================================================================
Параметры:
1326,6 → 1494,59
вызовет 32-битное переполнение.
 
======================================================================
======= Функция 24, подфункция 1 - начать проигрывать CD-audio. ======
======================================================================
Параметры:
* eax = 24 - номер функции
* ebx = 1 - номер подфункции
* ecx = 0x00FRSSMM, где
* MM = начальная минута
* SS = начальная секунда
* FR = начальный фрейм
Возвращаемое значение:
* eax = 0 - успешно
* eax = 1 - не определена база CD
Замечания:
* Предварительно нужно определить базовый порт CD вызовом
подфункции 3 функции 21.
* В секунде 75 фреймов, в минуте 60 секунд.
* Функция асинхронна (возвращает управление, когда началось
проигрывание).
 
======================================================================
===== Функция 24, подфункция 2 - получить информацию о дорожках. =====
======================================================================
Параметры:
* eax = 24 - номер функции
* ebx = 2 - номер подфункции
* ecx = указатель на буфер для таблицы
(максимум 8*64h+4 байт=100 дорожек)
Возвращаемое значение:
* eax = 0 - успешно
* eax = 1 - не определена база CD
Замечания:
* Формат таблицы с информацией о дорожках такой же, как и для
ATAPI-CD команды 43h (READ TOC), обычной таблицы (подкоманда 00h).
Адреса возвращаются в формате MSF.
* Предварительно нужно определить базовый порт CD вызовом
подфункции 3 функции 21.
* Функция возвращает информацию только о не более чем 100
первых дорожках. В большинстве случаев этого достаточно.
 
======================================================================
==== Функция 24, подфункция 3 - остановить проигрываемое CD-audio. ===
======================================================================
Параметры:
* eax = 24 - номер функции
* ebx = 1 - номер подфункции
Возвращаемое значение:
* eax = 0 - успешно
* eax = 1 - не определена база CD
Замечания:
* Предварительно нужно определить базовый порт CD вызовом
подфункции 3 функции 21.
 
======================================================================
======= Функция 24, подфункция 4 - извлечь лоток привода диска. ======
======================================================================
Параметры:
1332,9 → 1553,7
* eax = 24 - номер функции
* ebx = 4 - номер подфункции
* ecx = номер CD/DVD-диска
от 0=Primary Master до 3=Secondary Slave для первого IDE контр.
от 4=Primary Master до 7=Secondary Slave для второго IDE контр.
от 8=Primary Master до 11=Secondary Slave для третьего IDE контр.
(от 0=Primary Master до 3=Secondary Slave)
Возвращаемое значение:
* функция не возвращает значения
Замечания:
1352,9 → 1571,7
* eax = 24 - номер функции
* ebx = 5 - номер подфункции
* ecx = номер CD/DVD-диска
от 0=Primary Master до 3=Secondary Slave для первого IDE контр.
от 4=Primary Master до 7=Secondary Slave для второго IDE контр.
от 8=Primary Master до 11=Secondary Slave для третьего IDE контр.
(от 0=Primary Master до 3=Secondary Slave)
Возвращаемое значение:
* функция не возвращает значения
Замечания:
1432,6 → 1649,18
* Приложение @panel переключает раскладки по запросу пользователя.
 
======================================================================
============ Функция 26, подфункция 3 - получить базу CD. ============
======================================================================
Параметры:
* eax = 26 - номер функции
* ebx = 3 - номер подфункции
Возвращаемое значение:
* eax = база CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Замечания:
* База CD используется функцией 24.
* Установить базу CD можно вызовом подфункции 3 функции 21.
 
======================================================================
========== Функция 26, подфункция 5 - получить язык системы. =========
======================================================================
Параметры:
1446,6 → 1675,42
* Установить язык системы можно вызовом подфункции 5 функции 21.
 
======================================================================
============ Функция 26, подфункция 7 - получить базу HD. ============
======================================================================
База HD нужна для определения, на какой жёсткий диск писать, при
использовании устаревшего синтаксиса /HD в устаревшей функции 58;
при использовании современного синтаксиса /HD0,/HD1,/HD2,/HD3
база устанавливается автоматически.
Параметры:
* eax = 26 - номер функции
* ebx = 7 - номер подфункции
Возвращаемое значение:
* eax = база HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Замечания:
* Любое приложение в любой момент времени может изменить базу.
* Установить базу можно вызовом подфункции 7 функции 21.
* Получить используемый раздел жёсткого диска можно подфункцией 8.
 
======================================================================
=========== Функция 26, подфункция 8 - получить раздел HD. ===========
======================================================================
Раздел HD нужен для определения, на какой раздел жёсткого диска
писать, при использовании устаревшего синтаксиса /HD в устаревшей
функции 58; при использовании современного синтаксиса
/HD0,/HD1,/HD2,/HD3 база и раздел устанавливаются автоматически.
Параметры:
* eax = 26 - номер функции
* ebx = 8 - номер подфункции
Возвращаемое значение:
* eax = раздел HD (считая с 1)
Замечания:
* Любое приложение в любой момент времени может изменить раздел.
* Установить раздел можно вызовом подфункции 8 функции 21.
* Узнать число разделов на жёстком диске можно вызовом
подфункции 11 функции 18.
* Получить используемую базу жёсткого диска можно подфункцией 7.
 
======================================================================
=== Функция 26, подфункция 9 - получить значение счётчика времени. ===
======================================================================
Параметры:
2279,6 → 2544,221
эмулируется (через аналоги подфункций функции 62 режима ядра).
 
======================================================================
============== Функция 58 - работа с файловой системой. ==============
======================================================================
Параметры:
* eax = 58
* ebx = указатель на информационную структуру
Возвращаемое значение:
* eax = 0 - успешно; иначе код ошибки файловой системы
* в зависимости от подфункции может возвращаться значение и
в других регистрах
Общий формат информационной структуры:
* +0: dword: номер подфункции
* +4: dword: номер блока
* +8: dword: размер
* +12 = +0xC: dword: указатель на данные
* +16 = +0x10: dword: указатель на память для работы системы
(4096 байт)
* +20 = +0x14: n db: ASCIIZ-строка с именем файла
Уточнения - в документации на соответствующую подфункцию.
Имя файла нечувствительно к регистру латинских букв,
русские буквы должны быть заглавными.
Формат имени файла:
/base/number/dir1/dir2/.../dirn/file,
где /base/number идентифицирует устройство, на котором ищется файл:
одно из
* /RD/1 = /RAMDISK/1 для доступа к рамдиску
* /FD/1 = /FLOPPYDISK/1 для доступа к первому флоппи-дисководу,
/FD/2 = /FLOPPYDISK/2 для второго флоппи-дисковода
* /HD/x = /HARDDISK/x - устаревший вариант доступа к жёсткому диску
(в этом случае база определяется подфункцией 7 функции 21),
x - номер раздела (считая с 1)
* /HD0/x, /HD1/x, /HD2/x, /HD3/x для доступа соответственно
к устройствам IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave);
x - номер раздела на выбранном винчестере, изменяется от 1 до 255
(на каждом из винчестеров нумерация начинается с 1)
Замечания:
* В первых двух случаях допускается использование FIRST вместо 1,
SECOND вместо 2, но использовать эту возможность
не рекомендуется для удобства перехода на будущие расширения.
* Накладывается ограничение n<=39.
* Имена папок и файла dir1,...,dirn,file должны быть в формате 8.3:
имя не более 8 символов, точка, расширение не более 3 символов.
Хвостовые пробелы игнорируются. Других пробелов быть не должно.
Если имя занимает ровно 8 символов, точку можно опустить
(хотя пользоваться этим не рекомендуется для удобства перехода
на будущие расширения).
* Функция не поддерживает папок на рамдиске.
Примеры:
* '/RAMDISK/FIRST/KERNEL.ASM',0
'/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0
* '/hd0/1/menuet/pics/tanzania.bmp',0
Доступные подфункции:
* подфункция 0 - чтение файла/папки
* подфункция 8 - LBA-чтение с устройства
* подфункция 15 - получение информации о файловой системе
 
======================================================================
========== Функция 58, подфункция 0 - прочитать файл/папку. ==========
======================================================================
Параметры:
* eax = 58
* ebx = указатель на информационную структуру
Формат информационной структуры:
* +0: dword: 0 = номер подфункции
* +4: dword: номер блока для чтения (считая с 0)
* +8: dword: число блоков для чтения
* +12 = +0xC: dword: указатель на буфер, куда будут записаны данные
* +16 = +0x10: dword: указатель на буфер для работы системы
(4096 байт)
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в
общем описании
Возвращаемое значение:
* eax = 0 - успешно, иначе код ошибки файловой системы
* ebx = размер файла (в байтах) или
-1=0xffffffff, если файл не найден
Замечания:
* Размер блока - 512 байт.
* Эта функция устарела, для чтения файлов используйте подфункцию 0
функции 70, для чтения папок - подфункцию 1 функции 70.
* Функция позволяет читать содержимое папки. Из файловых систем
поддерживается только FAT. Формат FAT-папки описан в любой
документации по FAT.
* Размер папки определяется по размеру цепочки кластеров в FAT.
* Если файл кончился раньше, чем был прочитан последний запрошенный
блок, то функция прочитает, сколько сможет, после чего вернёт
eax=6 (EOF).
* Функция позволяет читать корневые папки /rd/1,/fd/x,/hd[n]/x, но
в первых двух случаях текущая реализация не следует
установленным правилам:
для /rd/1:
* если указано 0 блоков для чтения, считается,
что запрашивается 1;
* если запрашивается больше 14 блоков или начальный блок
не меньше 14-го, то возвращается eax=5 (not found) и ebx=-1;
* размер корневого каталога рамдиска = 14 блоков,
0x1C00=7168 байт; но возвращается ebx=0
(за исключением случая предыдущего пункта);
* как ни странно, можно прочитать 14-й блок (там, вообще говоря,
мусор - напоминаю, счёт ведётся с 0);
* если был запрошен хотя бы один блок с номером, не меньшим 14,
то возвращается eax=6(EOF); иначе eax=0.
Для /fd/x:
* если начальный блок не меньше 14-го, то возвращается
eax=5 (not found) и ebx=0;
* кстати говоря, формат FAT12 допускает дискеты с размером
корневого каталога меньше или больше 14 блоков;
* проверки длины не делается;
* если удалось прочитать данные с дискеты, возвращается
eax=0,ebx=0; в противном случае eax=10 (access denied), ebx=-1.
* Функция обрабатывает чтение специальных папок /,/rd,/fd,/hd[n];
но результат не соответствует ожидаемому
(по работе с обычными файлами/папками), не следует установленным
правилам, может измениться в следующих версиях ядра и потому
не описывается. Для получения информации об оборудовании
используйте подфункцию 11 функции 18 или
читайте соответствующие папки подфункцией 1 функции 70.
 
======================================================================
========= Функция 58, подфункция 8 - LBA-чтение с устройства. ========
======================================================================
Параметры:
* eax = 58 - номер функции
* ebx = указатель на информационную структуру
Формат информационной структуры:
* +0: dword: 8 = номер подфункции
* +4: dword: номер блока для чтения (считая с 0)
* +8: dword: игнорируется (устанавливайте в 1)
* +12 = +0xC: dword: указатель на буфер, куда будут записаны данные
(512 байт)
* +16 = +0x10: dword: указатель на буфер для работы системы
(4096 байт)
* +20 = +0x14: ASCIIZ-имя устройства: нечувствительно к регистру,
одно из /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n,
1<=n<=4 - номер устройства: 1=IDE0, ..., 4=IDE3.
Вместо цифр допускается, хотя и не рекомендуется для удобства
перехода на будущие расширения,
использование 'first','second','third','fourth'.
Возвращаемое значение:
* если указано имя устройства /hd/xxx, где xxx не находится
в списке выше:
* eax = ebx = 1
* если указано неправильное имя устройства
(за исключением предыдущего случая):
* eax = 5
* ebx не меняется
* если LBA-доступ запрещён подфункцией 11 функции 21:
* eax = 2
* ebx разрушается
* для рамдиска: попытка чтения блока за пределами рамдиска
(18*2*80 блоков) приводит к
* eax = 3
* ebx = 0
* при успешном чтении:
* eax = ebx = 0
Замечания:
* Размер блока - 512 байт; читается один блок.
* Не следует полагаться на возвращаемое значение,
оно может измениться в следующих версиях.
* Требуется, чтобы был разрешён LBA-доступ к устройствам
подфункцией 11 функции 21. Узнать это можно вызовом
подфункцией 11 функции 26.
* LBA-чтение дискеты не поддерживается.
* Функция считывает данные физического жёсткого диска;
если по каким-то причинам нужны данные конкретного раздела,
придётся определять начальный сектор этого раздела
(либо напрямую через MBR, либо из расширенной структуры,
возвращаемой той же подфункцией 11 функции 18).
* Функция не проверяет код ошибки жёсткого диска, так что запрос
несуществующего сектора всё равно что-то прочитает
(вероятнее всего, нули, но это определяется устройством) и
это будет считаться успехом (eax=0).
 
======================================================================
= Функция 58, подфункция 15 - получить информацию о файловой системе.
======================================================================
Параметры:
* eax = 58 - номер функции
* ebx = указатель на информационную структуру
Формат информационной структуры:
* +0: dword: 15 = номер подфункции
* +4: dword: игнорируется
* +8: dword: игнорируется
* +12 = +0xC: dword: игнорируется
* +16 = +0x10: dword: игнорируется
* +20 = +0x14: (проверяется только второй символ, сразу после слэша)
/rd=/RAMDISK или /hd=/HARDDISK
Возвращаемое значение:
* если второй символ не принадлежит множеству {'r','R','h','H'}:
* eax = 3
* ebx = ecx = dword [fileinfo] = 0
* для рамдиска:
* eax = 0 (успех)
* ebx = общее число кластеров = 2847
* ecx = число свободных кластеров
* dword [fileinfo] = размер кластера = 512
* для жёсткого диска: база и раздел определяются подфункциями 7 и 8
функции 21:
* eax = 0 (успех)
* ebx = общее число кластеров
* ecx = число свободных кластеров
* dword [fileinfo] = размер кластера (в байтах)
Замечания:
* Не удивляйтесь странному расположению 4-го возвращаемого
параметра - когда писался этот код, при системных вызовах
приложению возвращались только регистры eax,ebx,ecx (из
pushad-структуры, передающейся как аргумент системной функции).
Теперь это исправлено, так что, возможно, имеет смысл возвращать
размер кластера в edx, пока эту функцию не начали использовать.
* Вообще-то ещё существует подфункция 11 функции 18, возвращающая
информацию о файловой системе. По расширенной таблице дисковой
подсистемы можно определить размер кластера (там он хранится
в секторах) и общее число кластеров для жёстких дисков.
 
======================================================================
=========== Функция 60 - Inter Process Communication (IPC). ==========
======================================================================
IPC применяется для посылок сообщений от одного процесса/потока
4064,7 → 4544,13
Возвращаемое значение:
* eax = socketnum1, -1 для ошибки
* ebx = socketnum2, код ошибки в случае ошибки
Замечания:
 
Optstruct: dd level
dd optionname
dd optlength
db options...
 
======================================================================
========== Функция -1 - завершить выполнение потока/процесса =========
======================================================================
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
82,9 → 82,9
* The window of type I looks as follows:
* draw external frame of color indicated in edi, 1 pixel in width
* draw header - rectangle with the left upper corner (1,1) and
right lower (xsize-1,min(20,ysize-1)) color indicated in esi
right lower (xsize-1,min(25,ysize)) color indicated in esi
(taking a gradient into account)
* if ysize>21, fill the working area of the window -
* if ysize>=26, fill the working area of the window -
rectangle with the left upper corner (1,21) and right lower
(xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color
indicated in edx (taking a gradient into account)
148,10 → 148,7
Returned value:
* if the buffer is empty, function returns eax=1
* if the buffer is not empty, function returns al=0,
ah=code of the pressed key,
bits 16-23 = contain scancode for pressed key in ASCII mode,
in the scancodes mode this bits cleared.
bits 23-31 = zero
ah=code of the pressed key, high word of eax is zero
* if there is "hotkey", function returns al=2,
ah=scancode of the pressed key (0 for control keys),
high word of eax contains a status of control keys at the moment
818,9 → 815,9
changed in future versions of the kernel.
 
======================================================================
======= Function 18, subfunction 10 - minimize topmost window. =======
===== Function 18, subfunction 10 - minimize application window. =====
======================================================================
Minimizes the topmost (active) window.
Minimizes the own window.
Parameters:
* eax = 18 - function number
* ebx = 10 - subfunction number
831,8 → 828,8
keeps position and sizes.
* Restoring of an application window occurs at its activation by
subfunction 3.
* Usually there is no necessity to minimize/restore a window
explicitly: minimization of a window is carried out by the system
* Usually there is no necessity to minimize/restire a window
obviously: minimization of a window is carried out by the system
at pressing the minimization button (for skinned windows
it is defined automatically by function 0,
for other windows it can be defined manually by function 8),
845,7 → 842,8
* eax = 18 - function number
* ebx = 11 - subfunction number
* ecx = type of the table:
* 1 = short version, 16 bytes
* 1 = short version, 10 bytes
* 2 = full version, 65536 bytes
* edx = pointer to the buffer (in the application) for the table
Returned value:
* function does not return value
862,11 → 860,9
For example, for the standard configuration from one 1.44-drive
here will be 40h, and for the case 1.2Mb on A: and 1.44Mb on B:
the value is 24h.
First IDE controller:
* +1: byte: information about hard disks and CD-drives, AABBCCDD,
where AA corresponds to the controller IDE0, ..., DD - IDE3:
* 0 = device not found
* 0 = device is absent
* 1 = hard drive
* 2 = CD-drive
For example, in the case HD on IDE0 and CD on IDE2
873,37 → 869,32
this field contains 48h.
* +2: 4 db: number of the retrieved partitions on hard disks
at accordingly IDE0,...,IDE3.
Second IDE controller:
* +6: byte: information about hard disks and CD-drives, AABBCCDD,
where AA corresponds to the controller IDE4, ..., DD - IDE7:
* 0 = device not found
* 1 = hard drive
* 2 = CD-drive
For example, in the case HD on IDE4 and CD on IDE6
this field contains 48h.
* +7: 4 db: number of the retrieved partitions on hard disks
at accordingly IDE4,...,IDE7.
 
Third IDE controller:
* +11: byte: information about hard disks and CD-drives, AABBCCDD,
where AA corresponds to the controller IDE8, ..., DD - IDE11:
* 0 = device not found
* 1 = hard drive
* 2 = CD-drive
For example, in the case HD on IDE8 and CD on IDE10
this field contains 48h.
* +12: 4 db: number of the retrieved partitions on hard disks
at accordingly IDE8,...,IDE11.
If the hard disk on IDEx is absent, appropriate byte is zero,
otherwise it shows number of the recognized partitions, which
can be not presented (if the drive is not formatted or if
the file system is not supported). Current version of the kernel
supports only FAT12/16/32, NTFS, ext2/3/4 and XFS for hard disks.
 
supports only FAT16, FAT32 and NTFS for hard disks.
* +6: 4 db: reserved
Format of the table: full version:
* +0: 10 db: same as for the short version
* +10: 100 db: data for the first partition
* +110: 100 db: data for the second partition
* ...
* +10+100*(n-1): 100 db: data for the last partition
The partitions are located as follows: at first sequentially all
recoginzed partitions on HD on IDE0 (if present),
then on HD on IDE1 (if present) and so on up to IDE3.
Format of the information about partition
(at moment only FAT is supported):
* +0: dword: first physical sector of the partition
* +4: dword: last physical sector of the partition
(belongs to the partition)
* +8: byte: file system type:
16=FAT16, 32=FAT32, 1=NTFS
* other data are dependent on file system, are modified with
kernel modifications and therefore are not described
Remarks:
* The table can be used for obtaining the information about
* The short table can be used for obtaining the information about
available devices.
 
======================================================================
1218,6 → 1209,19
* The application @panel switches layouts on user request.
 
======================================================================
============== Function 21, subfunction 3 - set CD base. =============
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 3 - subfunction number
* ecx = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Returned value:
* eax = 0
Remarks:
* CD base is used by function 24.
* To get CD base use subfunction 3 of function 26.
 
======================================================================
========== Function 21, subfunction 5 - set system language. =========
======================================================================
Parameters:
1235,6 → 1239,49
* To get system language use subfunction 5 of function 26.
 
======================================================================
============== Function 21, subfunction 7 - set HD base. =============
======================================================================
The HD base defines hard disk to write with usage of obsolete
syntax /HD in obsolete function 58; at usage of modern syntax
/HD0,/HD1,/HD2,/HD3 base is set automatically.
Parameters:
* eax = 21 - function number
* ebx = 7 - subfunction number
* ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Returned value:
* eax = 0
Remarks:
* Any application at any time can change the base.
* Do not change base, when any application works with hard disk.
If you do not want system bugs.
* To get HD base use subfunction 7 of function 26.
* It is also necessary to define used partition of hard disk by
subfunction 8.
 
======================================================================
========= Function 21, subfunction 8 - set used HD partition. ========
======================================================================
The HD partition defines partition of the hard disk to write with
usage of obsolete syntax /HD and obsolete function 58;
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
base and partition are set automatically.
Parameters:
* eax = 21 - function number
* ebx = 8 - subfunction number
* ecx = HD partition (beginning from 1)
Return value:
* eax = 0
Remarks:
* Any application at any time can change partition.
* Do not change partition when any application works with hard disk.
If you do not want system bugs.
* To get used partition use subfunction 8 of function 26.
* There is no correctness checks.
* To get the number of partitions of a hard disk use
subfunction 11 of function 18.
* It is also necessary to define used HD base by subfunction 7.
 
======================================================================
Function 21, subfunction 11 - enable/disable low-level access to HD.
======================================================================
Parameters:
1263,6 → 1310,120
* To get current status use subfunction 12 of function 26.
 
======================================================================
============ Function 21, subfunction 13, subsubfunction 1 ===========
======== Initialize + get information on the driver vmode.mdr. =======
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 1 - number of the driver function
* edx = pointer to 512-bytes buffer
Returned value:
* if driver is not loaded
(never happens in the current implementation):
* eax = -1
* ebx, ecx destroyed
* if driver is loaded:
* eax = 'MDAZ' (in fasm style, that is 'M' - low byte, 'Z' - high)
- signature
* ebx = current frequency of the scanning (in Hz)
* ecx destroyed
* buffer pointed to by edx is filled
Format of the buffer:
* +0: 32*byte: driver name, "Trans VideoDriver"
(without quotes, supplemented by spaces)
* +32 = +0x20: dword: driver version (version x.y is encoded as
y*65536+x), for the current implementation is 1 (1.0)
* +36 = +0x24: 7*dword: reserved (0 in the current implementation)
* +64 = +0x40: 32*word: list of supported videomodes (each word
is number of a videomode, after list itself there are zeroes)
* +128 = +0x80: 32*(5*word): list of supported frequences of the
scannings for videomodes: for each videomode listed in the
previous field up to 5 supported frequences are given
(unused positions contain zeroes)
Remarks:
* Function initializes the driver (if it is not initialized yet)
and must be called first, before others (otherwise they will do
nothing and return -1).
* The current implementation supports only one frequency
of the scanning on videomode.
 
======================================================================
============ Function 21, subfunction 13, subsubfunction 2 ===========
================ Get information on current videomode. ===============
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 2 - number of the driver function
Returned value:
* eax = -1 - driver is not loaded or not initialized;
ebx,ecx are destroyed
* eax = [width]*65536 + [height]
* ebx = frequency of the vertical scanning (in Hz)
* ecx = number of current videomode
Remarks:
* Driver must be initialized by call to
driver function 1.
* If only screen sizes are required, it is more expedient to use
function 14 taking into account that it
returns sizes on 1 less.
 
======================================================================
=== Function 21, subfunction 13, subsubfunction 3 - set videomode. ===
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 3 - number of the driver function
* edx = [scanning frequency]*65536 + [videomode number]
Returned value:
* eax = -1 - driver is not loaded, not initialized or
an error has occured
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by driver function 1.
* The videomode number and frequency must be in the table
returned by driver function 1.
 
======================================================================
============ Function 21, subfunction 13, subsubfunction 4 ===========
================== Return to the initial videomode. ==================
======================================================================
Returns the screen to the videomode set at system boot.
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 4 - number of the driver function
Returned value:
* eax = -1 - driver is not loaded or not initialized
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by call to driver function 1.
 
======================================================================
============ Function 21, subfunction 13, subsubfunction 5 ===========
===== Increase/decrease the size of the visible area of monitor. =====
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 5 - number of the driver function
* edx = 0/1 - decrease/increase horizontal size on 1 position
* edx = 2/3 - is not supported in the current implementation;
is planned as decrease/increase vertical size on 1 position
Returned value:
* eax = -1 - driver is not loaded or not initialized
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by call to driver function 1.
* Function influences only the physical size of the screen image;
the logical size (number of pixels) does not change.
 
======================================================================
================= Function 22 - set system date/time. ================
======================================================================
Parameters:
1324,6 → 1485,58
makes 32-bit overflow.
 
======================================================================
======== Function 24, subfunction 1 - begin to play CD-audio. ========
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 1 - subfunction number
* ecx = 0x00FRSSMM, where
* MM = starting minute
* SS = starting second
* FR = starting frame
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* Previously CD base must be defined by the call to
subfunction 3 of function 21.
* One second includes 75 frames, one minute includes 60 seconds.
* The function is asynchronous (returns control, when play begins).
 
======================================================================
======= Function 24, subfunction 2 - get information on tracks. ======
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 2 - subfunction number
* ecx = pointer to the buffer for the table
(maximum 8*64h+4 bytes=100 tracks)
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* The format of the table with tracks information is the same as
for ATAPI-CD command 43h (READ TOC), usual table (subcommand 00h).
Function returns addresses in MSF.
* Previously CD base port must be set by call to
subfunction 3 of function 21.
* Function returns information only about no more than 100
first tracks. In most cases it is enough.
 
======================================================================
========== Function 24, subfunction 3 - stop play CD-audio. ==========
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 1 - subfunction number
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* Previously CD base port must be defined by call to
subfunction 3 of function 21.
 
======================================================================
======= Function 24, subfunction 4 - eject tray of disk drive. =======
======================================================================
Parameters:
1330,9 → 1543,7
* eax = 24 - function number
* ebx = 4 - subfunction number
* ecx = position of CD/DVD-drive
from 0=Primary Master to 3=Secondary Slave for first IDE contr.
from 4=Primary Master to 7=Secondary Slave for second IDE contr.
from 8=Primary Master to 11=Secondary Slave for third IDE contr.
(from 0=Primary Master to 3=Secondary Slave)
Returned value:
* function does not return value
Remarks:
1350,9 → 1561,7
* eax = 24 - function number
* ebx = 5 - subfunction number
* ecx = position of CD/DVD-drive
from 0=Primary Master to 3=Secondary Slave for first IDE contr.
from 4=Primary Master to 7=Secondary Slave for second IDE contr.
from 8=Primary Master to 11=Secondary Slave for third IDE contr.
(from 0=Primary Master to 3=Secondary Slave)
Returned value:
* function does not return value
Remarks:
1427,6 → 1636,18
* The application @panel switches layouts on user request.
 
======================================================================
============== Function 26, subfunction 3 - get CD base. =============
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 3 - subfunction number
Returned value:
* eax = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Remarks:
* CD base is used by function 24.
* To set CD base use subfunction 3 of function 21.
 
======================================================================
========== Function 26, subfunction 5 - get system language. =========
======================================================================
Parameters:
1441,6 → 1662,41
* To set system language use subfunction 5 of function 21.
 
======================================================================
============== Function 26, subfunction 7 - get HD base. =============
======================================================================
The HD base defines hard disk to write with usage of obsolete
syntax /HD in obsolete function 58; at usage of modern syntax
/HD0,/HD1,/HD2,/HD3 base is set automatically.
Parameters:
* eax = 26 - function number
* ebx = 7 - subfunction number
Returned value:
* eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Remarks:
* Any application in any time can change HD base.
* To set base use subfunction 7 of function 21.
* To get used partition of hard disk use subfunction 8.
 
======================================================================
========= Function 26, subfunction 8 - get used HD partition. ========
======================================================================
The HD partition defines partition of the hard disk to write with
usage of obsolete syntax /HD in obsolete function 58;
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
base and partition are set automatically.
Parameters:
* eax = 26 - function number
* ebx = 8 - subfunction number
Returned value:
* eax = HD partition (beginning from 1)
Remarks:
* Any application in any time can change partition.
* To set partition use subfunction 8 of function 21.
* To get number of partitions on a hard disk use
subfunction 11 of function 18.
* To get base of used hard disk, use subfunction 7.
 
======================================================================
=== Function 26, subfunction 9 - get the value of the time counter. ==
======================================================================
Parameters:
2059,7 → 2315,8
Parameters:
* eax = 48 - function number
* ebx = 8 - subfunction number
* ecx = pointer to filename of the skin
* ecx = pointer to a block for function 58, in
which the fields of intermediate buffer and file name are filled
Returned value:
* eax = 0 - success
* otherwise eax = file system error code; if file does not
2270,6 → 2527,219
(through kernel-mode analogues of subfunctions of function 62).
 
======================================================================
================ Function 58 - work with file system. ================
======================================================================
Parameters:
* eax = 58
* ebx = pointer to the information structure
Returned value:
* eax = 0 - success; otherwise file system error code
* some subfunctions return value in other registers too
General format of the information structure:
* +0: dword: subfunction number
* +4: dword: number of block
* +8: dword: size
* +12 = +0xC: dword: pointer to data
* +16 = +0x10: dword: pointer to a memory for system operations
(4096 bytes)
* +20 = +0x14: n db: ASCIIZ-string with the file name
Specifications - in documentation on the appropriate subfunction.
Filename is case-insensitive for latin letters, russian letters
must be capital.
Format of filename:
/base/number/dir1/dir2/.../dirn/file,
where /base/number identifies device, on which file is located:
one of
* /RD/1 = /RAMDISK/1 to access ramdisk
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive,
/FD/2 = /FLOPPYDISK/2 to access second one
* /HD/x = /HARDDISK/x - obsolete variant of access to hard disk
(in this case base is defined by subfunction 7 of function 21),
x - partition number (beginning from 1)
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices
IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave);
x - partition number on the selected hard drive, varies from 1
to 255 (on each hard drive the indexing starts from 1)
Remarks:
* In the first two cases it is also possible to use FIRST
instead of 1, SECOND instead of 2, but it is not recommended
for convenience of transition to the future extensions.
* Limitation n<=39 is imposed.
* Names of folders and file dir1,...,dirn,file must have the
format 8.3: name no more than 8 characters, dot, extension no
more than 3 characters. Trailing spaces are ignored, no other
spaces is allowed. If name occupies equally 8 characters,
dot may be omitted (though it is not recommended to use this
feature for convenience of transition to the future extensions).
* This function does not support folders on ramdisk.
Examples:
* '/RAMDISK/FIRST/KERNEL.ASM',0
'/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0
* '/hd0/1/menuet/pics/tanzania.bmp',0
Existing subfunctions:
* subfunction 0 - read file/folder
* subfunction 8 - LBA-read from device
* subfunction 15 - get file system information
 
======================================================================
=========== Function 58, subfunction 0 - read file/folder. ===========
======================================================================
Parameters:
* eax = 58
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 0 = subfunction number
* +4: dword: first block to read (beginning from 0)
* +8: dword: amount of blocks to read
* +12 = +0xC: dword: pointer to buffer for data
* +16 = +0x10: dword: pointer to buffer for system operations
(4096 bytes)
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx = file size (in bytes) or -1=0xffffffff, if file was not found
Remarks:
* Block size is 512 bytes.
* This function is obsolete, for reading files use subfunction 0
of function 70, for reading folders - subfunction 1 of
function 70.
* Function can read contents of a folder. Only FAT file system is
supported. The format of FAT-folder is described
in any FAT documentation.
* Size of a folder is determined by size of FAT clusters chain.
* If file was ended before last requested block was read,
the function will read as many as it can, and after that return
eax=6 (EOF).
* Function can read root folders /rd/1,/fd/x,/hd[n]/x, but
in the first two cases the current implementation does not follow
to the declared rules:
for /rd/1:
* if one want to read 0 blocks, function considers,
that he requested 1;
* if one requests more than 14 blocks or starting block is
not less than 14, function returns eax=5 (not found) and ebx=-1;
* size of ramdisk root folder is 14 blocks,
0x1C00=7168 bytes; but function returns ebx=0
(except of the case of previous item);
* strangely enough, it is possible to read 14th block (which
generally contains a garbage - I remind, the indexing begins
from 0);
* if some block with the number not less than 14 was requested,
function returns eax=6(EOF); otherwise eax=0.
For /fd/x:
* if the start block is not less than 14, function returns
eax=5 (not found) and ebx=0;
* note that format of FAT12 allows floppies with the root size
more or less than 14 blocks;
* check for length is not performed;
* if data was successful read, function returns
eax=0,ebx=0; otherwise eax=10 (access denied), ebx=-1.
* The function handles reading of special folders /,/rd,/fd,/hd[n];
but the result does not correspond to expected (on operations with
normal files/folders), does not follow the declared rules,
may be changed in future versions of the kernel and consequently
is not described. To obtain the information about the equipment
use subfunction 11 of function 18 or
read corresponding folder with subfunction 1 of function 70.
 
======================================================================
========= Function 58, subfunction 8 - LBA-read from device. =========
======================================================================
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 8 = subfunction number
* +4: dword: number of block to read (beginning from 0)
* +8: dword: ignored (set to 1)
* +12 = +0xC: dword: pointer to buffer for data (512 bytes)
* +16 = +0x10: dword: pointer to buffer for system operations
(4096 bytes)
* +20 = +0x14: ASCIIZ-name of device: case-insensitive, one of
/rd/1 = /RamDisk/1, /hd/n = /HardDisk/n,
1<=n<=4 - number of device: 1=IDE0, ..., 4=IDE3.
Instead of digits it is allowed, though not recommended for
convenience of transition to future extensions, to use
'first','second','third','fourth'.
Returned value:
* for device name /hd/xxx, where xxx is not in the list above:
* eax = ebx = 1
* for invalid device name (except for the previous case):
* eax = 5
* ebx does not change
* if LBA-access is disabled by subfunction 11 of function 21:
* eax = 2
* ebx destroyed
* for ramdisk: attempt to read block outside ramdisk
(18*2*80 blocks) results in
* eax = 3
* ebx = 0
* for successful read:
* eax = ebx = 0
Remarks:
* Block size is 512 bytes; function reads one block.
* Do not depend on returned value, it can be changed
in future versions.
* Function requires that LBA-access to devices is enabled by
subfunction 11 of function 21. To check this one can use
subfunction 11 of function 26.
* LBA-read of floppy is not supported.
* Function reads data on physical hard drive; if for any reason
data of the concrete partition are required, application must
define starting sector of this partition (either directly
through MBR, or from the full structure returned by
subfunction 11 of function 18).
* Function does not check error code of hard disk, so request of
nonexisting sector reads something (most probably it will be
zeroes, but this is defined by device) and this is considered
as success (eax=0).
 
======================================================================
==== Function 58, subfunction 15 - get information on file system. ===
======================================================================
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 15 = subfunction number
* +4: dword: ignored
* +8: dword: ignored
* +12 = +0xC: dword: ignored
* +16 = +0x10: dword: ignored
* +20 = +0x14: (only second character is checked)
/rd=/RAMDISK or /hd=/HARDDISK
Returned value:
* if the second character does not belong to set {'r','R','h','H'}:
* eax = 3
* ebx = ecx = dword [fileinfo] = 0
* for ramdisk:
* eax = 0 (success)
* ebx = total number of clusters = 2847
* ecx = number of free clusters
* dword [fileinfo] = cluster size = 512
* for hard disk: base and partition are defined by subfunctions
7 and 8 of function 21:
* eax = 0 (success)
* ebx = total number of clusters
* ecx = number of free clusters
* dword [fileinfo] = cluster size (in bytes)
Remarks:
* Be not surprised to strange layout of 4th returned parameter
- when this code was writing, at system calls application got
only registers eax,ebx,ecx (from pushad-structure transmitted
as argument to the system function). Now it is corrected, so,
probably, it is meaningful to return cluster size in edx, while
this function is not used yet.
* There exists also subfunction 11 of function 18,
which returns information on file system. From the full table
of disk subsystem it is possible to deduce cluster size (there
it is stored in sectors) and total number of clusters
for hard disks.
 
======================================================================
========== Function 60 - Inter Process Communication (IPC). ==========
======================================================================
IPC is used for message dispatching from one process/thread to
4032,7 → 4502,13
Returned value:
* eax = socketnum1, -1 on error
* ebx = socketnum2, errorcode on error
Remarks:
 
Optstruct: dd level
dd optionname
dd optlength
db options...
 
======================================================================
=============== Function -1 - terminate thread/process ===============
======================================================================
/kernel/branches/Kolibri-acpi/docs/usbapi.txt
186,7 → 186,6
USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer
USB_STATUS_CLOSED = 16 ; pipe closed, either explicitly with USBClosePipe
; or due to device disconnect
USB_STATUS_CANCELLED = 17 ; transfer cancelled with USBAbortPipe
 
If several transfers are queued for the same pipe, their callback functions
are called in the same order as they were queued.
195,11 → 194,6
with USB_STATUS_CLOSED. The call to DeviceDisconnected() occurs after
all callbacks.
 
void __stdcall USBAbortPipe(void* pipe);
Initiates cancellation of all active transfers for the given pipe. Asynchronous.
When a transfer will be cancelled, the associated callback function
will be called with USB_STATUS_CANCELLED.
 
void* __stdcall USBGetParam(void* pipe0, int param);
Returns miscellaneous parameters of the device.
pipe0 is the pointer to the config pipe.
/kernel/branches/Kolibri-acpi/encoding.inc
1,133 → 1,148
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 5082 $
 
; fetch the UTF-8 character in addrspace:offs to char
macro fetch_utf8_char addrspace, offs, char
; fetch the UTF-8 character in string+offs to char
; common part for all encodings: translate pseudographics
; Pseudographics for the boot screen:
; 0x2500 -> 0xC4, 0x2502 -> 0xB3, 0x250C -> 0xDA, 0x2510 -> 0xBF,
; 0x2514 -> 0xC0, 0x2518 -> 0xD9, 0x252C -> 0xC2, 0x2534 -> 0xC1, 0x2551 -> 0xBA
macro fetch_utf8_char string, offs, char, graph
{ local first_byte, b
virtual at 0
db string
if offs >= $
char = -1
else
; fetch first byte
load first_byte byte from addrspace:offs
load first_byte byte from offs
if first_byte < 0x80
char = first_byte
offs = offs + 1
else if first_byte < 0xC0
err Invalid UTF-8 string
.err Invalid UTF-8 string
else if first_byte < 0xE0
char = first_byte and 0x1F
load b byte from addrspace:offs + 1
load b byte from offs + 1
char = (char shl 6) + (b and 0x3F)
offs = offs + 2
else if first_byte < 0xF0
char = first_byte and 0xF
load b byte from addrspace:offs + 1
load b byte from offs + 1
char = (char shl 6) + (b and 0x3F)
load b byte from addrspace:offs + 2
load b byte from offs + 2
char = (char shl 6) + (b and 0x3F)
offs = offs + 3
else if first_byte < 0xF8
char = first_byte and 0x7
load b byte from addrspace:offs + 1
load b byte from offs + 1
char = (char shl 6) + (b and 0x3F)
load b byte from addrspace:offs + 2
load b byte from offs + 2
char = (char shl 6) + (b and 0x3F)
load b byte from addrspace:offs + 3
load b byte from offs + 3
char = (char shl 6) + (b and 0x3F)
offs = offs + 4
else
err Invalid UTF-8 string
.err Invalid UTF-8 string
end if
}
 
; Worker macro for all encodings.
; Common part for all encodings: map characters 0-0x7F trivially,
; translate pseudographics.
; Pseudographics for the boot screen:
; 0x2500 -> 0xC4, 0x2502 -> 0xB3, 0x250C -> 0xDA, 0x2510 -> 0xBF,
; 0x2514 -> 0xC0, 0x2518 -> 0xD9, 0x252C -> 0xC2, 0x2534 -> 0xC1, 0x2551 -> 0xBA
macro convert_utf8 encoding, [arg]
{ common
local ..addrspace, offs, char
offs = 0
virtual at 0
..addrspace:: db arg
..addrspace#.size = $
end if
end virtual
while offs < ..addrspace#.size
fetch_utf8_char ..addrspace, offs, char
if char = 0x2500
db 0xC4
graph = 0xC4
else if char = 0x2502
db 0xB3
graph = 0xB3
else if char = 0x250C
db 0xDA
graph = 0xDA
else if char = 0x2510
db 0xBF
graph = 0xBF
else if char = 0x2514
db 0xC0
graph = 0xC0
else if char = 0x2518
db 0xD9
graph = 0xD9
else if char = 0x252C
db 0xC2
graph = 0xC2
else if char = 0x2534
db 0xC1
graph = 0xC1
else if char = 0x2551
db 0xBA
else if char < 0x80
db char
graph = 0xBA
else
encoding char
graph = 0
end if
end while
}
 
macro declare_encoding encoding
{
macro encoding [arg]
\{ common convert_utf8 encoding#char, arg \}
struc encoding [arg]
\{ common convert_utf8 encoding#char, arg \}
macro encoding#char char
}
 
; Russian: use CP866.
; 0x00-0x7F - trivial map
; 0x410-0x43F -> 0x80-0xAF
; 0x440-0x44F -> 0xE0-0xEF
; 0x401 -> 0xF0, 0x451 -> 0xF1
declare_encoding cp866
{
if char = 0x401
macro cp866 [arg]
{ local offs, char, graph
offs = 0
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x80
db char
else if char = 0x401
db 0xF0
else if char = 0x451
db 0xF1
else if (char < 0x410) | (char > 0x44F)
err Failed to convert to CP866
.err Failed to convert to CP866
else if char < 0x440
db char - 0x410 + 0x80
else
db char - 0x440 + 0xE0
end if
end while
}
 
struc cp866 [arg]
{
common
cp866 arg
}
 
; Latin-1 encoding
; 0x00-0xFF - trivial map
declare_encoding latin1
{
if char < 0x100
macro latin1 [arg]
{ local offs, char, graph
offs = 0
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x100
db char
else
err Failed to convert to Latin-1
.err Failed to convert to Latin-1
end if
end while
}
 
struc latin1 [arg]
{
common
latin1 arg
}
 
; CP850 encoding
declare_encoding cp850
{
if char = 0xBF
macro cp850 [arg]
{ local offs, char, graph
offs = 0
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x80
db char
else if char = 0xBF
db 0xA8
else if char = 0xE1
db 0xA0
142,4 → 157,11
else
err Failed to convert to CP850
end if
end while
}
 
struc cp850 [arg]
{
common
cp850 arg
}
/kernel/branches/Kolibri-acpi/kernelsp.inc
1,13 → 1,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 4850 $
 
 
; Éste archivo debe ser editado con codificación CP866
 
version cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0
/kernel/branches/Kolibri-acpi/macros.inc
89,12 → 89,6
mov op1, op2
}
 
macro list_init head
{
mov [head+LHEAD.next], head
mov [head+LHEAD.prev], head
}
 
macro __list_add new, prev, next
{
mov [next+LHEAD.prev], new
117,10 → 111,10
 
macro list_del entry
{
mov edx, [entry+LHEAD.next]
mov ecx, [entry+LHEAD.prev]
mov [edx+LHEAD.prev], ecx
mov [ecx+LHEAD.next], edx
mov edx, [entry+list_fd]
mov ecx, [entry+list_bk]
mov [edx+list_bk], ecx
mov [ecx+list_fd], edx
}
 
; MOV Immediate.
/kernel/branches/Kolibri-acpi/build.bat
1,10 → 1,11
@echo off
cls
set languages=en ru ge et sp
set targets=kernel clean
set drivers=com_mouse emu10k1x fm801 infinity sis sound viasound vt823x
set targets=all kernel drivers clean
 
call :Check_Target %1
for %%a in (kernel) do if %%a==%target% call :Check_Lang %2
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2
call :Target_%target%
 
if ERRORLEVEL 0 goto Exit_OK
55,6 → 56,51
goto :eof
 
 
:Target_all
call :Target_kernel
call :Target_drivers
goto :eof
 
 
:Target_drivers
echo *** building drivers ...
 
if not exist bin\drivers mkdir bin\drivers
cd drivers
for %%a in (%drivers%) do (
fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj
if not %errorlevel%==0 goto :Error_FasmFailed
)
cd ..
 
kpack >nul 2>&1
 
if %errorlevel%==9009 goto :Error_KpackFailed
 
echo *
echo ##############################################
echo *
echo Kpack KolibriOS drivers?
echo *
 
set /P res=[y/n]?
 
if "%res%"=="y" (
 
echo *
echo Compressing system
 
echo *
for %%a in (bin\drivers\*.obj) do (
echo ================== kpack %%a
kpack %%a
if not %errorlevel%==0 goto :Error_KpackFailed
)
 
)
goto :eof
 
 
:Target_clean
echo *** cleaning ...
rmdir /S /Q bin
68,6 → 114,14
pause
exit 1
 
:Error_KpackFailed
echo *** NOTICE ***
echo If you want to pack all applications you may
echo place "kpack" in accessible directory or system %PATH%.
echo You can get this tool from KolibriOS distribution kit.
pause
exit 1
 
:Exit_OK
echo.
echo all operations have been done
/kernel/branches/Kolibri-acpi/makefile
1,10 → 1,11
FASM=fasm
FLAGS=-m 65536
languages=en|ru|ge|et|sp
drivers_src=com_mouse emu10k1x fm801 infinity sis sound vt823x
 
.PHONY: all kernel bootloader clean
.PHONY: all kernel drivers bootloader clean
 
all: kernel bootloader
all: kernel drivers bootloader
 
kernel: check_lang
@echo "*** building kernel with language '$(lang)' ..."
14,6 → 15,14
@$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt
@rm -f lang.inc
 
drivers:
@echo "*** building drivers ..."
@mkdir -p bin/drivers
@cd drivers; for f in $(drivers_src); do \
echo "--- building 'bin/drivers/$${f}.obj' ..."; \
$(FASM) $(FLAGS) "$${f}.asm" "../bin/drivers/$${f}.obj" || exit $?; \
done
 
bootloader: check_lang
@echo "*** building bootloader with language '$(lang)' ..."
@mkdir -p bin