acpi: update
git-svn-id: svn://kolibrios.org@5201 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
1ae250fff2
commit
e6265b4399
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -16,6 +16,7 @@ DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable
|
|||
DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters
|
||||
DISK_STATUS_NO_MEDIA = 2 ; no media present
|
||||
DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data
|
||||
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.
|
||||
|
@ -101,14 +102,13 @@ ends
|
|||
; there are two distinct caches for a disk, one for "system" data,and the other
|
||||
; for "application" data.
|
||||
struct DISKCACHE
|
||||
mutex MUTEX
|
||||
; Lock to protect the cache.
|
||||
; The following fields are inherited from data32.inc:cache_ideX.
|
||||
pointer dd ?
|
||||
data_size dd ? ; unused
|
||||
data dd ?
|
||||
sad_size dd ?
|
||||
search_start dd ?
|
||||
sector_size_log dd ?
|
||||
ends
|
||||
|
||||
; This structure represents a disk device and its media for the kernel.
|
||||
|
@ -169,6 +169,8 @@ struct DISK
|
|||
; 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.
|
||||
|
@ -270,13 +272,13 @@ disk_list_mutex MUTEX
|
|||
endg
|
||||
|
||||
iglobal
|
||||
; The function 'disk_scan_partitions' needs three 512-byte buffers for
|
||||
; The function 'disk_scan_partitions' needs three sector-sized 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.
|
||||
; heap. Also, the heap is used when sector size is other than 512.
|
||||
; 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
|
||||
|
@ -637,28 +639,25 @@ disk_scan_partitions:
|
|||
; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list.
|
||||
and [esi+DISK.NumPartitions], 0
|
||||
and [esi+DISK.Partitions], 0
|
||||
; 2. Currently we can work only with 512-bytes sectors. Check this restriction.
|
||||
; The only exception is 2048-bytes CD/DVD, but they are not supported yet by
|
||||
; this code.
|
||||
cmp [esi+DISK.MediaInfo.SectorSize], 512
|
||||
jz .doscan
|
||||
DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize]
|
||||
ret
|
||||
.doscan:
|
||||
; 3. Acquire the buffer for MBR and bootsector tests. See the comment before
|
||||
; 2. 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
|
||||
stdcall kernel_alloc, 512*3
|
||||
@@:
|
||||
lea eax, [eax*3]
|
||||
stdcall kernel_alloc, eax
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
xchg eax, ebx
|
||||
.buffer_acquired:
|
||||
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no
|
||||
; more than MAX_NUM_PARTITION times.
|
||||
; 4. Prepare things for the loop.
|
||||
; 3. 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.
|
||||
|
@ -667,6 +666,10 @@ disk_scan_partitions:
|
|||
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
|
||||
|
@ -985,7 +988,7 @@ end virtual
|
|||
; a three-sectors-sized buffer. This function saves ebx in the stack
|
||||
; immediately before ebp.
|
||||
mov ebx, [ebp-4] ; get buffer
|
||||
add ebx, 512 ; advance over MBR data to bootsector data
|
||||
add ebx, [esi+DISK.MediaInfo.SectorSize] ; 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
|
||||
|
@ -996,7 +999,7 @@ end virtual
|
|||
; 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+512 points to 512-bytes buffer that can be used for anything.
|
||||
; ebx+[esi+DISK.MediaInfo.SectorSize] points to sector-sized buffer that can be used for anything.
|
||||
call fat_create_partition
|
||||
test eax, eax
|
||||
jnz .success
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -379,10 +379,16 @@ RecalibrateFDD:
|
|||
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
|
||||
|
|
|
@ -17,7 +17,7 @@ hdbase dd ?
|
|||
hdid dd ?
|
||||
hdpos dd ?
|
||||
ends
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
iglobal
|
||||
align 4
|
||||
ide_callbacks:
|
||||
|
@ -35,18 +35,34 @@ hd0_data HD_DATA ?, 0, 1
|
|||
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
|
||||
|
||||
hd_address_table:
|
||||
dd 0x1f0, 0x00, 0x1f0, 0x10
|
||||
dd 0x170, 0x00, 0x170, 0x10
|
||||
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
|
||||
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
|
||||
|
@ -67,15 +83,13 @@ endl
|
|||
; 2. Acquire the global lock.
|
||||
mov ecx, ide_mutex
|
||||
call mutex_lock
|
||||
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 ecx, [hd_data]
|
||||
mov ecx, [ecx+HD_DATA.hdpos]
|
||||
dec ecx
|
||||
shr ecx, 1
|
||||
shl ecx, 2
|
||||
mov ecx, [ecx + ide_mutex_table]
|
||||
mov [channel_lock], ecx
|
||||
call mutex_lock
|
||||
; 3. Convert parameters to the form suitable for worker procedures.
|
||||
|
@ -83,6 +97,7 @@ endl
|
|||
; 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]
|
||||
|
@ -98,55 +113,65 @@ endl
|
|||
; 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
|
||||
|
||||
test [DRIVE_DATA+1], byte 10100000b
|
||||
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
|
||||
|
||||
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
|
||||
jnz .nodma
|
||||
|
||||
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
|
||||
|
@ -167,15 +192,13 @@ endl
|
|||
; 2. Acquire the global lock.
|
||||
mov ecx, ide_mutex
|
||||
call mutex_lock
|
||||
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 ecx, [hd_data]
|
||||
mov ecx, [ecx+HD_DATA.hdpos]
|
||||
dec ecx
|
||||
shr ecx, 1
|
||||
shl ecx, 2
|
||||
mov ecx, [ecx + ide_mutex_table]
|
||||
mov [channel_lock], ecx
|
||||
call mutex_lock
|
||||
; 3. Convert parameters to the form suitable for worker procedures.
|
||||
|
@ -183,6 +206,7 @@ endl
|
|||
; 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]
|
||||
|
@ -200,66 +224,79 @@ endl
|
|||
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
|
||||
|
||||
test [DRIVE_DATA+1], byte 10100000b
|
||||
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
|
||||
|
||||
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
|
||||
jnz .nodma
|
||||
|
||||
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]
|
||||
|
@ -270,14 +307,12 @@ proc ide_querymedia stdcall, hd_data, mediainfo
|
|||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
align 4
|
||||
; input: eax = sector, edi -> buffer
|
||||
; output: edi = edi + 512
|
||||
hd_read_pio:
|
||||
push eax edx
|
||||
|
||||
; Select the desired drive
|
||||
mov edx, [hdbase]
|
||||
add edx, 6 ;адрес регистра головок
|
||||
|
@ -286,9 +321,9 @@ hd_read_pio:
|
|||
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
|
||||
|
@ -372,7 +407,6 @@ hd_read_pio:
|
|||
|
||||
pushfd
|
||||
cli
|
||||
|
||||
mov ecx, 256
|
||||
mov edx, [hdbase]
|
||||
cld
|
||||
|
@ -393,6 +427,7 @@ cache_write_pio:
|
|||
out dx, al ; номер головки/номер диска
|
||||
|
||||
call wait_for_hd_idle
|
||||
|
||||
cmp [hd_error], 0
|
||||
jne hd_write_error
|
||||
|
||||
|
@ -550,13 +585,14 @@ wait_for_hd_idle:
|
|||
align 4
|
||||
wfhil1:
|
||||
call check_hd_wait_timeout
|
||||
|
||||
cmp [hd_error], 0
|
||||
jne @f
|
||||
|
||||
in al, dx
|
||||
test al, 128
|
||||
jnz wfhil1
|
||||
|
||||
;--------------------------------------
|
||||
@@:
|
||||
pop edx eax
|
||||
ret
|
||||
|
@ -573,6 +609,7 @@ wait_for_sector_buffer:
|
|||
align 4
|
||||
hdwait_sbuf: ; wait for sector buffer to be ready
|
||||
call check_hd_wait_timeout
|
||||
|
||||
cmp [hd_error], 0
|
||||
jne @f
|
||||
|
||||
|
@ -587,9 +624,10 @@ hdwait_sbuf: ; wait for sector buffer to be ready
|
|||
|
||||
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
|
||||
|
@ -606,22 +644,17 @@ wait_for_sector_dma_ide0:
|
|||
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
|
||||
|
@ -636,23 +669,17 @@ wait_for_sector_dma_ide1:
|
|||
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
|
||||
|
@ -660,7 +687,8 @@ align 4
|
|||
;-----------------------------------------------------------------------------
|
||||
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
|
||||
|
@ -673,19 +701,14 @@ endg
|
|||
;-----------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
|
@ -693,7 +716,8 @@ IDE_irq_14_handler:
|
|||
cli
|
||||
pushad
|
||||
mov [IDE_common_irq_param], 0
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
mov ecx, [IDE_controller_pointer]
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
; test whether it is our interrupt?
|
||||
add edx, 2
|
||||
in al, dx
|
||||
|
@ -715,18 +739,17 @@ IDE_irq_14_handler:
|
|||
mov al, 1
|
||||
ret
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
popad
|
||||
popfd
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.exit:
|
||||
mov al, 0
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
|
@ -734,7 +757,8 @@ IDE_irq_15_handler:
|
|||
cli
|
||||
pushad
|
||||
mov [IDE_common_irq_param], 0
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
mov ecx, [IDE_controller_pointer]
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
add dx, 8
|
||||
; test whether it is our interrupt?
|
||||
add edx, 2
|
||||
|
@ -757,26 +781,26 @@ IDE_irq_15_handler:
|
|||
mov al, 1
|
||||
ret
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
popad
|
||||
popfd
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.exit:
|
||||
mov al, 0
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
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 dx, [IDEContrRegsBaseAddr]
|
||||
mov ecx, [IDE_controller_pointer]
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
mov eax, IDE_common_irq_param
|
||||
cmp [eax], irq14_num
|
||||
mov [eax], bl
|
||||
|
@ -784,7 +808,6 @@ IDE_common_irq_handler:
|
|||
|
||||
add dx, 8
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
; test whether it is our interrupt?
|
||||
add edx, 2
|
||||
|
@ -807,13 +830,11 @@ align 4
|
|||
mov al, 1
|
||||
ret
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
popad
|
||||
popfd
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.exit:
|
||||
popfd
|
||||
mov al, 0
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
|
@ -824,26 +845,31 @@ hd_read_dma:
|
|||
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
|
||||
|
@ -851,13 +877,18 @@ hd_read_dma:
|
|||
mov word [eax+4], 0x2000
|
||||
sub eax, OS_BASE
|
||||
; select controller Primary or Secondary
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
mov ecx, [IDE_controller_pointer]
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
|
||||
push eax
|
||||
mov eax, [hd_address_table]
|
||||
cmp [hdbase], eax ; 0x1F0
|
||||
mov eax, [hdpos]
|
||||
dec eax
|
||||
test eax, 10b
|
||||
pop eax
|
||||
jz @f
|
||||
|
||||
add edx, 8
|
||||
;--------------------------------------
|
||||
@@:
|
||||
push edx
|
||||
; Bus Master IDE PRD Table Address
|
||||
|
@ -881,9 +912,9 @@ hd_read_dma:
|
|||
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
|
||||
|
@ -961,47 +992,55 @@ hd_read_dma:
|
|||
;--------------------------------------
|
||||
.continue:
|
||||
; select controller Primary or Secondary
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
mov eax, [hd_address_table]
|
||||
cmp [hdbase], eax ; 0x1F0
|
||||
mov ecx, [IDE_controller_pointer]
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
|
||||
mov eax, [hdpos]
|
||||
dec eax
|
||||
test eax, 10b
|
||||
jz @f
|
||||
|
||||
add dx, 8
|
||||
;--------------------------------------
|
||||
@@:
|
||||
; set write to memory and Start Bus Master
|
||||
mov al, 9
|
||||
out dx, al
|
||||
|
||||
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
|
||||
mov eax, [hdpos]
|
||||
dec eax
|
||||
test eax, 10b
|
||||
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, [hd_address_table]
|
||||
cmp [hdbase], eax ; 0x1F0
|
||||
mov eax, [hdpos]
|
||||
dec eax
|
||||
test eax, 10b
|
||||
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
|
||||
;-----------------------------------------------------------------------------
|
||||
|
@ -1011,6 +1050,7 @@ cache_write_dma:
|
|||
; 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
|
||||
|
@ -1021,15 +1061,21 @@ cache_write_dma:
|
|||
cld
|
||||
rep movsd
|
||||
popa
|
||||
|
||||
sub eax, OS_BASE
|
||||
; select controller Primary or Secondary
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
mov ecx, [IDE_controller_pointer]
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
|
||||
push eax
|
||||
mov eax, [hd_address_table]
|
||||
cmp [hdbase], eax ; 0x1F0
|
||||
mov eax, [hdpos]
|
||||
dec eax
|
||||
test eax, 10b
|
||||
pop eax
|
||||
jz @f
|
||||
|
||||
add edx, 8
|
||||
;--------------------------------------
|
||||
@@:
|
||||
push edx
|
||||
; Bus Master IDE PRD Table Address
|
||||
|
@ -1053,9 +1099,9 @@ cache_write_dma:
|
|||
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]
|
||||
|
@ -1134,52 +1180,93 @@ cache_write_dma:
|
|||
;--------------------------------------
|
||||
.continue:
|
||||
; select controller Primary or Secondary
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
mov eax, [hd_address_table]
|
||||
cmp [hdbase], eax ; 0x1F0
|
||||
mov ecx, [IDE_controller_pointer]
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
|
||||
mov eax, [hdpos]
|
||||
dec eax
|
||||
test eax, 10b
|
||||
jz @f
|
||||
|
||||
add dx, 8
|
||||
;--------------------------------------
|
||||
@@:
|
||||
; set write to device and Start Bus Master
|
||||
mov al, 1
|
||||
out dx, al
|
||||
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
|
||||
|
||||
mov eax, [hdpos]
|
||||
dec eax
|
||||
test eax, 10b
|
||||
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, [hd_address_table]
|
||||
cmp [hdbase], eax ; 0x1F0
|
||||
|
||||
mov eax, [hdpos]
|
||||
dec eax
|
||||
test eax, 10b
|
||||
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
|
||||
pop esi
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
uglobal
|
||||
proc clear_pci_ide_interrupts
|
||||
mov esi, pcidev_list
|
||||
;--------------------------------------
|
||||
align 4
|
||||
IDE_Interrupt dw ?
|
||||
IDEContrRegsBaseAddr dw ?
|
||||
IDEContrProgrammingInterface dw ?
|
||||
IDE_BAR0_val dw ?
|
||||
IDE_BAR1_val dw ?
|
||||
IDE_BAR2_val dw ?
|
||||
IDE_BAR3_val dw ?
|
||||
endg
|
||||
.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
|
||||
;-----------------------------------------------------------------------------
|
||||
|
|
|
@ -41,53 +41,29 @@ find_empty_slot_CD_cache:
|
|||
ret
|
||||
;--------------------------------------------------------------------
|
||||
clear_CD_cache:
|
||||
DEBUGF 1, 'K : clear_CD_cache\n'
|
||||
pusha
|
||||
.ide0:
|
||||
|
||||
mov esi, [cdpos]
|
||||
dec esi
|
||||
imul esi, sizeof.IDE_CACHE
|
||||
add esi, cache_ide0
|
||||
|
||||
xor eax, eax
|
||||
cmp [cdpos], 1
|
||||
jne .ide1
|
||||
mov [cache_ide0_search_start], eax
|
||||
mov ecx, [cache_ide0_system_sad_size]
|
||||
mov edi, [cache_ide0_pointer]
|
||||
|
||||
mov [esi+IDE_CACHE.search_start], eax
|
||||
mov ecx, [esi+IDE_CACHE.system_sad_size]
|
||||
mov edi, [esi+IDE_CACHE.pointer]
|
||||
call .clear
|
||||
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:
|
||||
|
||||
mov [esi+IDE_CACHE.appl_search_start], eax
|
||||
mov ecx, [esi+IDE_CACHE.appl_sad_size]
|
||||
mov edi, [esi+IDE_CACHE.data_pointer]
|
||||
call .clear
|
||||
|
||||
popa
|
||||
ret
|
||||
;--------------------------------------
|
||||
.clear:
|
||||
shl ecx, 1
|
||||
cld
|
||||
|
@ -96,272 +72,131 @@ clear_CD_cache:
|
|||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache:
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos], 1
|
||||
jne .ide1
|
||||
; 1 - IDE0 ... 12 - IDE11
|
||||
push eax
|
||||
|
||||
mov eax, [cdpos]
|
||||
dec eax
|
||||
imul eax, sizeof.IDE_CACHE
|
||||
add eax, cache_ide0
|
||||
|
||||
cmp [cd_appl_data], 0
|
||||
jne .ide0_appl_data
|
||||
mov ecx, [cache_ide0_system_sad_size]
|
||||
mov esi, [cache_ide0_pointer]
|
||||
jne @f
|
||||
|
||||
mov ecx, [eax+IDE_CACHE.system_sad_size]
|
||||
mov esi, [eax+IDE_CACHE.pointer]
|
||||
pop eax
|
||||
ret
|
||||
.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]
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov ecx, [eax+IDE_CACHE.appl_sad_size]
|
||||
mov esi, [eax+IDE_CACHE.data_pointer]
|
||||
pop eax
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_1:
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos], 1
|
||||
jne .ide1
|
||||
; 1 - IDE0 ... 12 - IDE11
|
||||
push eax
|
||||
|
||||
mov eax, [cdpos]
|
||||
dec eax
|
||||
imul eax, sizeof.IDE_CACHE
|
||||
add eax, cache_ide0
|
||||
|
||||
cmp [cd_appl_data], 0
|
||||
jne .ide0_appl_data
|
||||
mov esi, [cache_ide0_pointer]
|
||||
jne @f
|
||||
|
||||
mov esi, [eax+IDE_CACHE.pointer]
|
||||
pop eax
|
||||
ret
|
||||
.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]
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov esi, [eax+IDE_CACHE.data_pointer]
|
||||
pop eax
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_2:
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos], 1
|
||||
jne .ide1
|
||||
; 1 - IDE0 ... 12 - IDE11
|
||||
mov eax, [cdpos]
|
||||
dec eax
|
||||
imul eax, sizeof.IDE_CACHE
|
||||
add eax, cache_ide0
|
||||
|
||||
cmp [cd_appl_data], 0
|
||||
jne .ide0_appl_data
|
||||
mov eax, [cache_ide0_system_data]
|
||||
jne @f
|
||||
|
||||
mov eax, [eax+IDE_CACHE.system_data]
|
||||
ret
|
||||
.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]
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov eax, [eax+IDE_CACHE.appl_data]
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_3:
|
||||
; mov ecx,cache_max*10/100
|
||||
; mov edi,[cache_search_start]
|
||||
; 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 .ide0_appl_data
|
||||
mov edi, [cache_ide0_search_start]
|
||||
jne @f
|
||||
|
||||
mov edi, [eax+IDE_CACHE.search_start]
|
||||
pop eax
|
||||
ret
|
||||
.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]
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov edi, [eax+IDE_CACHE.appl_search_start]
|
||||
pop eax
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_4:
|
||||
; cmp edi,cache_max
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos], 1
|
||||
jne .ide1
|
||||
; 1 - IDE0 ... 12 - IDE11
|
||||
push eax
|
||||
|
||||
mov eax, [cdpos]
|
||||
dec eax
|
||||
imul eax, sizeof.IDE_CACHE
|
||||
add eax, cache_ide0
|
||||
|
||||
cmp [cd_appl_data], 0
|
||||
jne .ide0_appl_data
|
||||
cmp edi, [cache_ide0_system_sad_size]
|
||||
jne @f
|
||||
|
||||
cmp edi, [eax+IDE_CACHE.system_sad_size]
|
||||
pop eax
|
||||
ret
|
||||
.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]
|
||||
;--------------------------------------
|
||||
@@:
|
||||
cmp edi, [eax+IDE_CACHE.appl_sad_size]
|
||||
pop eax
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_5:
|
||||
; mov [cache_search_start],edi
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos], 1
|
||||
jne .ide1
|
||||
; 1 - IDE0 ... 12 - IDE11
|
||||
push eax
|
||||
|
||||
mov eax, [cdpos]
|
||||
dec eax
|
||||
imul eax, sizeof.IDE_CACHE
|
||||
add eax, cache_ide0
|
||||
|
||||
cmp [cd_appl_data], 0
|
||||
jne .ide0_appl_data
|
||||
mov [cache_ide0_search_start], edi
|
||||
jne @f
|
||||
|
||||
mov [eax+IDE_CACHE.search_start], edi
|
||||
pop eax
|
||||
ret
|
||||
.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
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov [eax+IDE_CACHE.appl_search_start], edi
|
||||
pop eax
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
;align 4
|
||||
;calculate_linear_to_real:
|
||||
; shr eax, 12
|
||||
; mov eax, [page_tabs+eax*4]
|
||||
; and eax, 0xFFFFF000
|
||||
; ret
|
||||
|
|
|
@ -22,11 +22,6 @@ ramdisk_functions:
|
|||
.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
|
||||
|
|
|
@ -394,145 +394,27 @@ sayerr:
|
|||
|
||||
push 0
|
||||
popf
|
||||
sti
|
||||
|
||||
; set up esp
|
||||
movzx esp, sp
|
||||
|
||||
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
|
||||
|
||||
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}
|
||||
xor cx, cx
|
||||
@@:
|
||||
in al, 64h
|
||||
test al, 2
|
||||
loopnz @b
|
||||
|
||||
mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование
|
||||
out 0x60, al
|
||||
xor cx, cx
|
||||
wait_loop: ; variant 2
|
||||
; reading state of port of 8042 controller
|
||||
@@:
|
||||
in al, 64h
|
||||
and al, 00000010b ; ready flag
|
||||
; wait until 8042 controller is ready
|
||||
loopnz wait_loop
|
||||
test al, 1
|
||||
loopz @b
|
||||
in al, 0x60
|
||||
|
||||
;;;/diamond today 5.02.2008
|
||||
; set keyboard typematic rate & delay
|
||||
|
@ -541,16 +423,19 @@ wait_loop: ; variant 2
|
|||
xor cx, cx
|
||||
@@:
|
||||
in al, 64h
|
||||
test al, 2
|
||||
loopnz @b
|
||||
test al, 1
|
||||
loopz @b
|
||||
in al, 0x60
|
||||
mov al, 0
|
||||
out 0x60, al
|
||||
xor cx, cx
|
||||
@@:
|
||||
in al, 64h
|
||||
test al, 2
|
||||
loopnz @b
|
||||
test al, 1
|
||||
loopz @b
|
||||
in al, 0x60
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
sti
|
||||
; --------------- APM ---------------------
|
||||
and word [es:BOOT_APM_VERSION], 0 ; ver = 0.0 (APM not found)
|
||||
mov ax, 0x5300
|
||||
|
|
|
@ -55,7 +55,7 @@ boot_dev db 0 ; 0=floppy, 1=hd
|
|||
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 " before automatical continuation",13,10,0
|
||||
db " to continue automatically",13,10,0
|
||||
current_cfg_msg db "Current settings:",13,10,0
|
||||
curvideo_msg db " [a] Videomode: ",0
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -221,11 +221,13 @@ calc_vmodes_table:
|
|||
cmp [es:mi.BitsPerPixel], 32 ;It show only videomodes to have support 24 and 32 bpp
|
||||
jb @f
|
||||
|
||||
; cmp [es:mi.BitsPerPixel],16
|
||||
; jne .l0
|
||||
; cmp [es:mi.GreenMaskSize],5
|
||||
; jne .l0
|
||||
; 16 bpp might actually be 15 bpp
|
||||
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:
|
||||
|
@ -368,6 +370,8 @@ if defined extended_primary_loader
|
|||
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
|
||||
|
@ -392,7 +396,8 @@ end if
|
|||
; 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
|
||||
|
@ -411,6 +416,8 @@ end if
|
|||
call .loops
|
||||
test ax, ax
|
||||
jz .ok_found_mode
|
||||
sub cx, 8
|
||||
jnz .find_mode
|
||||
|
||||
mov si, modes_table
|
||||
if ~ defined extended_primary_loader
|
||||
|
@ -474,18 +481,15 @@ end if
|
|||
jne .next
|
||||
cmp bx, word [es:si+2]
|
||||
jne .next
|
||||
cmp word [es:si+8], 32
|
||||
je .ok
|
||||
cmp word [es:si+8], 24
|
||||
je .ok
|
||||
cmp cx, word [es:si+8]
|
||||
jne .next
|
||||
xor ax, ax
|
||||
ret
|
||||
.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
|
||||
|
|
|
@ -9,10 +9,10 @@ $Revision$
|
|||
|
||||
|
||||
read_ramdisk:
|
||||
; READ RAMDISK IMAGE FROM HD
|
||||
; READ RAMDISK IMAGE FROM HD (only for IDE0, IDE1, IDE2, IDE3)
|
||||
|
||||
cmp [boot_dev+OS_BASE+0x10000], 1
|
||||
jne no_sys_on_hd
|
||||
jne no_sys_on_hd.1
|
||||
|
||||
xor ebp, ebp
|
||||
.hd_loop:
|
||||
|
@ -69,9 +69,19 @@ read_ramdisk:
|
|||
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:
|
||||
|
@ -79,7 +89,7 @@ read_image_fsinfo:
|
|||
dq 0 ; offset: zero
|
||||
dd 1474560 ; size
|
||||
dd RAMDISK ; buffer
|
||||
db '/hd'
|
||||
.name db '/hd'
|
||||
.name_digit db '0'
|
||||
db '/'
|
||||
.partition:
|
||||
|
@ -99,6 +109,8 @@ read_image:
|
|||
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
|
||||
|
|
|
@ -13,8 +13,24 @@
|
|||
|
||||
$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
|
||||
|
@ -166,7 +182,7 @@ restart_kernel_4000:
|
|||
pop es
|
||||
mov cx, 0x8000
|
||||
push cx
|
||||
push 0x7000
|
||||
push 0x7100
|
||||
pop ds
|
||||
xor si, si
|
||||
xor di, di
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
@echo off
|
||||
cls
|
||||
set languages=en ru ge et sp
|
||||
set drivers=com_mouse emu10k1x fm801 infinity sis sound viasound vt823x
|
||||
set targets=all kernel drivers clean
|
||||
set targets=kernel clean
|
||||
|
||||
call :Check_Target %1
|
||||
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2
|
||||
for %%a in (kernel) do if %%a==%target% call :Check_Lang %2
|
||||
call :Target_%target%
|
||||
|
||||
if ERRORLEVEL 0 goto Exit_OK
|
||||
|
@ -56,51 +55,6 @@ goto :eof
|
|||
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
|
||||
|
@ -114,14 +68,6 @@ echo.
|
|||
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
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
; =============================================================================
|
||||
; Version of all structures related to host controllers.
|
||||
; Must be the same in kernel and *hci-drivers.
|
||||
USBHC_VERSION = 1
|
||||
USBHC_VERSION = 2
|
||||
|
||||
; 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,6 +46,7 @@ USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer
|
|||
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
|
||||
|
@ -63,6 +64,9 @@ USB_FLAG_CAN_FREE = 2
|
|||
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
|
||||
|
||||
; =============================================================================
|
||||
|
@ -136,6 +140,14 @@ NewDevice dd ?
|
|||
; 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
|
||||
|
@ -307,6 +319,8 @@ NextVirt dd ?
|
|||
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
|
||||
|
@ -427,6 +441,8 @@ DeviceDescrSize db ?
|
|||
; 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 ?
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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.
|
||||
|
||||
|
@ -114,7 +124,7 @@ proc get_phys_addr
|
|||
ret
|
||||
endp
|
||||
|
||||
; Put the given control pipe in the wait list;
|
||||
; Put the given control/bulk 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.
|
||||
|
@ -128,6 +138,17 @@ proc usb_subscribe_control
|
|||
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.
|
||||
|
@ -254,13 +275,18 @@ proc usb_process_one_wait_list
|
|||
mov [esi+usb_controller.WaitPipeListAsync+edx], ebx
|
||||
jmp .continue
|
||||
.process:
|
||||
; 7. Call the handler depending on USB_FLAG_CLOSED.
|
||||
; 7. Call the handler depending on USB_FLAG_CLOSED and USB_FLAG_DISABLED.
|
||||
or [ebx+usb_pipe.NextWait], -1
|
||||
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED
|
||||
jz .nodisconnect
|
||||
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.
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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.
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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.
|
||||
|
||||
|
@ -55,7 +65,7 @@ proc usb_init
|
|||
mov esi, pcidev_list
|
||||
push 0
|
||||
.kickoff:
|
||||
mov esi, [esi+PCIDEV.list.next]
|
||||
mov esi, [esi+PCIDEV.fd]
|
||||
cmp esi, pcidev_list
|
||||
jz .done_kickoff
|
||||
cmp word [esi+PCIDEV.class+1], 0x0C03
|
||||
|
@ -108,7 +118,7 @@ proc usb_init
|
|||
; for all EHCI controllers.
|
||||
mov eax, pcidev_list
|
||||
.scan_ehci:
|
||||
mov eax, [eax+PCIDEV.list.next]
|
||||
mov eax, [eax+PCIDEV.fd]
|
||||
cmp eax, pcidev_list
|
||||
jz .done_ehci
|
||||
cmp [eax+PCIDEV.class], 0x0C0320
|
||||
|
@ -120,7 +130,7 @@ proc usb_init
|
|||
; for all UHCI and OHCI controllers.
|
||||
mov eax, pcidev_list
|
||||
.scan_usb1:
|
||||
mov eax, [eax+PCIDEV.list.next]
|
||||
mov eax, [eax+PCIDEV.fd]
|
||||
cmp eax, pcidev_list
|
||||
jz .done_usb1
|
||||
cmp [eax+PCIDEV.class], 0x0C0300
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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:
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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
|
||||
|
@ -13,6 +23,11 @@ else
|
|||
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
|
||||
|
@ -238,8 +253,17 @@ proc usb_close_pipe_nolock
|
|||
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
|
||||
|
@ -262,36 +286,66 @@ proc usb_close_pipe_nolock
|
|||
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
|
||||
proc usb_pipe_closed
|
||||
push edi
|
||||
mov edi, [esi+usb_controller.HardwareFunc]
|
||||
; 1. Loop over all transfers, calling the driver with USB_STATUS_CLOSED
|
||||
; and freeing all descriptors.
|
||||
; 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
|
||||
mov edx, [ebx+usb_pipe.LastTD]
|
||||
test edx, edx
|
||||
jz .no_transfer
|
||||
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
|
||||
mov eax, [edx+usb_gtd.NextVirt]
|
||||
push edx
|
||||
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
|
||||
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
|
||||
.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]
|
||||
|
@ -342,14 +396,23 @@ proc usb_pipe_closed
|
|||
dec eax
|
||||
jnz .notify_loop
|
||||
.notify_done:
|
||||
; 6. Bus address, if assigned, can now be reused.
|
||||
; 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.
|
||||
call [edi+usb_hardware_func.GetDeviceAddress]
|
||||
test eax, eax
|
||||
jz @f
|
||||
bts [esi+usb_controller.ExistingAddresses], eax
|
||||
@@:
|
||||
dbgstr 'USB device disconnected'
|
||||
; 7. All drivers have returned from disconnect callback,
|
||||
; 8. 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]
|
||||
|
@ -366,15 +429,74 @@ proc usb_pipe_closed
|
|||
.free_done:
|
||||
stdcall [edi+usb_hardware_func.FreePipe], ebx
|
||||
pop eax
|
||||
; 8. Free the usb_device_data structure.
|
||||
; 9. Free the usb_device_data structure.
|
||||
sub eax, usb_device_data.ClosedPipeList - usb_pipe.NextSibling
|
||||
call free
|
||||
; 9. Return.
|
||||
; 10. 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
|
||||
|
@ -508,6 +630,69 @@ endl
|
|||
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
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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),
|
||||
|
@ -33,6 +43,19 @@ USB_INTERFACE_POWER_DESCR = 8
|
|||
; 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 =================================
|
||||
; =============================================================================
|
||||
|
@ -179,21 +202,36 @@ ends
|
|||
; out: eax = 0 <=> failed, the caller should disable the port.
|
||||
proc usb_new_device
|
||||
push ebx edi ; save used registers to be stdcall
|
||||
; 1. Allocate resources. Any device uses the following resources:
|
||||
; 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:
|
||||
; - device address in the bus
|
||||
; - memory for device data
|
||||
; - pipe for zero endpoint
|
||||
; 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.
|
||||
; 1a. Allocate a bus address.
|
||||
; 2a. Allocate a bus address.
|
||||
push ecx
|
||||
call usb_set_address_request
|
||||
pop ecx
|
||||
; 1b. If failed, just return zero.
|
||||
; 2b. If failed, just return zero.
|
||||
test eax, eax
|
||||
jz .nothing
|
||||
; 1c. Allocate memory for device data.
|
||||
; 2c. 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.
|
||||
|
@ -201,10 +239,10 @@ proc usb_new_device
|
|||
push ecx
|
||||
call malloc
|
||||
pop ecx
|
||||
; 1d. If failed, free the bus address and return zero.
|
||||
; 2d. If failed, free the bus address and return zero.
|
||||
test eax, eax
|
||||
jz .nomemory
|
||||
; 1e. Open pipe for endpoint zero.
|
||||
; 2e. 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.
|
||||
|
@ -227,12 +265,14 @@ proc usb_new_device
|
|||
; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes.
|
||||
xchg eax, ebx
|
||||
pop eax
|
||||
; 1f. If failed, free the memory, the bus address and return zero.
|
||||
; 2f. If failed, free the memory, the bus address and return zero.
|
||||
test ebx, ebx
|
||||
jz .freememory
|
||||
; 2. Store pointer to device data in the pipe structure.
|
||||
; 3. Store pointer to device data in the pipe structure.
|
||||
mov [ebx+usb_pipe.DeviceData], eax
|
||||
; 3. Init device data, using usb_controller.Resetting* variables.
|
||||
; 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
|
||||
mov [eax+usb_device_data.TTHub], edi
|
||||
mov [eax+usb_device_data.TTPort], 0
|
||||
mov [eax+usb_device_data.NumInterfaces], edi
|
||||
|
@ -268,7 +308,7 @@ proc usb_new_device
|
|||
mov [eax+usb_device_data.Port], cl
|
||||
mov edx, [esi+usb_controller.ResettingHub]
|
||||
mov [eax+usb_device_data.Hub], edx
|
||||
; 4. Store pointer to the config pipe in the hub data.
|
||||
; 5. 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.
|
||||
|
@ -281,16 +321,29 @@ proc usb_new_device
|
|||
mov [esi+usb_controller.DevicesByPort+ecx*4], ebx
|
||||
@@:
|
||||
call usb_reinit_pipe_list
|
||||
; 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.
|
||||
; 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.
|
||||
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:
|
||||
; 6. Return.
|
||||
; 7. Return.
|
||||
pop edi ebx ; restore used registers to be stdcall
|
||||
ret
|
||||
; Handlers of failures in steps 1b, 1d, 1f.
|
||||
; Handlers of failures in steps 2b, 2d, 2f.
|
||||
.freememory:
|
||||
call free
|
||||
jmp .freeaddr
|
||||
|
@ -349,16 +402,23 @@ endp
|
|||
; 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]
|
||||
; 1. Check whether the device has accepted new address. If so, proceed to 2.
|
||||
; Otherwise, go to 3.
|
||||
; 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
|
||||
cmp [status], 0
|
||||
jnz .error
|
||||
; 2. Address accepted.
|
||||
; 2a. The controller-specific structure for the control pipe still uses
|
||||
; 3. Address accepted.
|
||||
; 3a. 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,
|
||||
|
@ -367,25 +427,49 @@ proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, l
|
|||
; be safe to continue.
|
||||
; dbgstr 'address set in device'
|
||||
call [eax+usb_hardware_func.SetDeviceAddress]
|
||||
; 2b. If the port is in non-root hub, clear 'reset in progress' flag.
|
||||
; In any case, proceed to 4.
|
||||
; 3b. If the port is in non-root hub, clear 'reset in progress' flag.
|
||||
; In any case, proceed to 6.
|
||||
mov eax, [esi+usb_controller.ResettingHub]
|
||||
test eax, eax
|
||||
jz .return
|
||||
and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS
|
||||
.return:
|
||||
; 4. Address configuration done, we can proceed with other ports.
|
||||
; 6. 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:
|
||||
; 3. Device error: device not responding, disconnect etc.
|
||||
; 5. Device error: device not responding, disconnect etc.
|
||||
DEBUGF 1,'K : error %d in SET_ADDRESS, USB device disabled\n',[status]
|
||||
; 3a. The address has not been accepted. Mark it as free.
|
||||
; 5a. The address has not been accepted. Mark it as free.
|
||||
bts dword [esi+usb_controller.ExistingAddresses], ecx
|
||||
; 3b. Disable the port with bad device.
|
||||
; 5b. 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).
|
||||
|
@ -642,7 +726,7 @@ end if
|
|||
; 3d. Free old memory.
|
||||
call free
|
||||
pop eax
|
||||
; 4. Issue control transfer GET_DESCRIPTOR(DEVICE) for full descriptor.
|
||||
; 4. Issue control transfer GET_DESCRIPTOR(CONFIGURATION) 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]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -179,8 +179,7 @@ struct TSS
|
|||
_io_map_1 rb 4096
|
||||
ends
|
||||
|
||||
PARTITION_COUNT equ 64
|
||||
DRIVE_DATA_SIZE equ (16+PARTITION_COUNT*100)
|
||||
DRIVE_DATA_SIZE equ 16
|
||||
|
||||
OS_BASE equ 0x80000000
|
||||
|
||||
|
@ -205,7 +204,7 @@ FDD_BUFF equ (OS_BASE+0x000D000) ;512
|
|||
|
||||
WIN_TEMP_XY equ (OS_BASE+0x000F300)
|
||||
KEY_COUNT equ (OS_BASE+0x000F400)
|
||||
KEY_BUFF equ (OS_BASE+0x000F401)
|
||||
KEY_BUFF equ (OS_BASE+0x000F401) ; 120*2 + 2*2 = 244 bytes, actually 255 bytes
|
||||
|
||||
BTN_COUNT equ (OS_BASE+0x000F500)
|
||||
BTN_BUFF equ (OS_BASE+0x000F501)
|
||||
|
@ -220,11 +219,7 @@ TASK_ACTIVATE equ (OS_BASE+0x000FF01)
|
|||
|
||||
TMP_STACK_TOP equ 0x006CC00
|
||||
|
||||
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)
|
||||
sys_proc equ (OS_BASE+0x006F000)
|
||||
|
||||
SLOT_BASE equ (OS_BASE+0x0080000)
|
||||
|
||||
|
@ -233,10 +228,6 @@ VGABasePtr equ (OS_BASE+0x00A0000)
|
|||
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)
|
||||
|
@ -252,7 +243,7 @@ kernel_tabs equ (page_tabs+ (OS_BASE shr 10)) ;0xFDE00000
|
|||
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;
|
||||
|
||||
|
@ -277,6 +268,8 @@ REG_EDI equ (RING0_STACK_SIZE-52)
|
|||
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
|
||||
|
@ -306,7 +299,7 @@ BOOT_DEBUG_PRINT equ 0x901E ;byte If nonzero, duplicates debug output to
|
|||
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
|
||||
;BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr ; now free and is not used
|
||||
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount
|
||||
|
||||
BOOT_APM_ENTRY equ 0x9040
|
||||
|
@ -315,12 +308,12 @@ BOOT_APM_FLAGS equ 0x9046 ;unused
|
|||
BOOT_APM_CODE_32 equ 0x9050
|
||||
BOOT_APM_CODE_16 equ 0x9052
|
||||
BOOT_APM_DATA_16 equ 0x9054
|
||||
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
|
||||
;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
|
||||
|
||||
TMP_FILE_NAME equ 0
|
||||
TMP_CMD_LINE equ 1024
|
||||
|
@ -437,7 +430,7 @@ struct display_t
|
|||
y dd ?
|
||||
width dd ?
|
||||
height dd ?
|
||||
bpp dd ?
|
||||
bits_per_pixel dd ?
|
||||
vrefresh dd ?
|
||||
pitch dd ?
|
||||
lfb dd ?
|
||||
|
@ -461,6 +454,8 @@ struct display_t
|
|||
mask_seqno dd ?
|
||||
check_mouse dd ?
|
||||
check_m_pixel dd ?
|
||||
|
||||
bytes_per_pixel dd ?
|
||||
ends
|
||||
|
||||
struct BOOT_DATA
|
||||
|
@ -507,14 +502,13 @@ struct MUTEX
|
|||
ends
|
||||
|
||||
struct PCIDEV
|
||||
list LHEAD
|
||||
vid_did dd ?
|
||||
bk dd ?
|
||||
fd dd ?
|
||||
vendor_device_id dd ?
|
||||
class dd ?
|
||||
svid_sdid dd ?
|
||||
devfn db ?
|
||||
bus db ?
|
||||
irq_line db ?
|
||||
rb 1
|
||||
rb 2
|
||||
owner dd ? ; pointer to SRV or 0
|
||||
ends
|
||||
|
||||
|
@ -625,6 +619,28 @@ struct COFF_SYM
|
|||
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 ?
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4850 $
|
||||
|
||||
|
||||
iglobal
|
||||
IRQ_COUNT dd 24
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4850 $
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
sys_clipboard:
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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
|
||||
|
|
|
@ -136,9 +136,18 @@ debug_getcontext:
|
|||
; ecx=pid
|
||||
; edx=sizeof(CONTEXT)
|
||||
; esi->CONTEXT
|
||||
; destroys eax,ecx,edx,esi,edi
|
||||
cmp edx, 28h
|
||||
jnz .ret
|
||||
; 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:
|
||||
; push ecx
|
||||
; mov ecx, esi
|
||||
call check_region
|
||||
|
@ -147,8 +156,15 @@ debug_getcontext:
|
|||
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*8+SLOT_BASE+APPDATA.pl0_stack]
|
||||
mov eax, [eax+SLOT_BASE+APPDATA.pl0_stack]
|
||||
lea esi, [eax+RING0_STACK_SIZE]
|
||||
|
||||
.ring0:
|
||||
|
@ -178,6 +194,29 @@ debug_getcontext:
|
|||
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
|
||||
|
|
|
@ -123,13 +123,13 @@ proc get_service stdcall, sz_name:dword
|
|||
|
||||
stdcall strncmp, edx, [sz_name], 16
|
||||
test eax, eax
|
||||
je .ok
|
||||
mov eax, edx
|
||||
je .nothing
|
||||
|
||||
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,12 +150,6 @@ proc get_service stdcall, sz_name:dword
|
|||
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
|
||||
|
@ -794,177 +788,6 @@ proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
|
|||
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:
|
||||
|
@ -1009,10 +832,9 @@ proc load_library stdcall, file_name:dword
|
|||
; ignore timestamp
|
||||
cli
|
||||
|
||||
mov esi, [CURRENT_TASK]
|
||||
shl esi, 8
|
||||
mov esi, [current_process]
|
||||
lea edi, [fullname]
|
||||
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
|
||||
mov ebx, [esi+PROC.dlls_list_ptr]
|
||||
test ebx, ebx
|
||||
jz .not_in_process
|
||||
mov esi, [ebx+HDLL.fd]
|
||||
|
@ -1372,28 +1194,21 @@ endp
|
|||
; out: eax = APPDATA.dlls_list_ptr if all is OK,
|
||||
; NULL if memory allocation failed
|
||||
init_dlls_in_thread:
|
||||
mov ebx, [current_slot]
|
||||
mov eax, [ebx+APPDATA.dlls_list_ptr]
|
||||
mov ebx, [current_process]
|
||||
mov eax, [ebx+PROC.dlls_list_ptr]
|
||||
test eax, eax
|
||||
jnz .ret
|
||||
push [ebx+APPDATA.dir_table]
|
||||
|
||||
mov eax, 8
|
||||
call malloc
|
||||
pop edx
|
||||
call malloc ; FIXME
|
||||
test eax, eax
|
||||
jz .ret
|
||||
|
||||
mov [eax], eax
|
||||
mov [eax+4], 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
|
||||
|
||||
mov ebx, [current_process]
|
||||
mov [ebx+PROC.dlls_list_ptr], eax
|
||||
.ret:
|
||||
ret
|
||||
|
||||
|
@ -1414,59 +1229,10 @@ dereference_dll:
|
|||
|
||||
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]
|
||||
|
|
|
@ -7,11 +7,6 @@
|
|||
|
||||
$Revision$
|
||||
|
||||
iglobal
|
||||
szKernel db 'KERNEL', 0
|
||||
szVersion db 'version',0
|
||||
endg
|
||||
|
||||
align 4
|
||||
__exports:
|
||||
export 'KERNEL', \
|
||||
|
@ -48,6 +43,7 @@ __exports:
|
|||
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
|
||||
|
@ -94,6 +90,7 @@ __exports:
|
|||
load_cursor, 'LoadCursor', \ ;stdcall
|
||||
\
|
||||
get_curr_task, 'GetCurrentTask', \
|
||||
change_task, 'ChangeTask', \
|
||||
load_file, 'LoadFile', \ ;retval eax, ebx
|
||||
delay_ms, 'Sleep', \
|
||||
\
|
||||
|
@ -105,6 +102,7 @@ __exports:
|
|||
strrchr, 'strrchr', \
|
||||
\
|
||||
timer_hs, 'TimerHS', \
|
||||
timer_hs, 'TimerHs', \ ; shit happens
|
||||
cancel_timer_hs, 'CancelTimerHS', \
|
||||
\
|
||||
reg_usb_driver, 'RegUSBDriver', \
|
||||
|
@ -120,6 +118,8 @@ __exports:
|
|||
NET_ptr_to_num, 'NetPtrToNum', \
|
||||
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
|
||||
|
|
|
@ -129,15 +129,11 @@ proc init_kernel_heap
|
|||
loop @B
|
||||
|
||||
stdcall alloc_pages, dword 32
|
||||
|
||||
or eax, PG_SW
|
||||
mov ebx, HEAP_BASE
|
||||
mov ecx, 32
|
||||
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
|
||||
call commit_pages
|
||||
|
||||
mov edi, HEAP_BASE ;descriptors
|
||||
mov ebx, HEAP_BASE+sizeof.MEM_BLOCK ;free space
|
||||
|
@ -480,46 +476,39 @@ proc kernel_alloc stdcall, size:dword
|
|||
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 ecx, 3
|
||||
jz .next
|
||||
shr ebx, 3
|
||||
jz .tail
|
||||
|
||||
and ebx, not 7
|
||||
push ebx
|
||||
shl ebx, 3
|
||||
stdcall alloc_pages, ebx
|
||||
pop ecx ; yes ecx!!!
|
||||
and eax, eax
|
||||
test eax, eax
|
||||
jz .err
|
||||
|
||||
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
|
||||
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
|
||||
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 ecx
|
||||
dec ebx
|
||||
jnz @B
|
||||
.end:
|
||||
mov eax, [lin_addr]
|
||||
|
@ -569,33 +558,36 @@ restore block_base
|
|||
restore block_size
|
||||
restore block_flags
|
||||
|
||||
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;; USER HEAP ;;;;;;;;;;;;;;;;;
|
||||
|
||||
HEAP_TOP equ 0x80000000
|
||||
|
||||
align 4
|
||||
proc init_heap
|
||||
|
||||
mov ebx, [current_slot]
|
||||
mov eax, [ebx+APPDATA.heap_top]
|
||||
mov ebx, [current_process]
|
||||
mov eax, [ebx+PROC.heap_top]
|
||||
test eax, eax
|
||||
jz @F
|
||||
sub eax, [ebx+APPDATA.heap_base]
|
||||
sub eax, 4096
|
||||
sub eax, [ebx+PROC.heap_base]
|
||||
sub eax, PAGE_SIZE
|
||||
ret
|
||||
@@:
|
||||
mov esi, [ebx+APPDATA.mem_size]
|
||||
lea ecx, [ebx+PROC.heap_lock]
|
||||
call mutex_init
|
||||
|
||||
mov esi, [ebx+PROC.mem_used]
|
||||
add esi, 4095
|
||||
and esi, not 4095
|
||||
mov [ebx+APPDATA.mem_size], esi
|
||||
mov [ebx+PROC.mem_used], esi
|
||||
mov eax, HEAP_TOP
|
||||
mov [ebx+APPDATA.heap_base], esi
|
||||
mov [ebx+APPDATA.heap_top], eax
|
||||
mov [ebx+PROC.heap_base], esi
|
||||
mov [ebx+PROC.heap_top], eax
|
||||
|
||||
sub eax, esi
|
||||
shr esi, 10
|
||||
mov ecx, eax
|
||||
sub eax, 4096
|
||||
sub eax, PAGE_SIZE
|
||||
or ecx, FREE_BLOCK
|
||||
mov [page_tabs+esi], ecx
|
||||
ret
|
||||
|
@ -608,25 +600,28 @@ proc user_alloc stdcall, alloc_size:dword
|
|||
push esi
|
||||
push edi
|
||||
|
||||
mov ebx, [current_process]
|
||||
lea ecx, [ebx+PROC.heap_lock]
|
||||
call mutex_lock
|
||||
|
||||
mov ecx, [alloc_size]
|
||||
add ecx, (4095+4096)
|
||||
add ecx, (4095+PAGE_SIZE)
|
||||
and ecx, not 4095
|
||||
|
||||
mov ebx, [current_slot]
|
||||
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base
|
||||
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top
|
||||
l_0:
|
||||
mov esi, dword [ebx+PROC.heap_base] ; heap_base
|
||||
mov edi, dword [ebx+PROC.heap_top] ; heap_top
|
||||
.scan:
|
||||
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]
|
||||
|
@ -648,12 +643,14 @@ l_0:
|
|||
jnz @B
|
||||
.no:
|
||||
|
||||
mov edx, [current_slot]
|
||||
mov edx, [current_process]
|
||||
mov ebx, [alloc_size]
|
||||
add ebx, 0xFFF
|
||||
and ebx, not 0xFFF
|
||||
add ebx, [edx+APPDATA.mem_size]
|
||||
call update_mem_size
|
||||
add [edx+PROC.mem_used], ebx
|
||||
|
||||
lea ecx, [edx+PROC.heap_lock]
|
||||
call mutex_unlock
|
||||
|
||||
lea eax, [esi+4096]
|
||||
|
||||
|
@ -661,15 +658,19 @@ l_0:
|
|||
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 l_0
|
||||
m_exit:
|
||||
jmp .scan
|
||||
.m_exit:
|
||||
mov ecx, [current_process]
|
||||
lea ecx, [ecx+PROC.heap_lock]
|
||||
call mutex_unlock
|
||||
|
||||
xor eax, eax
|
||||
pop edi
|
||||
pop esi
|
||||
|
@ -684,14 +685,17 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
|
|||
push esi
|
||||
push edi
|
||||
|
||||
mov ebx, [current_slot]
|
||||
mov ebx, [current_process]
|
||||
lea ecx, [ebx+PROC.heap_lock]
|
||||
call mutex_lock
|
||||
|
||||
mov edx, [address]
|
||||
and edx, not 0xFFF
|
||||
mov [address], edx
|
||||
sub edx, 0x1000
|
||||
jb .error
|
||||
mov esi, [ebx+APPDATA.heap_base]
|
||||
mov edi, [ebx+APPDATA.heap_top]
|
||||
mov esi, [ebx+PROC.heap_base]
|
||||
mov edi, [ebx+PROC.heap_top]
|
||||
cmp edx, esi
|
||||
jb .error
|
||||
.scan:
|
||||
|
@ -708,6 +712,10 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
|
|||
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
|
||||
|
@ -759,13 +767,14 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
|
|||
mov [page_tabs+ebx*4], ecx
|
||||
|
||||
.nothird:
|
||||
|
||||
mov edx, [current_slot]
|
||||
mov edx, [current_process]
|
||||
mov ebx, [alloc_size]
|
||||
add ebx, 0xFFF
|
||||
and ebx, not 0xFFF
|
||||
add ebx, [edx+APPDATA.mem_size]
|
||||
call update_mem_size
|
||||
add [edx+PROC.mem_used], ebx
|
||||
|
||||
lea ecx, [edx+PROC.heap_lock]
|
||||
call mutex_unlock
|
||||
|
||||
mov eax, [address]
|
||||
|
||||
|
@ -782,10 +791,14 @@ proc user_free stdcall, base:dword
|
|||
|
||||
mov esi, [base]
|
||||
test esi, esi
|
||||
jz .exit
|
||||
jz .fail
|
||||
|
||||
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]
|
||||
|
@ -821,25 +834,30 @@ proc user_free stdcall, base:dword
|
|||
.released:
|
||||
push edi
|
||||
|
||||
mov edx, [current_slot]
|
||||
mov esi, dword [edx+APPDATA.heap_base]
|
||||
mov edi, dword [edx+APPDATA.heap_top]
|
||||
sub ebx, [edx+APPDATA.mem_size]
|
||||
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]
|
||||
neg ebx
|
||||
call update_mem_size
|
||||
mov [edx+PROC.mem_used], ebx
|
||||
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
|
||||
|
@ -968,6 +986,13 @@ user_realloc:
|
|||
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]
|
||||
|
@ -975,6 +1000,10 @@ user_realloc:
|
|||
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
|
||||
|
@ -1009,16 +1038,16 @@ user_realloc:
|
|||
jnz .nofreeall
|
||||
mov eax, [page_tabs+ecx*4]
|
||||
and eax, not 0xFFF
|
||||
mov edx, [current_slot]
|
||||
mov ebx, [APPDATA.mem_size+edx]
|
||||
mov edx, [current_process]
|
||||
mov ebx, [edx+PROC.mem_used]
|
||||
sub ebx, eax
|
||||
add ebx, 0x1000
|
||||
or al, FREE_BLOCK
|
||||
mov [page_tabs+ecx*4], eax
|
||||
push esi edi
|
||||
mov esi, [APPDATA.heap_base+edx]
|
||||
mov edi, [APPDATA.heap_top+edx]
|
||||
call update_mem_size
|
||||
mov esi, [edx+PROC.heap_base]
|
||||
mov edi, [edx+PROC.heap_top]
|
||||
mov [edx+PROC.mem_used], ebx
|
||||
call user_normalize
|
||||
pop edi esi
|
||||
jmp .ret0 ; all freed
|
||||
|
@ -1030,11 +1059,11 @@ user_realloc:
|
|||
shr ebx, 12
|
||||
sub ebx, edx
|
||||
push ebx ecx edx
|
||||
mov edx, [current_slot]
|
||||
mov edx, [current_process]
|
||||
shl ebx, 12
|
||||
sub ebx, [APPDATA.mem_size+edx]
|
||||
sub ebx, [edx+PROC.mem_used]
|
||||
neg ebx
|
||||
call update_mem_size
|
||||
mov [edx+PROC.mem_used], ebx
|
||||
pop edx ecx ebx
|
||||
lea eax, [ecx+1]
|
||||
shl eax, 12
|
||||
|
@ -1044,8 +1073,8 @@ user_realloc:
|
|||
shl ebx, 12
|
||||
jz .ret
|
||||
push esi
|
||||
mov esi, [current_slot]
|
||||
mov esi, [APPDATA.heap_top+esi]
|
||||
mov esi, [current_process]
|
||||
mov esi, [esi+PROC.heap_top]
|
||||
shr esi, 12
|
||||
@@:
|
||||
cmp edx, esi
|
||||
|
@ -1064,12 +1093,16 @@ user_realloc:
|
|||
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_slot]
|
||||
mov eax, [APPDATA.heap_top+eax]
|
||||
mov eax, [current_process]
|
||||
mov eax, [eax+PROC.heap_top]
|
||||
shr eax, 12
|
||||
cmp edx, eax
|
||||
jae .cant_inplace
|
||||
|
@ -1101,17 +1134,21 @@ user_realloc:
|
|||
cld
|
||||
rep stosd
|
||||
pop edi
|
||||
mov edx, [current_slot]
|
||||
mov edx, [current_process]
|
||||
shl ebx, 12
|
||||
add ebx, [APPDATA.mem_size+edx]
|
||||
call update_mem_size
|
||||
add [edx+PROC.mem_used], ebx
|
||||
|
||||
mov ecx, [current_process]
|
||||
lea ecx, [ecx+PROC.heap_lock]
|
||||
call mutex_unlock
|
||||
pop eax edx ecx
|
||||
ret
|
||||
|
||||
.cant_inplace:
|
||||
push esi edi
|
||||
mov eax, [current_slot]
|
||||
mov esi, [APPDATA.heap_base+eax]
|
||||
mov edi, [APPDATA.heap_top+eax]
|
||||
mov eax, [current_process]
|
||||
mov esi, [eax+PROC.heap_base]
|
||||
mov edi, [eax+PROC.heap_top]
|
||||
shr esi, 12
|
||||
shr edi, 12
|
||||
sub ebx, ecx
|
||||
|
@ -1174,58 +1211,25 @@ user_realloc:
|
|||
jnz @b
|
||||
.no:
|
||||
push ebx
|
||||
mov edx, [current_slot]
|
||||
mov edx, [current_process]
|
||||
shl ebx, 12
|
||||
add ebx, [APPDATA.mem_size+edx]
|
||||
call update_mem_size
|
||||
add [edx+PROC.mem_used], ebx
|
||||
pop ebx
|
||||
@@:
|
||||
mov dword [page_tabs+esi*4], 2
|
||||
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
|
||||
|
||||
end if
|
||||
|
||||
|
||||
;;;;;;;;;;;;;; SHARED ;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;; SHARED MEMORY ;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
; param
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4850 $
|
||||
|
||||
|
||||
IRQ_RESERVED equ 24
|
||||
|
||||
IRQ_POOL_SIZE equ 48
|
||||
|
|
|
@ -123,19 +123,19 @@ proc alloc_pages stdcall, count:dword
|
|||
endp
|
||||
|
||||
align 4
|
||||
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
|
||||
;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
|
||||
map_page:
|
||||
push ebx
|
||||
mov eax, [phis_addr]
|
||||
mov eax, [esp+12] ; phis_addr
|
||||
and eax, not 0xFFF
|
||||
or eax, [flags]
|
||||
mov ebx, [lin_addr]
|
||||
or eax, [esp+16] ; flags
|
||||
mov ebx, [esp+8] ; lin_addr
|
||||
shr ebx, 12
|
||||
mov [page_tabs+ebx*4], eax
|
||||
mov eax, [lin_addr]
|
||||
invlpg [eax]
|
||||
mov eax, [esp+8] ; lin_addr
|
||||
pop ebx
|
||||
ret
|
||||
endp
|
||||
invlpg [eax]
|
||||
ret 12
|
||||
|
||||
align 4
|
||||
map_space: ;not implemented
|
||||
|
@ -350,9 +350,64 @@ proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
|
|||
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
|
||||
init_LFB:
|
||||
xchg bx, bx
|
||||
proc init_LFB
|
||||
locals
|
||||
pg_count dd ?
|
||||
endl
|
||||
|
||||
cmp dword [LFBAddress], -1
|
||||
jne @f
|
||||
|
@ -381,33 +436,61 @@ init_LFB:
|
|||
@@:
|
||||
call init_mtrr
|
||||
|
||||
xor edx, edx
|
||||
mov eax, [LFBAddress]
|
||||
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
|
||||
|
||||
bt [cpu_caps], CAPS_PGE
|
||||
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
|
||||
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
|
||||
|
||||
.map_pte:
|
||||
.map_page_tables:
|
||||
|
||||
@@:
|
||||
call alloc_page
|
||||
stdcall map_page_table, edx, eax
|
||||
add edx, 0x00400000
|
||||
dec edi
|
||||
jnz @B
|
||||
|
||||
mov eax, [LFBAddress]
|
||||
mov edi, page_tabs + (LFB_BASE shr 10)
|
||||
or eax, PG_UW
|
||||
mov ecx, [pg_count]
|
||||
cld
|
||||
@@:
|
||||
stosd
|
||||
add eax, 0x1000
|
||||
loop .map_pte
|
||||
dec ecx
|
||||
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]
|
||||
|
||||
.map_pde:
|
||||
stosd
|
||||
add eax, 0x1000
|
||||
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
|
||||
|
@ -417,7 +500,9 @@ proc new_mem_resize stdcall, new_size:dword
|
|||
push edi
|
||||
|
||||
mov edx, [current_slot]
|
||||
cmp [edx+APPDATA.heap_base], 0
|
||||
mov ebx, [edx+APPDATA.process]
|
||||
|
||||
cmp [ebx+PROC.heap_base], 0
|
||||
jne .exit
|
||||
|
||||
mov edi, [new_size]
|
||||
|
@ -425,7 +510,7 @@ proc new_mem_resize stdcall, new_size:dword
|
|||
and edi, not 4095
|
||||
mov [new_size], edi
|
||||
|
||||
mov esi, [edx+APPDATA.mem_size]
|
||||
mov esi, [ebx+PROC.mem_used]
|
||||
add esi, 4095
|
||||
and esi, not 4095
|
||||
|
||||
|
@ -460,7 +545,8 @@ proc new_mem_resize stdcall, new_size:dword
|
|||
.update_size:
|
||||
mov edx, [current_slot]
|
||||
mov ebx, [new_size]
|
||||
call update_mem_size
|
||||
mov edx, [edx+APPDATA.process]
|
||||
mov [edx+PROC.mem_used], ebx
|
||||
.exit:
|
||||
pop edi
|
||||
pop esi
|
||||
|
@ -536,38 +622,6 @@ proc new_mem_resize stdcall, new_size:dword
|
|||
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
|
||||
;
|
||||
|
@ -624,11 +678,6 @@ end if
|
|||
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 ;Страница присутствует
|
||||
|
@ -668,9 +717,8 @@ end if
|
|||
; 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_TASK]
|
||||
shl eax, 8
|
||||
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
|
||||
mov eax, [current_process]
|
||||
mov eax, [eax+PROC.dlls_list_ptr]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
mov esi, [eax+HDLL.fd]
|
||||
|
@ -746,120 +794,129 @@ end if
|
|||
endp
|
||||
|
||||
; returns number of mapped bytes
|
||||
proc map_mem stdcall, lin_addr:dword,slot:dword,\
|
||||
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
|
||||
ofs:dword,buf_size:dword,req_access:dword
|
||||
push 0 ; initialize number of mapped bytes
|
||||
locals
|
||||
count dd ?
|
||||
process dd ?
|
||||
endl
|
||||
|
||||
mov [count], 0
|
||||
cmp [buf_size], 0
|
||||
jz .exit
|
||||
|
||||
mov eax, [slot]
|
||||
shl eax, 8
|
||||
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
|
||||
and eax, 0xFFFFF000
|
||||
mov eax, [SLOT_BASE+eax+APPDATA.process]
|
||||
test eax, eax
|
||||
jz .exit
|
||||
|
||||
stdcall map_page, [ipc_pdir], eax, PG_UW
|
||||
mov [process], eax
|
||||
mov ebx, [ofs]
|
||||
shr ebx, 22
|
||||
mov esi, [ipc_pdir]
|
||||
mov edi, [ipc_ptab]
|
||||
mov eax, [esi+ebx*4]
|
||||
mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table
|
||||
mov esi, [ipc_ptab]
|
||||
and eax, 0xFFFFF000
|
||||
jz .exit
|
||||
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
|
||||
|
||||
stdcall map_page, esi, eax, PG_SW
|
||||
@@:
|
||||
mov edi, [lin_addr]
|
||||
and edi, 0xFFFFF000
|
||||
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 dword [ebp-4], 4096
|
||||
add [ofs], 4096
|
||||
add [count], PAGE_SIZE
|
||||
add [ofs], PAGE_SIZE
|
||||
dec ecx
|
||||
jz .exit
|
||||
add edi, 0x1000
|
||||
|
||||
add edi, PAGE_SIZE
|
||||
inc edx
|
||||
cmp edx, 0x400
|
||||
cmp edx, 1024
|
||||
jnz .map
|
||||
|
||||
inc ebx
|
||||
mov eax, [ipc_pdir]
|
||||
mov eax, [eax+ebx*4]
|
||||
mov eax, [process]
|
||||
mov eax, [eax+PROC.pdt_0+ebx*4]
|
||||
and eax, 0xFFFFF000
|
||||
jz .exit
|
||||
stdcall map_page, esi, eax, PG_UW
|
||||
|
||||
stdcall map_page, esi, eax, PG_SW
|
||||
xor edx, edx
|
||||
jmp .map
|
||||
|
||||
.exit:
|
||||
pop eax
|
||||
mov eax, [count]
|
||||
ret
|
||||
endp
|
||||
|
||||
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
|
||||
ofs:dword,buf_size:dword,req_access:dword
|
||||
push 0 ; initialize number of mapped bytes
|
||||
locals
|
||||
count dd ?
|
||||
process dd ?
|
||||
endl
|
||||
|
||||
mov [count], 0
|
||||
cmp [buf_size], 0
|
||||
jz .exit
|
||||
|
||||
mov eax, [slot]
|
||||
shl eax, 8
|
||||
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
|
||||
and eax, 0xFFFFF000
|
||||
|
||||
stdcall map_page, [proc_mem_pdir], eax, PG_UW
|
||||
mov ebx, [ofs]
|
||||
shr ebx, 22
|
||||
mov esi, [proc_mem_pdir]
|
||||
mov edi, [proc_mem_tab]
|
||||
mov eax, [esi+ebx*4]
|
||||
and eax, 0xFFFFF000
|
||||
mov eax, [SLOT_BASE+eax+APPDATA.process]
|
||||
test eax, eax
|
||||
jz .exit
|
||||
stdcall map_page, edi, eax, PG_UW
|
||||
|
||||
mov [process], eax
|
||||
mov ebx, [ofs]
|
||||
shr ebx, 22
|
||||
mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table
|
||||
mov esi, [proc_mem_tab]
|
||||
and eax, 0xFFFFF000
|
||||
jz .exit
|
||||
stdcall map_page, esi, eax, PG_SW
|
||||
@@:
|
||||
mov edi, [lin_addr]
|
||||
and edi, 0xFFFFF000
|
||||
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 dword [ebp-4], 0x1000
|
||||
add edi, 0x1000
|
||||
add [ofs], 0x1000
|
||||
inc edx
|
||||
add [count], PAGE_SIZE
|
||||
add [ofs], PAGE_SIZE
|
||||
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:
|
||||
pop eax
|
||||
mov eax, [count]
|
||||
ret
|
||||
endp
|
||||
|
||||
|
@ -905,7 +962,8 @@ proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
|
|||
push ebx ecx
|
||||
mov eax, [slot]
|
||||
shl eax, 8
|
||||
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
|
||||
mov eax, [SLOT_BASE+eax+APPDATA.process]
|
||||
mov eax, [eax+PROC.dlls_list_ptr]
|
||||
test eax, eax
|
||||
jz .no_hdll
|
||||
mov ecx, [eax+HDLL.fd]
|
||||
|
@ -992,29 +1050,6 @@ sys_IPC:
|
|||
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 ?
|
||||
|
@ -1033,7 +1068,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
|||
|
||||
mov [dst_slot], eax
|
||||
shl eax, 8
|
||||
mov edi, [eax+SLOT_BASE+0xa0] ;is ipc area defined?
|
||||
mov edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined?
|
||||
test edi, edi
|
||||
jz .no_ipc_area
|
||||
|
||||
|
@ -1041,7 +1076,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
|||
and ebx, 0xFFF
|
||||
mov [dst_offset], ebx
|
||||
|
||||
mov esi, [eax+SLOT_BASE+0xa4]
|
||||
mov esi, [eax+SLOT_BASE+APPDATA.ipc_size]
|
||||
mov [buf_size], esi
|
||||
|
||||
mov ecx, [ipc_tmp]
|
||||
|
@ -1054,7 +1089,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
|||
pop edi esi
|
||||
@@:
|
||||
mov [used_buf], ecx
|
||||
stdcall map_mem, ecx, [dst_slot], \
|
||||
stdcall map_mem_ipc, ecx, [dst_slot], \
|
||||
edi, esi, PG_SW
|
||||
|
||||
mov edi, [dst_offset]
|
||||
|
@ -1125,7 +1160,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
|
|||
.ret:
|
||||
mov eax, [used_buf]
|
||||
cmp eax, [ipc_tmp]
|
||||
jz @f
|
||||
je @f
|
||||
stdcall free_kernel_space, eax
|
||||
@@:
|
||||
pop eax
|
||||
|
@ -1329,113 +1364,6 @@ proc load_pe_driver stdcall, file:dword, cmdline:dword
|
|||
ret
|
||||
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
|
||||
|
|
|
@ -0,0 +1,881 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 5130 $
|
||||
|
||||
; Initializes MTRRs.
|
||||
proc init_mtrr
|
||||
|
||||
cmp [BOOT_VARS+BOOT_MTRR], byte 2
|
||||
je .exit
|
||||
|
||||
bt [cpu_caps], CAPS_MTRR
|
||||
jnc .exit
|
||||
|
||||
call mtrr_reconfigure
|
||||
stdcall set_mtrr, [LFBAddress], 0x1000000, MEM_WC
|
||||
|
||||
.exit:
|
||||
ret
|
||||
endp
|
||||
|
||||
; Helper procedure for mtrr_reconfigure and set_mtrr,
|
||||
; called before changes in MTRRs.
|
||||
proc mtrr_begin_change
|
||||
mov eax, cr0
|
||||
or eax, 0x60000000 ;disable caching
|
||||
mov cr0, eax
|
||||
wbinvd ;invalidate cache
|
||||
ret
|
||||
endp
|
||||
|
||||
; Helper procedure for mtrr_reconfigure and set_mtrr,
|
||||
; called after changes in MTRRs.
|
||||
proc mtrr_end_change
|
||||
wbinvd ;again invalidate
|
||||
mov eax, cr0
|
||||
and eax, not 0x60000000
|
||||
mov cr0, eax ; enable caching
|
||||
ret
|
||||
endp
|
||||
|
||||
; Some limits to number of structures located in the stack.
|
||||
MAX_USEFUL_MTRRS = 16
|
||||
MAX_RANGES = 16
|
||||
|
||||
; mtrr_reconfigure keeps a list of MEM_WB ranges.
|
||||
; This structure describes one item in the list.
|
||||
struct mtrr_range
|
||||
next dd ? ; next item
|
||||
start dq ? ; first byte
|
||||
length dq ? ; length in bytes
|
||||
ends
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
num_variable_mtrrs dd 0 ; number of variable-range MTRRs
|
||||
endg
|
||||
|
||||
; Helper procedure for MTRR initialization.
|
||||
; Takes MTRR configured by BIOS and tries to recongifure them
|
||||
; in order to allow non-UC data at top of 4G memory.
|
||||
; Example: if low part of physical memory is 3.5G = 0xE0000000 bytes wide,
|
||||
; BIOS can configure two MTRRs so that the first MTRR describes [0, 4G) as WB
|
||||
; and the second MTRR describes [3.5G, 4G) as UC;
|
||||
; WB+UC=UC, so the resulting memory map would be as needed,
|
||||
; but in this configuration our attempts to map LFB at (say) 0xE8000000 as WC
|
||||
; would be ignored, WB+UC+WC is still UC.
|
||||
; So we must keep top of 4G memory not covered by MTRRs,
|
||||
; using three WB MTRRs [0,2G) + [2G,3G) + [3G,3.5G),
|
||||
; this gives the same memory map, but allows to add further entries.
|
||||
; See mtrrtest.asm for detailed input/output from real hardware+BIOS.
|
||||
proc mtrr_reconfigure
|
||||
push ebp ; we're called from init_LFB, and it feels hurt when ebp is destroyed
|
||||
; 1. Prepare local variables.
|
||||
; 1a. Create list of MAX_RANGES free (aka not yet allocated) ranges.
|
||||
xor eax, eax
|
||||
lea ecx, [eax+MAX_RANGES]
|
||||
.init_ranges:
|
||||
sub esp, sizeof.mtrr_range - 4
|
||||
push eax
|
||||
mov eax, esp
|
||||
dec ecx
|
||||
jnz .init_ranges
|
||||
mov eax, esp
|
||||
; 1b. Fill individual local variables.
|
||||
xor edx, edx
|
||||
sub esp, MAX_USEFUL_MTRRS * 16 ; .mtrrs
|
||||
push edx ; .mtrrs_end
|
||||
push edx ; .num_used_mtrrs
|
||||
push eax ; .first_free_range
|
||||
push edx ; .first_range: no ranges yet
|
||||
mov cl, [cpu_phys_addr_width]
|
||||
or eax, -1
|
||||
shl eax, cl ; note: this uses cl&31 = cl-32, not the entire cl
|
||||
push eax ; .phys_reserved_mask
|
||||
virtual at esp
|
||||
.phys_reserved_mask dd ?
|
||||
.first_range dd ?
|
||||
.first_free_range dd ?
|
||||
.num_used_mtrrs dd ?
|
||||
.mtrrs_end dd ?
|
||||
.mtrrs rq MAX_USEFUL_MTRRS * 2
|
||||
.local_vars_size = $ - esp
|
||||
end virtual
|
||||
|
||||
; 2. Get the number of variable-range MTRRs from MTRRCAP register.
|
||||
; Abort if zero.
|
||||
mov ecx, 0xFE
|
||||
rdmsr
|
||||
test al, al
|
||||
jz .abort
|
||||
mov byte [num_variable_mtrrs], al
|
||||
; 3. Validate MTRR_DEF_TYPE register.
|
||||
mov ecx, 0x2FF
|
||||
rdmsr
|
||||
; If BIOS has not initialized variable-range MTRRs, fallback to step 7.
|
||||
test ah, 8
|
||||
jz .fill_ranges_from_memory_map
|
||||
; If the default memory type (not covered by MTRRs) is not UC,
|
||||
; then probably BIOS did something strange, so it is better to exit immediately
|
||||
; hoping for the best.
|
||||
cmp al, MEM_UC
|
||||
jnz .abort
|
||||
; 4. Validate all variable-range MTRRs
|
||||
; and copy configured MTRRs to the local array [.mtrrs].
|
||||
; 4a. Prepare for the loop over existing variable-range MTRRs.
|
||||
mov ecx, 0x200
|
||||
lea edi, [.mtrrs]
|
||||
.get_used_mtrrs_loop:
|
||||
; 4b. For every MTRR, read PHYSBASEn and PHYSMASKn.
|
||||
; In PHYSBASEn, clear upper bits and copy to ebp:ebx.
|
||||
rdmsr
|
||||
or edx, [.phys_reserved_mask]
|
||||
xor edx, [.phys_reserved_mask]
|
||||
mov ebp, edx
|
||||
mov ebx, eax
|
||||
inc ecx
|
||||
; If PHYSMASKn is not active, ignore this MTRR.
|
||||
rdmsr
|
||||
inc ecx
|
||||
test ah, 8
|
||||
jz .get_used_mtrrs_next
|
||||
; 4c. For every active MTRR, check that number of local entries is not too large.
|
||||
inc [.num_used_mtrrs]
|
||||
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
|
||||
ja .abort
|
||||
; 4d. For every active MTRR, store PHYSBASEn with upper bits cleared.
|
||||
; This contains the MTRR base and the memory type in low byte.
|
||||
mov [edi], ebx
|
||||
mov [edi+4], ebp
|
||||
; 4e. For every active MTRR, check that the range is continuous:
|
||||
; PHYSMASKn with upper bits set must be negated power of two, and
|
||||
; low bits of PHYSBASEn must be zeroes:
|
||||
; PHYSMASKn = 1...10...0,
|
||||
; PHYSBASEn = x...x0...0,
|
||||
; this defines a continuous range from x...x0...0 to x...x1...1,
|
||||
; length = 10...0 = negated PHYSMASKn.
|
||||
; Store length in the local array.
|
||||
and eax, not 0xFFF
|
||||
or edx, [.phys_reserved_mask]
|
||||
mov dword [edi+8], 0
|
||||
mov dword [edi+12], 0
|
||||
sub [edi+8], eax
|
||||
sbb [edi+12], edx
|
||||
; (x and -x) is the maximum power of two that divides x.
|
||||
; Condition for powers of two: (x and -x) equals x.
|
||||
and eax, [edi+8]
|
||||
and edx, [edi+12]
|
||||
cmp eax, [edi+8]
|
||||
jnz .abort
|
||||
cmp edx, [edi+12]
|
||||
jnz .abort
|
||||
sub eax, 1
|
||||
sbb edx, 0
|
||||
and eax, not 0xFFF
|
||||
and eax, ebx
|
||||
jnz .abort
|
||||
and edx, ebp
|
||||
jnz .abort
|
||||
; 4f. For every active MTRR, validate memory type: it must be either WB or UC.
|
||||
add edi, 16
|
||||
cmp bl, MEM_UC
|
||||
jz .get_used_mtrrs_next
|
||||
cmp bl, MEM_WB
|
||||
jnz .abort
|
||||
.get_used_mtrrs_next:
|
||||
; 4g. Repeat the loop at 4b-4f for all [num_variable_mtrrs] entries.
|
||||
mov eax, [num_variable_mtrrs]
|
||||
lea eax, [0x200+eax*2]
|
||||
cmp ecx, eax
|
||||
jb .get_used_mtrrs_loop
|
||||
; 4h. If no active MTRRs were detected, fallback to step 7.
|
||||
cmp [.num_used_mtrrs], 0
|
||||
jz .fill_ranges_from_memory_map
|
||||
mov [.mtrrs_end], edi
|
||||
; 5. Generate sorted list of ranges marked as WB.
|
||||
; 5a. Prepare for the loop over configured MTRRs filled at step 4.
|
||||
lea ecx, [.mtrrs]
|
||||
.fill_wb_ranges:
|
||||
; 5b. Ignore non-WB MTRRs.
|
||||
mov ebx, [ecx]
|
||||
cmp bl, MEM_WB
|
||||
jnz .next_wb_range
|
||||
mov ebp, [ecx+4]
|
||||
and ebx, not 0xFFF ; clear memory type and reserved bits
|
||||
; ebp:ebx = start of the range described by the current MTRR.
|
||||
; 5c. Find the first existing range containing a point greater than ebp:ebx.
|
||||
lea esi, [.first_range]
|
||||
.find_range_wb:
|
||||
; If there is no next range or start of the next range is greater than ebp:ebx,
|
||||
; exit the loop to 5d.
|
||||
mov edi, [esi]
|
||||
test edi, edi
|
||||
jz .found_place_wb
|
||||
mov eax, ebx
|
||||
mov edx, ebp
|
||||
sub eax, dword [edi+mtrr_range.start]
|
||||
sbb edx, dword [edi+mtrr_range.start+4]
|
||||
jb .found_place_wb
|
||||
; Otherwise, if end of the next range is greater than or equal to ebp:ebx,
|
||||
; exit the loop to 5e.
|
||||
mov esi, edi
|
||||
sub eax, dword [edi+mtrr_range.length]
|
||||
sbb edx, dword [edi+mtrr_range.length+4]
|
||||
jb .expand_wb
|
||||
or eax, edx
|
||||
jnz .find_range_wb
|
||||
jmp .expand_wb
|
||||
.found_place_wb:
|
||||
; 5d. ebp:ebx is not within any existing range.
|
||||
; Insert a new range between esi and edi.
|
||||
; (Later, during 5e, it can be merged with the following ranges.)
|
||||
mov eax, [.first_free_range]
|
||||
test eax, eax
|
||||
jz .abort
|
||||
mov [esi], eax
|
||||
mov edx, [eax+mtrr_range.next]
|
||||
mov [.first_free_range], edx
|
||||
mov dword [eax+mtrr_range.start], ebx
|
||||
mov dword [eax+mtrr_range.start+4], ebp
|
||||
; Don't fill [eax+mtrr_range.next] and [eax+mtrr_range.length] yet,
|
||||
; they will be calculated including merges at step 5e.
|
||||
mov esi, edi
|
||||
mov edi, eax
|
||||
.expand_wb:
|
||||
; 5e. The range at edi contains ebp:ebx, and esi points to the first range
|
||||
; to be checked for merge: esi=edi if ebp:ebx was found in an existing range,
|
||||
; esi is next after edi if a new range with ebp:ebx was created.
|
||||
; Merge it with following ranges while start of the next range is not greater
|
||||
; than the end of the new range.
|
||||
add ebx, [ecx+8]
|
||||
adc ebp, [ecx+12]
|
||||
; ebp:ebx = end of the range described by the current MTRR.
|
||||
.expand_wb_loop:
|
||||
; If there is no next range or start of the next range is greater than ebp:ebx,
|
||||
; exit the loop to 5g.
|
||||
test esi, esi
|
||||
jz .expand_wb_done
|
||||
mov eax, ebx
|
||||
mov edx, ebp
|
||||
sub eax, dword [esi+mtrr_range.start]
|
||||
sbb edx, dword [esi+mtrr_range.start+4]
|
||||
jb .expand_wb_done
|
||||
; Otherwise, if end of the next range is greater than or equal to ebp:ebx,
|
||||
; exit the loop to 5f.
|
||||
sub eax, dword [esi+mtrr_range.length]
|
||||
sbb edx, dword [esi+mtrr_range.length+4]
|
||||
jb .expand_wb_last
|
||||
; Otherwise, the current range is completely within the new range.
|
||||
; Free it and continue the loop.
|
||||
mov edx, [esi+mtrr_range.next]
|
||||
cmp esi, edi
|
||||
jz @f
|
||||
mov eax, [.first_free_range]
|
||||
mov [esi+mtrr_range.next], eax
|
||||
mov [.first_free_range], esi
|
||||
@@:
|
||||
mov esi, edx
|
||||
jmp .expand_wb_loop
|
||||
.expand_wb_last:
|
||||
; 5f. Start of the new range is inside range described by esi,
|
||||
; end of the new range is inside range described by edi.
|
||||
; If esi is equal to edi, the new range is completely within
|
||||
; an existing range, so proceed to the next range.
|
||||
cmp esi, edi
|
||||
jz .next_wb_range
|
||||
; Otherwise, set end of interval at esi to end of interval at edi
|
||||
; and free range described by edi.
|
||||
mov ebx, dword [esi+mtrr_range.start]
|
||||
mov ebp, dword [esi+mtrr_range.start+4]
|
||||
add ebx, dword [esi+mtrr_range.length]
|
||||
adc ebp, dword [esi+mtrr_range.length+4]
|
||||
mov edx, [esi+mtrr_range.next]
|
||||
mov eax, [.first_free_range]
|
||||
mov [esi+mtrr_range.next], eax
|
||||
mov [.first_free_range], esi
|
||||
mov esi, edx
|
||||
.expand_wb_done:
|
||||
; 5g. We have found the next range (maybe 0) after merging and
|
||||
; the new end of range (maybe ebp:ebx from the new range
|
||||
; or end of another existing interval calculated at step 5f).
|
||||
; Write them to range at edi.
|
||||
mov [edi+mtrr_range.next], esi
|
||||
sub ebx, dword [edi+mtrr_range.start]
|
||||
sbb ebp, dword [edi+mtrr_range.start+4]
|
||||
mov dword [edi+mtrr_range.length], ebx
|
||||
mov dword [edi+mtrr_range.length+4], ebp
|
||||
.next_wb_range:
|
||||
; 5h. Continue the loop 5b-5g over all configured MTRRs.
|
||||
add ecx, 16
|
||||
cmp ecx, [.mtrrs_end]
|
||||
jb .fill_wb_ranges
|
||||
; 6. Exclude all ranges marked as UC.
|
||||
; 6a. Prepare for the loop over configured MTRRs filled at step 4.
|
||||
lea ecx, [.mtrrs]
|
||||
.fill_uc_ranges:
|
||||
; 6b. Ignore non-UC MTRRs.
|
||||
mov ebx, [ecx]
|
||||
cmp bl, MEM_UC
|
||||
jnz .next_uc_range
|
||||
mov ebp, [ecx+4]
|
||||
and ebx, not 0xFFF ; clear memory type and reserved bits
|
||||
; ebp:ebx = start of the range described by the current MTRR.
|
||||
lea esi, [.first_range]
|
||||
; 6c. Find the first existing range containing a point greater than ebp:ebx.
|
||||
.find_range_uc:
|
||||
; If there is no next range, ignore this MTRR,
|
||||
; exit the loop and continue to next MTRR.
|
||||
mov edi, [esi]
|
||||
test edi, edi
|
||||
jz .next_uc_range
|
||||
; If start of the next range is greater than or equal to ebp:ebx,
|
||||
; exit the loop to 6e.
|
||||
mov eax, dword [edi+mtrr_range.start]
|
||||
mov edx, dword [edi+mtrr_range.start+4]
|
||||
sub eax, ebx
|
||||
sbb edx, ebp
|
||||
jnb .truncate_uc
|
||||
; Otherwise, continue the loop if end of the next range is less than ebp:ebx,
|
||||
; exit the loop to 6d otherwise.
|
||||
mov esi, edi
|
||||
add eax, dword [edi+mtrr_range.length]
|
||||
adc edx, dword [edi+mtrr_range.length+4]
|
||||
jnb .find_range_uc
|
||||
; 6d. ebp:ebx is inside (or at end of) an existing range.
|
||||
; Split the range. (The second range, maybe containing completely within UC-range,
|
||||
; maybe of zero length, can be removed at step 6e, if needed.)
|
||||
mov edi, [.first_free_range]
|
||||
test edi, edi
|
||||
jz .abort
|
||||
mov dword [edi+mtrr_range.start], ebx
|
||||
mov dword [edi+mtrr_range.start+4], ebp
|
||||
mov dword [edi+mtrr_range.length], eax
|
||||
mov dword [edi+mtrr_range.length+4], edx
|
||||
mov eax, [edi+mtrr_range.next]
|
||||
mov [.first_free_range], eax
|
||||
mov eax, [esi+mtrr_range.next]
|
||||
mov [edi+mtrr_range.next], eax
|
||||
; don't change [esi+mtrr_range.next] yet, it will be filled at step 6e
|
||||
mov eax, ebx
|
||||
mov edx, ebp
|
||||
sub eax, dword [esi+mtrr_range.start]
|
||||
sbb edx, dword [esi+mtrr_range.start+4]
|
||||
mov dword [esi+mtrr_range.length], eax
|
||||
mov dword [esi+mtrr_range.length+4], edx
|
||||
.truncate_uc:
|
||||
; 6e. edi is the first range after ebp:ebx, check it and next ranges
|
||||
; for intersection with the new range, truncate heads.
|
||||
add ebx, [ecx+8]
|
||||
adc ebp, [ecx+12]
|
||||
; ebp:ebx = end of the range described by the current MTRR.
|
||||
.truncate_uc_loop:
|
||||
; If start of the next range is greater than ebp:ebx,
|
||||
; exit the loop to 6g.
|
||||
mov eax, ebx
|
||||
mov edx, ebp
|
||||
sub eax, dword [edi+mtrr_range.start]
|
||||
sbb edx, dword [edi+mtrr_range.start+4]
|
||||
jb .truncate_uc_done
|
||||
; Otherwise, if end of the next range is greater than ebp:ebx,
|
||||
; exit the loop to 6f.
|
||||
sub eax, dword [edi+mtrr_range.length]
|
||||
sbb edx, dword [edi+mtrr_range.length+4]
|
||||
jb .truncate_uc_last
|
||||
; Otherwise, the current range is completely within the new range.
|
||||
; Free it and continue the loop if there is a next range.
|
||||
; If that was a last range, exit the loop to 6g.
|
||||
mov edx, [edi+mtrr_range.next]
|
||||
mov eax, [.first_free_range]
|
||||
mov [.first_free_range], edi
|
||||
mov [edi+mtrr_range.next], eax
|
||||
mov edi, edx
|
||||
test edi, edi
|
||||
jnz .truncate_uc_loop
|
||||
jmp .truncate_uc_done
|
||||
.truncate_uc_last:
|
||||
; 6f. The range at edi partially intersects with the UC-range described by MTRR.
|
||||
; Truncate it from the head.
|
||||
mov dword [edi+mtrr_range.start], ebx
|
||||
mov dword [edi+mtrr_range.start+4], ebp
|
||||
neg eax
|
||||
adc edx, 0
|
||||
neg edx
|
||||
mov dword [edi+mtrr_range.length], eax
|
||||
mov dword [edi+mtrr_range.length+4], edx
|
||||
.truncate_uc_done:
|
||||
; 6g. We have found the next range (maybe 0) after intersection.
|
||||
; Write it to [esi+mtrr_range.next].
|
||||
mov [esi+mtrr_range.next], edi
|
||||
.next_uc_range:
|
||||
; 6h. Continue the loop 6b-6g over all configured MTRRs.
|
||||
add ecx, 16
|
||||
cmp ecx, [.mtrrs_end]
|
||||
jb .fill_uc_ranges
|
||||
; Sanity check: if there are no ranges after steps 5-6,
|
||||
; fallback to step 7. Otherwise, go to 8.
|
||||
cmp [.first_range], 0
|
||||
jnz .ranges_ok
|
||||
.fill_ranges_from_memory_map:
|
||||
; 7. BIOS has not configured variable-range MTRRs.
|
||||
; Create one range from 0 to [MEM_AMOUNT].
|
||||
mov eax, [.first_free_range]
|
||||
mov edx, [eax+mtrr_range.next]
|
||||
mov [.first_free_range], edx
|
||||
mov [.first_range], eax
|
||||
xor edx, edx
|
||||
mov [eax+mtrr_range.next], edx
|
||||
mov dword [eax+mtrr_range.start], edx
|
||||
mov dword [eax+mtrr_range.start+4], edx
|
||||
mov ecx, [MEM_AMOUNT]
|
||||
mov dword [eax+mtrr_range.length], ecx
|
||||
mov dword [eax+mtrr_range.length+4], edx
|
||||
.ranges_ok:
|
||||
; 8. We have calculated list of WB-ranges.
|
||||
; Now we should calculate a list of MTRRs so that
|
||||
; * every MTRR describes a range with length = power of 2 and start that is aligned,
|
||||
; * every MTRR can be WB or UC
|
||||
; * (sum of all WB ranges) minus (sum of all UC ranges) equals the calculated list
|
||||
; * top of 4G memory must not be covered by any ranges
|
||||
; Example: range [0,0xBC000000) can be converted to
|
||||
; [0,0x80000000)+[0x80000000,0xC0000000)-[0xBC000000,0xC0000000)
|
||||
; WB +WB -UC
|
||||
; but not to [0,0x100000000)-[0xC0000000,0x100000000)-[0xBC000000,0xC0000000).
|
||||
; 8a. Check that list of ranges is [0,something) plus, optionally, [4G,something).
|
||||
; This holds in practice (see mtrrtest.asm for real-life examples)
|
||||
; and significantly simplifies the code: ranges are independent, start of range
|
||||
; is almost always aligned (the only exception >4G upper memory can be easily covered),
|
||||
; there is no need to consider adding holes before start of range, only
|
||||
; append them to end of range.
|
||||
xor eax, eax
|
||||
mov edi, [.first_range]
|
||||
cmp dword [edi+mtrr_range.start], eax
|
||||
jnz .abort
|
||||
cmp dword [edi+mtrr_range.start+4], eax
|
||||
jnz .abort
|
||||
cmp dword [edi+mtrr_range.length+4], eax
|
||||
jnz .abort
|
||||
mov edx, [edi+mtrr_range.next]
|
||||
test edx, edx
|
||||
jz @f
|
||||
cmp dword [edx+mtrr_range.start], eax
|
||||
jnz .abort
|
||||
cmp dword [edx+mtrr_range.start+4], 1
|
||||
jnz .abort
|
||||
cmp [edx+mtrr_range.next], eax
|
||||
jnz .abort
|
||||
@@:
|
||||
; 8b. Initialize: no MTRRs filled.
|
||||
mov [.num_used_mtrrs], eax
|
||||
lea esi, [.mtrrs]
|
||||
.range2mtrr_loop:
|
||||
; 8c. If we are dealing with upper-memory range (after 4G)
|
||||
; with length > start, create one WB MTRR with [start,2*start),
|
||||
; reset start to 2*start and return to this step.
|
||||
; Example: [4G,24G) -> [4G,8G) {returning} + [8G,16G) {returning}
|
||||
; + [16G,24G) {advancing to ?}.
|
||||
mov eax, dword [edi+mtrr_range.length+4]
|
||||
test eax, eax
|
||||
jz .less4G
|
||||
mov edx, dword [edi+mtrr_range.start+4]
|
||||
cmp eax, edx
|
||||
jb .start_aligned
|
||||
inc [.num_used_mtrrs]
|
||||
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
|
||||
ja .abort
|
||||
mov dword [esi], MEM_WB
|
||||
mov dword [esi+4], edx
|
||||
mov dword [esi+8], 0
|
||||
mov dword [esi+12], edx
|
||||
add esi, 16
|
||||
add dword [edi+mtrr_range.start+4], edx
|
||||
sub dword [edi+mtrr_range.length+4], edx
|
||||
jnz .range2mtrr_loop
|
||||
cmp dword [edi+mtrr_range.length], 0
|
||||
jz .range2mtrr_next
|
||||
.less4G:
|
||||
; 8d. If we are dealing with low-memory range (before 4G)
|
||||
; and appending a maximal-size hole would create a range covering top of 4G,
|
||||
; create a maximal-size WB range and return to this step.
|
||||
; Example: for [0,0xBC000000) the following steps would consider
|
||||
; variants [0,0x80000000)+(another range to be splitted) and
|
||||
; [0,0x100000000)-(another range to be splitted); we forbid the last variant,
|
||||
; so the first variant must be used.
|
||||
bsr ecx, dword [edi+mtrr_range.length]
|
||||
xor edx, edx
|
||||
inc edx
|
||||
shl edx, cl
|
||||
lea eax, [edx*2]
|
||||
add eax, dword [edi+mtrr_range.start]
|
||||
jnz .start_aligned
|
||||
inc [.num_used_mtrrs]
|
||||
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
|
||||
ja .abort
|
||||
mov eax, dword [edi+mtrr_range.start]
|
||||
mov dword [esi], eax
|
||||
or dword [esi], MEM_WB
|
||||
mov dword [esi+4], 0
|
||||
mov dword [esi+8], edx
|
||||
mov dword [esi+12], 0
|
||||
add esi, 16
|
||||
add dword [edi+mtrr_range.start], edx
|
||||
sub dword [edi+mtrr_range.length], edx
|
||||
jnz .less4G
|
||||
jmp .range2mtrr_next
|
||||
.start_aligned:
|
||||
; Start is aligned for any allowed length, maximum-size hole is allowed.
|
||||
; Select the best MTRR configuration for one range.
|
||||
; length=...101101
|
||||
; Without hole at the end, we need one WB MTRR for every 1-bit in length:
|
||||
; length=...100000 + ...001000 + ...000100 + ...000001
|
||||
; We can also append one hole at the end so that one 0-bit (selected by us)
|
||||
; becomes 1 and all lower bits become 0 for WB-range:
|
||||
; length=...110000 - (...00010 + ...00001)
|
||||
; In this way, we need one WB MTRR for every 1-bit higher than the selected bit,
|
||||
; one WB MTRR for the selected bit, one UC MTRR for every 0-bit between
|
||||
; the selected bit and lowest 1-bit (they become 1-bits after negation)
|
||||
; and one UC MTRR for lowest 1-bit.
|
||||
; So we need to select 0-bit with the maximal difference
|
||||
; (number of 0-bits) - (number of 1-bits) between selected and lowest 1-bit,
|
||||
; this equals the gain from using a hole. If the difference is negative for
|
||||
; all 0-bits, don't append hole.
|
||||
; Note that lowest 1-bit is not included when counting, but selected 0-bit is.
|
||||
; 8e. Find the optimal bit position for hole.
|
||||
; eax = current difference, ebx = best difference,
|
||||
; ecx = hole bit position, edx = current bit position.
|
||||
xor eax, eax
|
||||
xor ebx, ebx
|
||||
xor ecx, ecx
|
||||
bsf edx, dword [edi+mtrr_range.length]
|
||||
jnz @f
|
||||
bsf edx, dword [edi+mtrr_range.length+4]
|
||||
add edx, 32
|
||||
@@:
|
||||
push edx ; save position of lowest 1-bit for step 8f
|
||||
.calc_stat:
|
||||
inc edx
|
||||
cmp edx, 64
|
||||
jae .stat_done
|
||||
inc eax ; increment difference in hope for 1-bit
|
||||
; Note: bt conveniently works with both .length and .length+4,
|
||||
; depending on whether edx>=32.
|
||||
bt dword [edi+mtrr_range.length], edx
|
||||
jc .calc_stat
|
||||
dec eax ; hope was wrong, decrement difference to correct 'inc'
|
||||
dec eax ; and again, now getting the real difference
|
||||
cmp eax, ebx
|
||||
jle .calc_stat
|
||||
mov ebx, eax
|
||||
mov ecx, edx
|
||||
jmp .calc_stat
|
||||
.stat_done:
|
||||
; 8f. If we decided to create a hole, flip all bits between lowest and selected.
|
||||
pop edx ; restore position of lowest 1-bit saved at step 8e
|
||||
test ecx, ecx
|
||||
jz .fill_hi_init
|
||||
@@:
|
||||
inc edx
|
||||
cmp edx, ecx
|
||||
ja .fill_hi_init
|
||||
btc dword [edi+mtrr_range.length], edx
|
||||
jmp @b
|
||||
.fill_hi_init:
|
||||
; 8g. Create MTRR ranges corresponding to upper 32 bits.
|
||||
sub ecx, 32
|
||||
.fill_hi_loop:
|
||||
bsr edx, dword [edi+mtrr_range.length+4]
|
||||
jz .fill_hi_done
|
||||
inc [.num_used_mtrrs]
|
||||
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
|
||||
ja .abort
|
||||
mov eax, dword [edi+mtrr_range.start]
|
||||
mov [esi], eax
|
||||
mov eax, dword [edi+mtrr_range.start+4]
|
||||
mov [esi+4], eax
|
||||
xor eax, eax
|
||||
mov [esi+8], eax
|
||||
bts eax, edx
|
||||
mov [esi+12], eax
|
||||
cmp edx, ecx
|
||||
jl .fill_hi_uc
|
||||
or dword [esi], MEM_WB
|
||||
add dword [edi+mtrr_range.start+4], eax
|
||||
jmp @f
|
||||
.fill_hi_uc:
|
||||
sub dword [esi+4], eax
|
||||
sub dword [edi+mtrr_range.start+4], eax
|
||||
@@:
|
||||
add esi, 16
|
||||
sub dword [edi+mtrr_range.length], eax
|
||||
jmp .fill_hi_loop
|
||||
.fill_hi_done:
|
||||
; 8h. Create MTRR ranges corresponding to lower 32 bits.
|
||||
add ecx, 32
|
||||
.fill_lo_loop:
|
||||
bsr edx, dword [edi+mtrr_range.length]
|
||||
jz .range2mtrr_next
|
||||
inc [.num_used_mtrrs]
|
||||
cmp [.num_used_mtrrs], MAX_USEFUL_MTRRS
|
||||
ja .abort
|
||||
mov eax, dword [edi+mtrr_range.start]
|
||||
mov [esi], eax
|
||||
mov eax, dword [edi+mtrr_range.start+4]
|
||||
mov [esi+4], eax
|
||||
xor eax, eax
|
||||
mov [esi+12], eax
|
||||
bts eax, edx
|
||||
mov [esi+8], eax
|
||||
cmp edx, ecx
|
||||
jl .fill_lo_uc
|
||||
or dword [esi], MEM_WB
|
||||
add dword [edi+mtrr_range.start], eax
|
||||
jmp @f
|
||||
.fill_lo_uc:
|
||||
sub dword [esi], eax
|
||||
sub dword [edi+mtrr_range.start], eax
|
||||
@@:
|
||||
add esi, 16
|
||||
sub dword [edi+mtrr_range.length], eax
|
||||
jmp .fill_lo_loop
|
||||
.range2mtrr_next:
|
||||
; 8i. Repeat the loop at 8c-8h for all ranges.
|
||||
mov edi, [edi+mtrr_range.next]
|
||||
test edi, edi
|
||||
jnz .range2mtrr_loop
|
||||
; 9. We have calculated needed MTRRs, now setup them in the CPU.
|
||||
; 9a. Abort if number of MTRRs is too large.
|
||||
mov eax, [num_variable_mtrrs]
|
||||
cmp [.num_used_mtrrs], eax
|
||||
ja .abort
|
||||
|
||||
; 9b. Prepare for changes.
|
||||
call mtrr_begin_change
|
||||
|
||||
; 9c. Prepare for loop over MTRRs.
|
||||
lea esi, [.mtrrs]
|
||||
mov ecx, 0x200
|
||||
@@:
|
||||
; 9d. For every MTRR, copy PHYSBASEn as is: step 8 has configured
|
||||
; start value and type bits as needed.
|
||||
mov eax, [esi]
|
||||
mov edx, [esi+4]
|
||||
wrmsr
|
||||
inc ecx
|
||||
; 9e. For every MTRR, calculate PHYSMASKn = -(length) or 0x800
|
||||
; with upper bits cleared, 0x800 = MTRR is valid.
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
sub eax, [esi+8]
|
||||
sbb edx, [esi+12]
|
||||
or eax, 0x800
|
||||
or edx, [.phys_reserved_mask]
|
||||
xor edx, [.phys_reserved_mask]
|
||||
wrmsr
|
||||
inc ecx
|
||||
; 9f. Continue steps 9d and 9e for all MTRRs calculated at step 8.
|
||||
add esi, 16
|
||||
dec [.num_used_mtrrs]
|
||||
jnz @b
|
||||
; 9g. Zero other MTRRs.
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
mov ebx, [num_variable_mtrrs]
|
||||
lea ebx, [0x200+ebx*2]
|
||||
@@:
|
||||
cmp ecx, ebx
|
||||
jae @f
|
||||
wrmsr
|
||||
inc ecx
|
||||
wrmsr
|
||||
inc ecx
|
||||
jmp @b
|
||||
@@:
|
||||
|
||||
; 9i. Configure MTRR_DEF_TYPE.
|
||||
mov ecx, 0x2FF
|
||||
rdmsr
|
||||
or ah, 8 ; enable variable-ranges MTRR
|
||||
and al, 0xF0; default memtype = UC
|
||||
wrmsr
|
||||
|
||||
; 9j. Changes are done.
|
||||
call mtrr_end_change
|
||||
|
||||
.abort:
|
||||
add esp, .local_vars_size + MAX_RANGES * sizeof.mtrr_range
|
||||
pop ebp
|
||||
ret
|
||||
endp
|
||||
|
||||
; Allocate&set one MTRR for given range.
|
||||
; size must be power of 2 that divides base.
|
||||
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
|
||||
; find unused register
|
||||
mov ecx, 0x201
|
||||
.scan:
|
||||
rdmsr
|
||||
dec ecx
|
||||
test ah, 8
|
||||
jz .found
|
||||
rdmsr
|
||||
test edx, edx
|
||||
jnz @f
|
||||
and eax, not 0xFFF ; clear reserved bits
|
||||
cmp eax, [base]
|
||||
jz .ret
|
||||
@@:
|
||||
add ecx, 3
|
||||
mov eax, [num_variable_mtrrs]
|
||||
lea eax, [0x200+eax*2]
|
||||
cmp ecx, eax
|
||||
jb .scan
|
||||
; no free registers, ignore the call
|
||||
.ret:
|
||||
ret
|
||||
.found:
|
||||
; found, write values
|
||||
call mtrr_begin_change
|
||||
xor edx, edx
|
||||
mov eax, [base]
|
||||
or eax, [mem_type]
|
||||
wrmsr
|
||||
|
||||
mov al, [cpu_phys_addr_width]
|
||||
xor edx, edx
|
||||
bts edx, eax
|
||||
xor eax, eax
|
||||
sub eax, [size]
|
||||
sbb edx, 0
|
||||
or eax, 0x800
|
||||
inc ecx
|
||||
wrmsr
|
||||
call mtrr_end_change
|
||||
ret
|
||||
endp
|
||||
|
||||
; Helper procedure for mtrr_validate.
|
||||
; Calculates memory type for given address according to variable-range MTRRs.
|
||||
; Assumes that MTRRs are enabled.
|
||||
; in: ebx = 32-bit physical address
|
||||
; out: eax = memory type for ebx
|
||||
proc mtrr_get_real_type
|
||||
; 1. Initialize: we have not yet found any MTRRs covering ebx.
|
||||
push 0
|
||||
mov ecx, 0x201
|
||||
.mtrr_loop:
|
||||
; 2. For every MTRR, check whether it is valid; if not, continue to the next MTRR.
|
||||
rdmsr
|
||||
dec ecx
|
||||
test ah, 8
|
||||
jz .next
|
||||
; 3. For every valid MTRR, check whether (ebx and PHYSMASKn) == PHYSBASEn,
|
||||
; excluding low 12 bits.
|
||||
and eax, ebx
|
||||
push eax
|
||||
rdmsr
|
||||
test edx, edx
|
||||
pop edx
|
||||
jnz .next
|
||||
xor edx, eax
|
||||
and edx, not 0xFFF
|
||||
jnz .next
|
||||
; 4. If so, set the bit corresponding to memory type defined by this MTRR.
|
||||
and eax, 7
|
||||
bts [esp], eax
|
||||
.next:
|
||||
; 5. Continue loop at 2-4 for all variable-range MTRRs.
|
||||
add ecx, 3
|
||||
mov eax, [num_variable_mtrrs]
|
||||
lea eax, [0x200+eax*2]
|
||||
cmp ecx, eax
|
||||
jb .mtrr_loop
|
||||
; 6. If no MTRRs cover address in ebx, use default MTRR type from MTRR_DEF_CAP.
|
||||
pop edx
|
||||
test edx, edx
|
||||
jz .default
|
||||
; 7. Find&clear 1-bit in edx.
|
||||
bsf eax, edx
|
||||
btr edx, eax
|
||||
; 8. If there was only one 1-bit, then all MTRRs are consistent, return that bit.
|
||||
test edx, edx
|
||||
jz .nothing
|
||||
; Otherwise, return MEM_UC (e.g. WB+UC is UC).
|
||||
xor eax, eax
|
||||
.nothing:
|
||||
ret
|
||||
.default:
|
||||
mov ecx, 0x2FF
|
||||
rdmsr
|
||||
movzx eax, al
|
||||
ret
|
||||
endp
|
||||
|
||||
; If MTRRs are configured improperly, this is not obvious to the user;
|
||||
; everything works, but the performance can be horrible.
|
||||
; Try to detect this and let the user know that the low performance
|
||||
; is caused by some problem and is not a global property of the system.
|
||||
; Let's hope he would report it to developers...
|
||||
proc mtrr_validate
|
||||
; 1. If MTRRs are not supported, they cannot be configured improperly.
|
||||
; Note: VirtualBox claims MTRR support in cpuid, but emulates MTRRCAP=0,
|
||||
; which is efficiently equivalent to absent MTRRs.
|
||||
; So check [num_variable_mtrrs] instead of CAPS_MTRR in [cpu_caps].
|
||||
cmp [num_variable_mtrrs], 0
|
||||
jz .exit
|
||||
; 2. If variable-range MTRRs are not configured, this is a problem.
|
||||
mov ecx, 0x2FF
|
||||
rdmsr
|
||||
test ah, 8
|
||||
jz .fail
|
||||
; 3. Get the memory type for address somewhere inside working memory.
|
||||
; It must be write-back.
|
||||
mov ebx, 0x27FFFF
|
||||
call mtrr_get_real_type
|
||||
cmp al, MEM_WB
|
||||
jnz .fail
|
||||
; 4. If we're using a mode with LFB,
|
||||
; get the memory type for last pixel of the framebuffer.
|
||||
; It must be write-combined.
|
||||
test word [SCR_MODE], 0x4000
|
||||
jz .exit
|
||||
mov eax, [_display.pitch]
|
||||
mul [_display.height]
|
||||
dec eax
|
||||
; LFB is mapped to virtual address LFB_BASE,
|
||||
; it uses global pages if supported by CPU.
|
||||
mov ebx, [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)]
|
||||
test ebx, PG_LARGE
|
||||
jnz @f
|
||||
mov ebx, [page_tabs+(LFB_BASE shr 10)]
|
||||
@@:
|
||||
and ebx, not 0xFFF
|
||||
add ebx, eax
|
||||
call mtrr_get_real_type
|
||||
cmp al, MEM_WC
|
||||
jz .exit
|
||||
; 5. The check at step 4 fails on Bochs:
|
||||
; Bochs BIOS configures MTRRs in a strange way not respecting [cpu_phys_addr_width],
|
||||
; so mtrr_reconfigure avoids to touch anything.
|
||||
; However, Bochs core ignores MTRRs (keeping them only for rdmsr/wrmsr),
|
||||
; so we don't care about proper setting for Bochs.
|
||||
; Use northbridge PCI id to detect Bochs: it emulates either i440fx or i430fx
|
||||
; depending on configuration file.
|
||||
mov eax, [pcidev_list.fd]
|
||||
cmp eax, pcidev_list ; sanity check: fail if no PCI devices
|
||||
jz .fail
|
||||
cmp [eax+PCIDEV.vendor_device_id], 0x12378086
|
||||
jz .exit
|
||||
cmp [eax+PCIDEV.vendor_device_id], 0x01228086
|
||||
jnz .fail
|
||||
.exit:
|
||||
ret
|
||||
.fail:
|
||||
mov ebx, mtrr_user_message
|
||||
mov ebp, notifyapp
|
||||
call fs_execute_from_sysdir_param
|
||||
ret
|
||||
endp
|
|
@ -24,15 +24,30 @@ proc load_PE stdcall, file_name:dword
|
|||
|
||||
mov [image], eax
|
||||
|
||||
mov edx, [eax+60]
|
||||
mov edx, [eax+STRIPPED_PE_HEADER.SizeOfImage]
|
||||
; mov cl, [eax+STRIPPED_PE_HEADER.Subsystem]
|
||||
cmp word [eax], STRIPPED_PE_SIGNATURE
|
||||
jz @f
|
||||
|
||||
stdcall kernel_alloc, [eax+80+edx]
|
||||
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
|
||||
test eax, eax
|
||||
jz .cleanup
|
||||
|
||||
mov [base], eax
|
||||
|
||||
stdcall map_PE, eax, [image]
|
||||
push ebx ebp
|
||||
mov ebx, [image]
|
||||
mov ebp, eax
|
||||
call map_PE
|
||||
pop ebp ebx
|
||||
|
||||
mov [entry], eax
|
||||
test eax, eax
|
||||
|
@ -48,199 +63,200 @@ proc load_PE stdcall, file_name:dword
|
|||
ret
|
||||
endp
|
||||
|
||||
DWORD equ dword
|
||||
PTR equ
|
||||
|
||||
align 4
|
||||
map_PE: ;stdcall base:dword, image:dword
|
||||
cld
|
||||
push ebp
|
||||
map_PE: ;ebp=base:dword, ebx=image:dword
|
||||
push edi
|
||||
push esi
|
||||
push ebx
|
||||
sub esp, 60
|
||||
mov ebx, DWORD PTR [esp+84]
|
||||
mov ebp, DWORD PTR [esp+80]
|
||||
mov edx, ebx
|
||||
mov esi, ebx
|
||||
add edx, DWORD PTR [ebx+60]
|
||||
mov edi, ebp
|
||||
mov DWORD PTR [esp+32], edx
|
||||
mov ecx, DWORD PTR [edx+84]
|
||||
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
|
||||
|
||||
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
|
||||
mov edi, ebp
|
||||
shr ecx, 2
|
||||
rep movsd
|
||||
|
||||
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]
|
||||
cmp [.numsections], 0
|
||||
jz .nosections
|
||||
.copy_sections:
|
||||
mov eax, [edx+8]
|
||||
test eax, eax
|
||||
je L4
|
||||
je .no_section_data
|
||||
mov esi, ebx
|
||||
mov edi, ebp
|
||||
add esi, DWORD PTR [edx+268]
|
||||
add esi, [edx+12]
|
||||
mov ecx, eax
|
||||
add edi, DWORD PTR [edx+260]
|
||||
add edi, [edx+4]
|
||||
|
||||
add ecx, 3
|
||||
shr ecx, 2
|
||||
rep movsd
|
||||
|
||||
L4:
|
||||
mov ecx, DWORD PTR [edx+256]
|
||||
.no_section_data:
|
||||
mov ecx, [edx]
|
||||
cmp ecx, eax
|
||||
jbe L6
|
||||
jbe .no_section_fill
|
||||
sub ecx, eax
|
||||
add eax, DWORD PTR [edx+260]
|
||||
add eax, [edx+4]
|
||||
lea edi, [eax+ebp]
|
||||
|
||||
xor eax, eax
|
||||
rep stosb
|
||||
|
||||
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]
|
||||
.no_section_fill:
|
||||
add edx, [.section_header_size]
|
||||
dec [.numsections]
|
||||
jnz .copy_sections
|
||||
.nosections:
|
||||
cmp [.relocs_size], 0
|
||||
je .no_relocations
|
||||
mov esi, ebp
|
||||
mov ecx, ebp
|
||||
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
|
||||
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
|
||||
shr ebx, 1
|
||||
jmp L13
|
||||
L14:
|
||||
movzx eax, WORD PTR [ecx+8+edi*2]
|
||||
jz .relocs_next_block
|
||||
.one_reloc:
|
||||
movzx eax, word [ecx]
|
||||
add ecx, 2
|
||||
mov edx, eax
|
||||
shr eax, 12
|
||||
and edx, 4095
|
||||
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]
|
||||
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]
|
||||
test edx, edx
|
||||
jnz @f
|
||||
mov edx, ecx
|
||||
@@:
|
||||
mov DWORD PTR [esp+52], 0
|
||||
mov [.import_idx], 0
|
||||
add ecx, ebp
|
||||
add edx, ebp
|
||||
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]
|
||||
mov [.import_names], edx
|
||||
mov [.import_targets], ecx
|
||||
.import_func:
|
||||
mov esi, [.import_idx]
|
||||
mov edi, [.import_names]
|
||||
mov eax, [edi+esi*4]
|
||||
test eax, eax
|
||||
je L27
|
||||
test eax, eax
|
||||
js L27
|
||||
je .next_import_block
|
||||
js .next_import_block
|
||||
lea edi, [ebp+eax]
|
||||
mov eax, DWORD PTR [esp+28]
|
||||
mov DWORD PTR [eax+esi*4], 0
|
||||
mov eax, [.import_targets]
|
||||
mov dword [eax+esi*4], 0
|
||||
lea esi, [edi+2]
|
||||
push eax
|
||||
movzx ebx, word [edi]
|
||||
push 32
|
||||
movzx eax, WORD PTR [edi]
|
||||
mov edx, DWORD PTR [esp+56]
|
||||
mov eax, DWORD PTR [edx+eax*4]
|
||||
mov ecx, [__exports+32]
|
||||
mov eax, [ecx+OS_BASE+ebx*4]
|
||||
add eax, OS_BASE
|
||||
push eax
|
||||
push esi
|
||||
call strncmp
|
||||
pop ebx
|
||||
test eax, eax
|
||||
jz .import_func_found
|
||||
xor ebx, ebx
|
||||
test eax, eax
|
||||
jne L32
|
||||
jmp L30
|
||||
L33:
|
||||
push ecx
|
||||
.import_func_candidate:
|
||||
push 32
|
||||
mov ecx, DWORD PTR [esp+28]
|
||||
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4]
|
||||
mov ecx, [__exports+32]
|
||||
mov eax, [ecx+OS_BASE+ebx*4]
|
||||
add eax, OS_BASE
|
||||
push eax
|
||||
push esi
|
||||
call strncmp
|
||||
pop edx
|
||||
test eax, eax
|
||||
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:
|
||||
je .import_func_found
|
||||
inc ebx
|
||||
L32:
|
||||
cmp ebx, DWORD PTR [__exports+24]
|
||||
jb L33
|
||||
L36:
|
||||
cmp ebx, DWORD PTR [__exports+24]
|
||||
jne L37
|
||||
cmp ebx, [__exports+24]
|
||||
jb .import_func_candidate
|
||||
|
||||
mov esi, msg_unresolved
|
||||
call sys_msg_board_str
|
||||
|
@ -249,34 +265,30 @@ L36:
|
|||
mov esi, msg_CR
|
||||
call sys_msg_board_str
|
||||
|
||||
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]
|
||||
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]
|
||||
add eax, OS_BASE
|
||||
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:
|
||||
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:
|
||||
xor eax, eax
|
||||
cmp DWORD PTR [esp+40], 0
|
||||
jne L40
|
||||
L20:
|
||||
mov ecx, DWORD PTR [esp+32]
|
||||
cmp [.bad_import], 0
|
||||
jne @f
|
||||
.no_imports:
|
||||
mov eax, ebp
|
||||
add eax, DWORD PTR [ecx+40]
|
||||
L40:
|
||||
add esp, 60
|
||||
pop ebx
|
||||
add eax, [.AddressOfEntryPoint]
|
||||
@@:
|
||||
add esp, .locals_size
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 8
|
||||
ret
|
||||
|
|
|
@ -29,8 +29,7 @@ irq0:
|
|||
.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
|
||||
|
@ -44,26 +43,10 @@ change_task:
|
|||
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
|
||||
|
@ -121,10 +104,11 @@ do_change_task:
|
|||
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 ecx, APPDATA.dir_table
|
||||
mov eax, [ebx+ecx] ;offset>0x7F
|
||||
cmp eax, [esi+ecx] ;offset>0x7F
|
||||
mov eax, [ebx+APPDATA.process]
|
||||
cmp eax, [current_process]
|
||||
je @f
|
||||
mov [current_process], eax
|
||||
mov eax, [eax+PROC.pdt_0_phys]
|
||||
mov cr3, eax
|
||||
@@:
|
||||
; set tss.esp0
|
||||
|
@ -159,7 +143,7 @@ do_change_task:
|
|||
jz @f
|
||||
xor eax, eax
|
||||
mov dr6, eax
|
||||
lea esi, [ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table];offset>0x7F
|
||||
lea esi, [ebx+APPDATA.dbg_regs]
|
||||
cld
|
||||
macro lodsReg [reg] {
|
||||
lodsd
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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
|
||||
|
|
|
@ -413,23 +413,26 @@ endg
|
|||
|
||||
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
|
||||
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0
|
||||
jne @F
|
||||
mov edx, [SLOT_BASE+esi+APPDATA.process]
|
||||
test edx, edx
|
||||
jnz @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...
|
||||
|
@ -442,14 +445,14 @@ terminate: ; terminate application
|
|||
; ...it has page directory for V86 mode
|
||||
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
|
||||
mov ecx, [esi+4]
|
||||
mov [eax+SLOT_BASE+APPDATA.dir_table], ecx
|
||||
mov [eax+SLOT_BASE+APPDATA.process], ecx
|
||||
; ...and I/O permission map for V86 mode
|
||||
mov ecx, [esi+12]
|
||||
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
|
||||
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
|
||||
|
@ -467,11 +470,6 @@ terminate: ; terminate application
|
|||
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
|
||||
|
@ -630,6 +628,9 @@ terminate: ; terminate application
|
|||
je @F
|
||||
call free_page
|
||||
@@:
|
||||
lea ebx, [edi+APPDATA.list]
|
||||
list_del ebx ;destroys edx, ecx
|
||||
|
||||
mov eax, 0x20202020
|
||||
stosd
|
||||
stosd
|
||||
|
@ -745,7 +746,17 @@ terminate: ; terminate application
|
|||
add ecx, 0x100
|
||||
jmp .xd0
|
||||
.xd1:
|
||||
; call systest
|
||||
;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
|
||||
@@:
|
||||
sti ; .. and life goes on
|
||||
|
||||
mov eax, [draw_limits.left]
|
||||
|
@ -760,18 +771,10 @@ terminate: ; terminate application
|
|||
call unlock_application_table
|
||||
;mov esi,process_terminated
|
||||
;call sys_msg_board_str
|
||||
add esp, 4
|
||||
add esp, 8
|
||||
ret
|
||||
restore .slot
|
||||
|
||||
;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
|
||||
restore .process
|
||||
|
||||
; Three following procedures are used to guarantee that
|
||||
; some part of kernel code will not be terminated from outside
|
||||
|
|
|
@ -70,7 +70,7 @@ proc fs_execute
|
|||
filename rd 256 ;1024/4
|
||||
flags dd ?
|
||||
|
||||
save_cr3 dd ?
|
||||
save_proc dd ?
|
||||
slot dd ?
|
||||
slot_base dd ?
|
||||
file_base dd ?
|
||||
|
@ -215,7 +215,7 @@ proc fs_execute
|
|||
|
||||
call lock_application_table
|
||||
|
||||
call get_new_process_place
|
||||
call alloc_thread_slot
|
||||
test eax, eax
|
||||
mov esi, -0x20 ; too many processes
|
||||
jz .err
|
||||
|
@ -248,18 +248,23 @@ proc fs_execute
|
|||
loop .copy_process_name_loop
|
||||
.copy_process_name_done:
|
||||
|
||||
mov ebx, cr3
|
||||
mov [save_cr3], ebx
|
||||
mov ebx, [current_process]
|
||||
mov [save_proc], ebx
|
||||
|
||||
stdcall create_app_space, [hdr_mem], [file_base], [file_size]
|
||||
stdcall create_process, [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.dir_table], eax
|
||||
mov eax, [hdr_mem]
|
||||
mov [ebx+APPDATA.mem_size], eax
|
||||
mov [ebx+APPDATA.process], eax
|
||||
|
||||
lea edx, [ebx+APPDATA.list]
|
||||
lea ecx, [eax+PROC.thr_list]
|
||||
list_add_tail edx, ecx
|
||||
|
||||
xor edx, edx
|
||||
cmp word [6], '02'
|
||||
|
@ -292,7 +297,7 @@ end if
|
|||
lea ecx, [filename]
|
||||
stdcall set_app_params , [slot], eax, ebx, ecx, [flags]
|
||||
|
||||
mov eax, [save_cr3]
|
||||
mov eax, [save_proc]
|
||||
call set_cr3
|
||||
|
||||
mov eax, [process_number];set result
|
||||
|
@ -301,7 +306,7 @@ end if
|
|||
jmp .final
|
||||
|
||||
.failed:
|
||||
mov eax, [save_cr3]
|
||||
mov eax, [save_proc]
|
||||
call set_cr3
|
||||
.err:
|
||||
.err_hdr:
|
||||
|
@ -385,53 +390,55 @@ test_app_header:
|
|||
ret
|
||||
|
||||
align 4
|
||||
proc get_new_process_place
|
||||
alloc_thread_slot:
|
||||
;input:
|
||||
; none
|
||||
;result:
|
||||
; eax=[new_process_place]<>0 - ok
|
||||
; eax=[new_thread_slot]<>0 - ok
|
||||
; 0 - failed.
|
||||
;This function find least empty slot.
|
||||
;It doesn't increase [TASK_COUNT]!
|
||||
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:
|
||||
|
||||
|
||||
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
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
.found:
|
||||
btr [edx], eax
|
||||
sub edx, thr_slot_map
|
||||
lea eax, [eax+edx*8]
|
||||
popfd
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
||||
proc create_process stdcall, app_size:dword,img_base:dword,img_size:dword
|
||||
locals
|
||||
app_pages dd ?
|
||||
img_pages dd ?
|
||||
dir_addr dd ?
|
||||
process dd ?
|
||||
app_tabs dd ?
|
||||
endl
|
||||
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_lock
|
||||
|
||||
xor eax, eax
|
||||
mov [dir_addr], eax
|
||||
mov [process], eax
|
||||
|
||||
mov eax, [app_size]
|
||||
add eax, 4095
|
||||
|
@ -454,39 +461,59 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
|
|||
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
|
||||
|
||||
call alloc_page
|
||||
stdcall kernel_alloc, 0x2000
|
||||
test eax, eax
|
||||
jz .fail
|
||||
mov [dir_addr], eax
|
||||
stdcall map_page, [tmp_task_pdir], eax, dword PG_SW
|
||||
mov [process], eax
|
||||
|
||||
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
|
||||
mov esi, sys_pgdir+(OS_BASE shr 20)
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
|
||||
mov ecx, (OS_BASE shr 20)/4
|
||||
mov esi, sys_proc+PROC.pdt_0+(OS_BASE shr 20)
|
||||
rep movsd
|
||||
|
||||
mov eax, [dir_addr]
|
||||
mov eax, [edi-8192+PROC.pdt_0_phys]
|
||||
or eax, PG_SW
|
||||
mov [edi-4096+(page_tabs shr 20)], eax
|
||||
|
||||
and eax, -4096
|
||||
lea eax, [edi-8192]
|
||||
call set_cr3
|
||||
|
||||
mov edx, [app_tabs]
|
||||
mov edi, new_app_base
|
||||
mov ecx, [app_tabs]
|
||||
test ecx, ecx
|
||||
jz .done
|
||||
|
||||
xor edi, edi
|
||||
@@:
|
||||
call alloc_page
|
||||
test eax, eax
|
||||
|
@ -494,81 +521,81 @@ end if
|
|||
|
||||
stdcall map_page_table, edi, eax
|
||||
add edi, 0x00400000
|
||||
dec edx
|
||||
jnz @B
|
||||
loop @B
|
||||
|
||||
mov edi, new_app_base
|
||||
shr edi, 10
|
||||
add edi, page_tabs
|
||||
mov edi, page_tabs
|
||||
|
||||
mov ecx, [app_tabs]
|
||||
shl ecx, 10
|
||||
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
|
||||
add edi, page_tabs
|
||||
mov edi, page_tabs
|
||||
.remap:
|
||||
lodsd
|
||||
and eax, 0xFFFFF000
|
||||
or eax, ebx; force user level r/w access
|
||||
stosd
|
||||
add edx, 0x1000
|
||||
dec [app_pages]
|
||||
dec ecx
|
||||
jnz .remap
|
||||
|
||||
mov ecx, [app_pages]
|
||||
test ecx, ecx
|
||||
loop .remap
|
||||
.bss:
|
||||
mov ebx, [app_pages]
|
||||
test ebx, ebx
|
||||
jz .done
|
||||
|
||||
if GREEDY_KERNEL
|
||||
mov eax, 0x02
|
||||
rep stosd
|
||||
else
|
||||
|
||||
.alloc:
|
||||
.map_bss:
|
||||
call alloc_page
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
stdcall map_page, edx, eax, dword PG_UW
|
||||
add edx, 0x1000
|
||||
dec [app_pages]
|
||||
jnz .alloc
|
||||
end if
|
||||
dec ebx
|
||||
jnz .map_bss
|
||||
|
||||
.done:
|
||||
stdcall map_page, [tmp_task_pdir], dword 0, dword PG_UNMAP
|
||||
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
mov eax, [dir_addr]
|
||||
mov eax, [process]
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
.fail:
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
cmp [dir_addr], 0
|
||||
cmp [process], 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 [ebx+APPDATA.dir_table], eax
|
||||
mov [current_process], eax
|
||||
mov [ebx+APPDATA.process], eax
|
||||
mov eax, [eax+PROC.pdt_0_phys]
|
||||
mov cr3, eax
|
||||
popfd
|
||||
ret
|
||||
|
||||
align 4
|
||||
|
@ -582,6 +609,8 @@ proc destroy_page_table stdcall, pg_tab:dword
|
|||
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
|
||||
|
@ -594,46 +623,25 @@ proc destroy_page_table stdcall, pg_tab:dword
|
|||
endp
|
||||
|
||||
align 4
|
||||
proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
|
||||
destroy_process: ;fastcall ecx= ptr to process
|
||||
|
||||
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
|
||||
lea eax, [ecx+PROC.thr_list]
|
||||
cmp eax, [eax+LHEAD.next]
|
||||
jne .exit
|
||||
|
||||
;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
|
||||
align 4
|
||||
.internal:
|
||||
push ecx
|
||||
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_lock
|
||||
mov esi, [ecx+PROC.dlls_list_ptr]
|
||||
call destroy_all_hdlls
|
||||
|
||||
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
|
||||
; mov ecx, pg_data.mutex
|
||||
; call mutex_lock
|
||||
|
||||
mov esi, [esp]
|
||||
add esi, PROC.pdt_0
|
||||
mov edi, (0x80000000 shr 20)/4
|
||||
.destroy:
|
||||
mov eax, [esi]
|
||||
test eax, 1
|
||||
|
@ -648,16 +656,13 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
|
|||
dec edi
|
||||
jnz .destroy
|
||||
|
||||
mov eax, [pg_dir]
|
||||
call free_page
|
||||
.exit:
|
||||
call kernel_free ;ecx still in stack
|
||||
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
|
||||
stdcall map_page, [tmp_task_pdir], 0, PG_UNMAP
|
||||
mov ecx, pg_data.mutex
|
||||
call mutex_unlock
|
||||
.ret:
|
||||
; mov ecx, pg_data.mutex
|
||||
; call mutex_unlock
|
||||
|
||||
.exit:
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
get_pid:
|
||||
|
@ -708,6 +713,10 @@ check_region:
|
|||
;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
|
||||
;-----------------------------------------------------------------------------
|
||||
|
@ -732,57 +741,13 @@ check_region:
|
|||
|
||||
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
|
||||
|
@ -954,7 +919,7 @@ proc new_sys_threads
|
|||
|
||||
call lock_application_table
|
||||
|
||||
call get_new_process_place
|
||||
call alloc_thread_slot
|
||||
test eax, eax
|
||||
jz .failed
|
||||
|
||||
|
@ -976,20 +941,12 @@ proc new_sys_threads
|
|||
mov ecx, 11
|
||||
rep movsb ;copy process name
|
||||
|
||||
mov eax, [ebx+APPDATA.heap_base]
|
||||
mov [edx+APPDATA.heap_base], eax
|
||||
mov eax, [ebx+APPDATA.process]
|
||||
mov [edx+APPDATA.process], eax
|
||||
|
||||
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
|
||||
lea ebx, [edx+APPDATA.list]
|
||||
lea ecx, [eax+PROC.thr_list]
|
||||
list_add_tail ebx, ecx ;add thread to process child's list
|
||||
|
||||
mov eax, [ebx+APPDATA.tls_base]
|
||||
test eax, eax
|
||||
|
@ -1118,8 +1075,8 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
|||
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]
|
||||
|
||||
|
@ -1158,8 +1115,8 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
|||
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]
|
||||
|
@ -1188,9 +1145,9 @@ proc set_app_params stdcall,slot:dword, params:dword,\
|
|||
xor eax, eax
|
||||
mov [ecx+0], dword eax
|
||||
mov [ecx+4], dword eax
|
||||
mov eax, [_display.width]
|
||||
mov eax, [Screen_Max_X]
|
||||
mov [ecx+8], eax
|
||||
mov eax, [_display.height]
|
||||
mov eax, [Screen_Max_Y]
|
||||
mov [ecx+12], eax
|
||||
|
||||
mov ebx, [pl0_stack]
|
||||
|
|
|
@ -14,9 +14,7 @@ DEBUG_SHOW_IO = 0
|
|||
|
||||
struct V86_machine
|
||||
; page directory
|
||||
pagedir dd ?
|
||||
; translation table: V86 address -> flat linear address
|
||||
pages dd ?
|
||||
process dd ?
|
||||
; mutex to protect all data from writing by multiple threads at one time
|
||||
mutex dd ?
|
||||
; i/o permission map
|
||||
|
@ -38,91 +36,87 @@ v86_create:
|
|||
and dword [eax+V86_machine.mutex], 0
|
||||
; allocate tables
|
||||
mov ebx, eax
|
||||
; 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
|
||||
|
||||
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
|
||||
call kernel_alloc
|
||||
test eax, eax
|
||||
jz .fail2
|
||||
mov [ebx+V86_machine.pagedir], eax
|
||||
push edi eax
|
||||
mov edi, eax
|
||||
add eax, 1800h
|
||||
mov [ebx+V86_machine.pages], eax
|
||||
|
||||
mov [ebx+V86_machine.iopm], eax
|
||||
|
||||
|
||||
; initialize tables
|
||||
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...
|
||||
push edi
|
||||
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, -1
|
||||
mov ecx, 2000h/4
|
||||
rep stosd
|
||||
|
||||
mov eax, [ebx+V86_machine.process]
|
||||
mov eax, [eax+PROC.pdt_0_phys]
|
||||
|
||||
pushfd
|
||||
cli
|
||||
mov cr3, eax
|
||||
|
||||
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
|
||||
|
||||
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 ecx, 4
|
||||
mov edx, 0x9C000
|
||||
push eax
|
||||
lea edi, [eax+0x9C*4]
|
||||
|
||||
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
|
||||
@@:
|
||||
lea eax, [edx + OS_BASE]
|
||||
mov [edi+800h], eax
|
||||
lea eax, [edx + 111b]
|
||||
stosd
|
||||
add edx, 0x1000
|
||||
add eax, edx
|
||||
loop @b
|
||||
pop eax
|
||||
pop edi
|
||||
|
||||
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
|
||||
; physical address = 0xC0000
|
||||
; linear address = 0x800C0000
|
||||
mov ecx, 0xC0
|
||||
|
||||
mov eax, 0xC0000+PG_UW
|
||||
mov edi, page_tabs+0xC0*4
|
||||
mov ecx, 64
|
||||
@@:
|
||||
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
|
||||
stosd
|
||||
add eax, edx
|
||||
loop @b
|
||||
|
||||
mov eax, sys_proc
|
||||
push ebx
|
||||
call set_cr3
|
||||
pop ebx
|
||||
popfd
|
||||
|
||||
pop edi
|
||||
|
||||
mov eax, ebx
|
||||
ret
|
||||
.fail2:
|
||||
|
@ -132,15 +126,16 @@ v86_create:
|
|||
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
|
||||
|
@ -150,28 +145,30 @@ v86_destroy:
|
|||
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
|
||||
add eax, [edx+ecx*4] ; atomic operation, no mutex needed
|
||||
and edx, 0xFFFFF000
|
||||
or eax, edx
|
||||
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!)
|
||||
; 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)
|
||||
|
@ -214,21 +211,7 @@ init_sys_v86:
|
|||
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]
|
||||
|
@ -272,36 +255,38 @@ ends
|
|||
; eax = 3 - IRQ is already hooked by another VM
|
||||
; destroys: nothing
|
||||
v86_start:
|
||||
|
||||
pushad
|
||||
|
||||
cli
|
||||
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
add ecx, SLOT_BASE
|
||||
mov ecx, [current_slot]
|
||||
|
||||
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
|
||||
add eax, 0x1000
|
||||
mov dword [ecx+APPDATA.io_map+4], eax
|
||||
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax
|
||||
|
||||
push [ecx+APPDATA.dir_table]
|
||||
push [ecx+APPDATA.process]
|
||||
push [ecx+APPDATA.saved_esp0]
|
||||
mov [ecx+APPDATA.saved_esp0], esp
|
||||
mov [tss._esp0], esp
|
||||
|
||||
mov eax, [esi+V86_machine.pagedir]
|
||||
mov eax, [esi+V86_machine.iopm]
|
||||
call get_pg_addr
|
||||
mov [ecx+APPDATA.dir_table], eax
|
||||
mov cr3, eax
|
||||
inc eax
|
||||
mov dword [ecx+APPDATA.io_map], eax
|
||||
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax
|
||||
|
||||
; mov [irq_tab+5*4], my05
|
||||
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]
|
||||
mov cr3, eax
|
||||
|
||||
; We do not enable interrupts, because V86 IRQ redirector assumes that
|
||||
; machine is running
|
||||
|
@ -782,19 +767,21 @@ end if
|
|||
mov esp, esi
|
||||
|
||||
cli
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
mov ecx, [current_slot]
|
||||
pop eax
|
||||
mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax
|
||||
|
||||
mov [ecx+APPDATA.saved_esp0], eax
|
||||
mov [tss._esp0], eax
|
||||
pop eax
|
||||
mov [SLOT_BASE+ecx+APPDATA.dir_table], eax
|
||||
mov [ecx+APPDATA.process], eax
|
||||
mov [current_process], eax
|
||||
pop ebx
|
||||
mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx
|
||||
mov dword [ecx+APPDATA.io_map+4], ebx
|
||||
mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx
|
||||
pop ebx
|
||||
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx
|
||||
mov dword [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
|
||||
|
||||
|
@ -843,11 +830,10 @@ v86_irq:
|
|||
pop eax
|
||||
v86_irq2:
|
||||
mov esi, [v86_irqhooks+edi*8] ; get VM handle
|
||||
mov eax, [esi+V86_machine.pagedir]
|
||||
call get_pg_addr
|
||||
mov eax, [esi+V86_machine.process]
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax
|
||||
cmp [SLOT_BASE+ecx+APPDATA.process], eax
|
||||
jnz .notcurrent
|
||||
lea eax, [edi+8]
|
||||
cmp al, 10h
|
||||
|
@ -860,7 +846,7 @@ v86_irq2:
|
|||
mov ebx, SLOT_BASE + 0x100
|
||||
mov ecx, [TASK_COUNT]
|
||||
.scan:
|
||||
cmp [ebx+APPDATA.dir_table], eax
|
||||
cmp [ebx+APPDATA.process], eax
|
||||
jnz .cont
|
||||
push ecx
|
||||
mov ecx, [ebx+APPDATA.saved_esp0]
|
||||
|
@ -895,6 +881,7 @@ v86_irq2:
|
|||
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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -140,24 +140,20 @@ end if
|
|||
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 'PS2MOUSE',0
|
||||
szPS2MDriver db '/rd/1/drivers/PS2MOUSE.SYS',0
|
||||
;szCOM_MDriver db 'COM_MOUSE',0
|
||||
szVidintel db 'vidintel',0
|
||||
szVidintel db '/rd/1/drivers/vidintel.sys',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
|
||||
|
||||
|
@ -168,8 +164,10 @@ firstapp db 'LAUNCHER',0
|
|||
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
|
||||
|
@ -179,7 +177,7 @@ kernel_file_load:
|
|||
dd 0 ; subfunction
|
||||
dq 0 ; offset in file
|
||||
dd 0x30000 ; number of bytes to read
|
||||
dd OS_BASE + 0x70000 ; buffer for data
|
||||
dd OS_BASE + 0x71000 ; buffer for data
|
||||
db '/RD/1/KERNEL.MNT',0
|
||||
|
||||
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
|
||||
|
@ -347,6 +345,8 @@ mem_block_list rd 64*2
|
|||
mem_used_list rd 64*2
|
||||
mem_hash_cnt rd 64
|
||||
|
||||
thr_slot_map rd 8
|
||||
|
||||
cpu_freq rq 1
|
||||
|
||||
heap_mutex MUTEX
|
||||
|
@ -378,12 +378,14 @@ _display display_t
|
|||
_WinMapAddress rd 1
|
||||
_WinMapSize rd 1
|
||||
|
||||
LFBAddress rd 1
|
||||
LFBAddress dd ?
|
||||
Screen_Max_X dd ?
|
||||
Screen_Max_Y dd ?
|
||||
|
||||
SCR_MODE rw 2
|
||||
|
||||
PUTPIXEL rd 1
|
||||
GETPIXEL rd 1
|
||||
PUTPIXEL dd ?
|
||||
GETPIXEL dd ?
|
||||
|
||||
if VESA_1_2_VIDEO
|
||||
BANK_SWITCH rd 1 reserved for vesa 1.2
|
||||
|
@ -399,7 +401,7 @@ d_width_calc_area rd 1140
|
|||
|
||||
mouseunder rd 16*24
|
||||
|
||||
MOUSE_PICTURE rd 1
|
||||
MOUSE_PICTURE dd ?
|
||||
|
||||
MOUSE_SCROLL_H rw 1
|
||||
MOUSE_X: rw 1
|
||||
|
@ -436,14 +438,15 @@ proc_mem_map rd 1
|
|||
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
|
||||
|
||||
LFBSize rd 1
|
||||
|
||||
current_slot rd 1
|
||||
current_process rd 1
|
||||
current_slot rd 1 ; i.e. cureent thread
|
||||
|
||||
|
||||
; status
|
||||
hd1_status rd 1 ; 0 - free : other - pid
|
||||
|
@ -460,8 +463,6 @@ cdid rd 1
|
|||
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
|
||||
|
@ -494,63 +495,12 @@ BgrDataHeight rd 1
|
|||
|
||||
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
|
||||
|
||||
|
@ -575,16 +525,21 @@ end if
|
|||
|
||||
org (OS_BASE+0x0100000)
|
||||
|
||||
RAMDISK: rb 2880*512
|
||||
rb 2856*4 ; not used
|
||||
; 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 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
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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
|
||||
|
@ -37,7 +47,8 @@ if preboot_blogesc
|
|||
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
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2008-2011. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2008-2014. 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
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2009-2011. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2009-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4850 $
|
||||
|
||||
|
||||
; Query physical memory map from BIOS.
|
||||
; diamond, 2009
|
||||
|
||||
|
|
|
@ -17,93 +17,192 @@ $Revision$
|
|||
;****************************************************
|
||||
;* ПОИСК HDD и CD *
|
||||
;****************************************************
|
||||
cmp [IDEContrProgrammingInterface], 0
|
||||
cmp [ecx+IDE_DATA.ProgrammingInterface], 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_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
|
||||
call FindHDD_2
|
||||
|
||||
mov [DiskNumber], 1
|
||||
call FindHDD_3
|
||||
; mov al,[Sector512+176]
|
||||
; mov [DRIVE_DATA+7],al
|
||||
call FindHDD_2
|
||||
|
||||
inc [ChannelNumber]
|
||||
|
||||
mov [DiskNumber], 0
|
||||
call FindHDD_3
|
||||
; mov al,[Sector512+176]
|
||||
; mov [DRIVE_DATA+8],al
|
||||
call FindHDD_2
|
||||
|
||||
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 FindHDD_2
|
||||
jne .FindCD
|
||||
|
||||
cmp [Sector512+6], word 16
|
||||
ja FindHDD_2
|
||||
ja .FindCD
|
||||
|
||||
cmp [Sector512+12], word 255
|
||||
ja FindHDD_2
|
||||
inc byte [DRIVE_DATA+1]
|
||||
jmp Print_Device_Name
|
||||
FindHDD_2:
|
||||
ja .FindCD
|
||||
|
||||
inc byte [ebx+DRIVE_DATA]
|
||||
jmp .Print_Device_Name
|
||||
;--------------------------------------
|
||||
.FindCD:
|
||||
push ebx ecx
|
||||
call DeviceReset
|
||||
pop ecx ebx
|
||||
cmp [DevErrorCode], 0
|
||||
jne FindHDD_2_2
|
||||
jne .end
|
||||
|
||||
push ebx ecx
|
||||
call ReadCD_ID
|
||||
pop ecx ebx
|
||||
cmp [DevErrorCode], 0
|
||||
jne FindHDD_2_2
|
||||
inc byte [DRIVE_DATA+1]
|
||||
inc byte [DRIVE_DATA+1]
|
||||
Print_Device_Name:
|
||||
jne .end
|
||||
|
||||
add [ebx+DRIVE_DATA], byte 2
|
||||
;--------------------------------------
|
||||
.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 mode %x\n", eax
|
||||
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
|
||||
|
||||
mov ax, [Sector512+63*2]
|
||||
DEBUGF 1, "K : Multiword DMA mode %x\n", eax
|
||||
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
|
||||
|
||||
mov ax, [Sector512+88*2]
|
||||
DEBUGF 1, "K : Ultra DMA mode %x\n", eax
|
||||
FindHDD_2_2:
|
||||
ret
|
||||
DEBUGF 1, "K : Ultra DMA possible modes %x\n", al
|
||||
|
||||
FindHDD_3:
|
||||
call FindHDD_1
|
||||
shl byte [DRIVE_DATA+1], 2
|
||||
ret
|
||||
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
|
||||
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:
|
||||
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
|
||||
;-----------------------------------------------------------------------------
|
||||
;*************************************************
|
||||
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
|
@ -119,32 +218,32 @@ ReadHDD_ID:
|
|||
; Послать команду идентификации устройства
|
||||
mov [ATAFeatures], 0
|
||||
mov [ATAHead], 0
|
||||
mov [ATACommand], 0ECh
|
||||
mov [ATACommand], 0xEC
|
||||
call SendCommandToHDD
|
||||
cmp [DevErrorCode], 0;проверить код ошибки
|
||||
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 AX,DS
|
||||
; mov ES,AX
|
||||
mov EDI, Sector512 ;offset Sector512
|
||||
mov DX, [ATABasePortAddr];регистр данных
|
||||
mov CX, 256 ;число считываемых слов
|
||||
mov edi, Sector512
|
||||
mov dx, [ATABasePortAddr];регистр данных
|
||||
mov cx, 256 ;число считываемых слов
|
||||
rep insw ;принять блок данных
|
||||
ret
|
||||
; Записать код ошибки
|
||||
|
@ -155,34 +254,32 @@ ReadHDD_ID:
|
|||
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
|
||||
;-----------------------------------------------------------------------------
|
||||
;****************************************************
|
||||
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
|
@ -207,89 +304,85 @@ SendCommandToHDD:
|
|||
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], 0Fh;проверить номер головки
|
||||
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 ;проверить номер головки
|
||||
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
|
||||
ret
|
||||
; Записать код ошибки
|
||||
@@Err1:
|
||||
mov [DevErrorCode], 1
|
||||
mov [DevErrorCode], 7
|
||||
ret
|
||||
@@Err2:
|
||||
mov [DevErrorCode], 2
|
||||
|
@ -304,7 +397,7 @@ SendCommandToHDD:
|
|||
mov [DevErrorCode], 5
|
||||
; Завершение работы программы
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
;*************************************************
|
||||
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
|
@ -323,33 +416,32 @@ ReadCD_ID:
|
|||
mov [ATASectorNumber], 0
|
||||
mov [ATACylinder], 0
|
||||
mov [ATAHead], 0
|
||||
mov [ATACommand], 0A1h
|
||||
mov [ATACommand], 0xA1
|
||||
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 AX,DS
|
||||
; mov ES,AX
|
||||
mov EDI, Sector512 ;offset Sector512
|
||||
mov DX, [ATABasePortAddr];порт 1x0h
|
||||
mov CX, 256;число считываемых слов
|
||||
mov edi, Sector512 ;offset Sector512
|
||||
mov dx, [ATABasePortAddr];порт 1x0h
|
||||
mov cx, 256;число считываемых слов
|
||||
rep insw
|
||||
ret
|
||||
; Записать код ошибки
|
||||
|
@ -360,7 +452,7 @@ ReadCD_ID:
|
|||
mov [DevErrorCode], 6
|
||||
@@End_1:
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
;*************************************************
|
||||
;* СБРОС УСТРОЙСТВА *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
|
@ -370,39 +462,40 @@ ReadCD_ID:
|
|||
;*************************************************
|
||||
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, 08h
|
||||
inc DX ;регистр команд
|
||||
out DX, AL
|
||||
mov al, 0x8
|
||||
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
|
||||
|
@ -418,6 +511,5 @@ DeviceReset:
|
|||
mov [DevErrorCode], 4
|
||||
; Записать код ошибки
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
EndFindHDD:
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
$Revision$
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
pusha
|
||||
|
||||
mov eax, [pg_data.pages_free]
|
||||
|
@ -20,89 +21,167 @@ $Revision$
|
|||
; 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 @f
|
||||
mov eax, 128*1024
|
||||
@@:
|
||||
.continue:
|
||||
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
|
||||
jae .continue
|
||||
|
||||
test byte [DRIVE_DATA+1], 2
|
||||
je .ide2
|
||||
mov esi, cache_ide3
|
||||
call get_cache_ide
|
||||
.ide2:
|
||||
test byte [DRIVE_DATA+1], 8
|
||||
je .ide1
|
||||
mov esi, cache_ide2
|
||||
call get_cache_ide
|
||||
.ide1:
|
||||
test byte [DRIVE_DATA+1], 0x20
|
||||
je .ide0
|
||||
mov esi, cache_ide1
|
||||
call get_cache_ide
|
||||
.ide0:
|
||||
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
|
||||
|
||||
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
|
||||
call get_cache_ide
|
||||
;--------------------------------------
|
||||
@@:
|
||||
jmp end_get_cache
|
||||
test byte [DRIVE_DATA+1], 0x20
|
||||
je @f
|
||||
|
||||
mov esi, cache_ide1
|
||||
call get_cache_ide
|
||||
;--------------------------------------
|
||||
@@:
|
||||
test byte [DRIVE_DATA+1], 8
|
||||
je @f
|
||||
|
||||
mov esi, cache_ide2
|
||||
call get_cache_ide
|
||||
;--------------------------------------
|
||||
@@:
|
||||
test byte [DRIVE_DATA+1], 2
|
||||
je @f
|
||||
|
||||
mov esi, cache_ide3
|
||||
call get_cache_ide
|
||||
;--------------------------------------
|
||||
@@:
|
||||
test byte [DRIVE_DATA+6], 0x80
|
||||
je @f
|
||||
|
||||
mov esi, cache_ide4
|
||||
call get_cache_ide
|
||||
;--------------------------------------
|
||||
@@:
|
||||
test byte [DRIVE_DATA+6], 0x20
|
||||
je @f
|
||||
|
||||
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+cache_ide0_search_start-cache_ide0], 0
|
||||
and [esi+cache_ide0_appl_search_start-cache_ide0], 0
|
||||
and [esi+IDE_CACHE.search_start], 0
|
||||
and [esi+IDE_CACHE.appl_search_start], 0
|
||||
|
||||
push ecx
|
||||
stdcall kernel_alloc, [esi+cache_ide0_size-cache_ide0]
|
||||
mov [esi+cache_ide0_pointer-cache_ide0], eax
|
||||
; 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
|
||||
pop ecx
|
||||
|
||||
mov edx, eax
|
||||
mov eax, [esi+cache_ide0_size-cache_ide0]
|
||||
mov eax, [esi+IDE_CACHE.size]
|
||||
shr eax, 3
|
||||
mov [esi+cache_ide0_system_data_size-cache_ide0], eax
|
||||
; DEBUGF 1, "K : IDE_CACHE.system_data_size %x\n", eax
|
||||
mov [esi+IDE_CACHE.system_data_size], eax
|
||||
mov ebx, eax
|
||||
imul eax, 7
|
||||
mov [esi+cache_ide0_appl_data_size-cache_ide0], eax
|
||||
; DEBUGF 1, "K : IDE_CACHE.appl_data_size %x\n", eax
|
||||
mov [esi+IDE_CACHE.appl_data_size], eax
|
||||
add ebx, edx
|
||||
mov [esi+cache_ide0_data_pointer-cache_ide0], ebx
|
||||
mov [esi+IDE_CACHE.data_pointer], ebx
|
||||
|
||||
.cd:
|
||||
push ecx
|
||||
mov eax, [esi+cache_ide0_system_data_size-cache_ide0]
|
||||
mov eax, [esi+IDE_CACHE.system_data_size]
|
||||
call calculate_for_cd
|
||||
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
|
||||
add eax, [esi+IDE_CACHE.pointer]
|
||||
mov [esi+IDE_CACHE.system_data], eax
|
||||
mov [esi+IDE_CACHE.system_sad_size], ecx
|
||||
|
||||
push edi
|
||||
mov edi, [esi+cache_ide0_pointer-cache_ide0]
|
||||
mov edi, [esi+IDE_CACHE.pointer]
|
||||
call clear_ide_cache
|
||||
pop edi
|
||||
|
||||
mov eax, [esi+cache_ide0_appl_data_size-cache_ide0]
|
||||
mov eax, [esi+IDE_CACHE.appl_data_size]
|
||||
call calculate_for_cd
|
||||
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
|
||||
add eax, [esi+IDE_CACHE.data_pointer]
|
||||
mov [esi+IDE_CACHE.appl_data], eax
|
||||
mov [esi+IDE_CACHE.appl_sad_size], ecx
|
||||
|
||||
push edi
|
||||
mov edi, [esi+cache_ide0_data_pointer-cache_ide0]
|
||||
mov edi, [esi+IDE_CACHE.data_pointer]
|
||||
call clear_ide_cache
|
||||
pop edi
|
||||
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
calculate_for_cd:
|
||||
push eax
|
||||
mov ebx, eax
|
||||
|
@ -116,7 +195,7 @@ calculate_for_cd:
|
|||
sub eax, ebx
|
||||
dec ecx
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
clear_ide_cache:
|
||||
push eax
|
||||
shl ecx, 1
|
||||
|
@ -125,6 +204,6 @@ clear_ide_cache:
|
|||
rep stosd
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
end_get_cache:
|
||||
popa
|
||||
|
|
|
@ -0,0 +1,464 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 5147 $
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; find the IDE controller in the device list
|
||||
;-----------------------------------------------------------------------------
|
||||
mov ecx, IDE_controller_1
|
||||
mov esi, pcidev_list
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.loop:
|
||||
mov esi, [esi+PCIDEV.fd]
|
||||
cmp esi, pcidev_list
|
||||
jz find_IDE_controller_done
|
||||
|
||||
mov eax, [esi+PCIDEV.class]
|
||||
; shr eax, 4
|
||||
; cmp eax, 0x01018
|
||||
shr eax, 7
|
||||
cmp eax, 0x010180 shr 7
|
||||
jnz .loop
|
||||
;--------------------------------------
|
||||
.found:
|
||||
mov eax, [esi+PCIDEV.class]
|
||||
DEBUGF 1, 'K : IDE controller programming interface %x\n', eax
|
||||
mov [ecx+IDE_DATA.ProgrammingInterface], eax
|
||||
|
||||
mov ah, [esi+PCIDEV.bus]
|
||||
mov al, 2
|
||||
mov bh, [esi+PCIDEV.devfn]
|
||||
;--------------------------------------
|
||||
mov dx, 0x1F0
|
||||
test byte [esi+PCIDEV.class], 1
|
||||
jz @f
|
||||
mov bl, 0x10
|
||||
push eax
|
||||
call pci_read_reg
|
||||
and eax, 0xFFFC
|
||||
mov edx, eax
|
||||
pop eax
|
||||
@@:
|
||||
DEBUGF 1, 'K : BAR0 IDE base addr %x\n', dx
|
||||
mov [StandardATABases], dx
|
||||
mov [ecx+IDE_DATA.BAR0_val], dx
|
||||
;--------------------------------------
|
||||
mov dx, 0x3F4
|
||||
test byte [esi+PCIDEV.class], 1
|
||||
jz @f
|
||||
mov bl, 0x14
|
||||
push eax
|
||||
call pci_read_reg
|
||||
and eax, 0xFFFC
|
||||
mov edx, eax
|
||||
pop eax
|
||||
@@:
|
||||
DEBUGF 1, 'K : BAR1 IDE base addr %x\n', dx
|
||||
mov [ecx+IDE_DATA.BAR1_val], dx
|
||||
;--------------------------------------
|
||||
mov dx, 0x170
|
||||
test byte [esi+PCIDEV.class], 4
|
||||
jz @f
|
||||
mov bl, 0x18
|
||||
push eax
|
||||
call pci_read_reg
|
||||
and eax, 0xFFFC
|
||||
mov edx, eax
|
||||
pop eax
|
||||
@@:
|
||||
DEBUGF 1, 'K : BAR2 IDE base addr %x\n', dx
|
||||
mov [StandardATABases+2], dx
|
||||
mov [ecx+IDE_DATA.BAR2_val], dx
|
||||
;--------------------------------------
|
||||
mov dx, 0x374
|
||||
test byte [esi+PCIDEV.class], 4
|
||||
jz @f
|
||||
mov bl, 0x1C
|
||||
push eax
|
||||
call pci_read_reg
|
||||
and eax, 0xFFFC
|
||||
mov edx, eax
|
||||
pop eax
|
||||
@@:
|
||||
DEBUGF 1, 'K : BAR3 IDE base addr %x\n', dx
|
||||
mov [ecx+IDE_DATA.BAR3_val], dx
|
||||
;--------------------------------------
|
||||
mov bl, 0x20
|
||||
push eax
|
||||
call pci_read_reg
|
||||
and eax, 0xFFFC
|
||||
DEBUGF 1, 'K : BAR4 IDE controller register base addr %x\n', ax
|
||||
mov [ecx+IDE_DATA.RegsBaseAddres], ax
|
||||
pop eax
|
||||
;--------------------------------------
|
||||
mov bl, 0x3C
|
||||
push eax
|
||||
call pci_read_reg
|
||||
and eax, 0xFF
|
||||
DEBUGF 1, 'K : IDE Interrupt %x\n', al
|
||||
mov [ecx+IDE_DATA.Interrupt], ax
|
||||
pop eax
|
||||
|
||||
add ecx, sizeof.IDE_DATA
|
||||
;--------------------------------------
|
||||
jmp .loop
|
||||
;-----------------------------------------------------------------------------
|
||||
uglobal
|
||||
align 4
|
||||
;--------------------------------------
|
||||
IDE_controller_pointer dd ?
|
||||
;--------------------------------------
|
||||
IDE_controller_1 IDE_DATA
|
||||
IDE_controller_2 IDE_DATA
|
||||
IDE_controller_3 IDE_DATA
|
||||
;--------------------------------------
|
||||
cache_ide0 IDE_CACHE
|
||||
cache_ide1 IDE_CACHE
|
||||
cache_ide2 IDE_CACHE
|
||||
cache_ide3 IDE_CACHE
|
||||
cache_ide4 IDE_CACHE
|
||||
cache_ide5 IDE_CACHE
|
||||
cache_ide6 IDE_CACHE
|
||||
cache_ide7 IDE_CACHE
|
||||
cache_ide8 IDE_CACHE
|
||||
cache_ide9 IDE_CACHE
|
||||
cache_ide10 IDE_CACHE
|
||||
cache_ide11 IDE_CACHE
|
||||
;--------------------------------------
|
||||
IDE_device_1 rd 2
|
||||
IDE_device_2 rd 2
|
||||
IDE_device_3 rd 2
|
||||
;--------------------------------------
|
||||
endg
|
||||
;-----------------------------------------------------------------------------
|
||||
; START of initialisation IDE ATA code
|
||||
;-----------------------------------------------------------------------------
|
||||
Init_IDE_ATA_controller:
|
||||
cmp [ecx+IDE_DATA.ProgrammingInterface], 0
|
||||
jne @f
|
||||
|
||||
ret
|
||||
;--------------------------------------
|
||||
@@:
|
||||
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, [ecx+IDE_DATA.BAR1_val] ;0x3F4
|
||||
add dx, 2 ;0x3F6
|
||||
out dx, al
|
||||
mov dx, [ecx+IDE_DATA.BAR3_val] ;0x374
|
||||
add dx, 2 ;0x376
|
||||
out dx, al
|
||||
;-----------------------------------------------------------------------------
|
||||
; set current ata bases
|
||||
@@:
|
||||
mov ax, [ecx+IDE_DATA.BAR0_val]
|
||||
mov [StandardATABases], ax
|
||||
mov ax, [ecx+IDE_DATA.BAR2_val]
|
||||
mov [StandardATABases+2], ax
|
||||
|
||||
mov esi, boot_detecthdcd
|
||||
call boot_log
|
||||
;--------------------------------------
|
||||
include 'dev_hdcd.inc'
|
||||
;--------------------------------------
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
Init_IDE_ATA_controller_2:
|
||||
cmp [ecx+IDE_DATA.ProgrammingInterface], 0
|
||||
jne @f
|
||||
|
||||
ret
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
; test whether it is our interrupt?
|
||||
add dx, 2
|
||||
in al, dx
|
||||
test al, 100b
|
||||
jz @f
|
||||
; clear Bus Master IDE Status register
|
||||
; clear Interrupt bit
|
||||
out dx, al
|
||||
;--------------------------------------
|
||||
@@:
|
||||
add dx, 8
|
||||
; test whether it is our interrupt?
|
||||
in al, dx
|
||||
test al, 100b
|
||||
jz @f
|
||||
; clear Bus Master IDE Status register
|
||||
; clear Interrupt bit
|
||||
out dx, al
|
||||
;--------------------------------------
|
||||
@@:
|
||||
; read status register and remove the interrupt request
|
||||
mov dx, [ecx+IDE_DATA.BAR0_val] ;0x1F0
|
||||
add dx, 0x7 ;0x1F7
|
||||
in al, dx
|
||||
mov dx, [ecx+IDE_DATA.BAR2_val] ;0x170
|
||||
add dx, 0x7 ;0x177
|
||||
in al, dx
|
||||
;-----------------------------------------------------------------------------
|
||||
; push eax edx
|
||||
; mov dx, [ecx+IDE_DATA.RegsBaseAddres]
|
||||
; 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 [ecx+IDE_DATA.RegsBaseAddres], 0
|
||||
; setnz [ecx+IDE_DATA.dma_hdd]
|
||||
;-----------------------------------------------------------------------------
|
||||
; set interrupts for IDE Controller
|
||||
;-----------------------------------------------------------------------------
|
||||
pushfd
|
||||
cli
|
||||
.enable_IDE_interrupt:
|
||||
mov esi, boot_enabling_ide
|
||||
call boot_log
|
||||
; Enable interrupts in IDE controller for DMA
|
||||
xor ebx, ebx
|
||||
cmp ecx, IDE_controller_2
|
||||
jne @f
|
||||
|
||||
add ebx, 5
|
||||
jmp .check_DRIVE_DATA
|
||||
;--------------------------------------
|
||||
@@:
|
||||
cmp ecx, IDE_controller_3
|
||||
jne .check_DRIVE_DATA
|
||||
|
||||
add ebx, 10
|
||||
;--------------------------------------
|
||||
.check_DRIVE_DATA:
|
||||
mov al, 0
|
||||
mov ah, [ebx+DRIVE_DATA+1]
|
||||
test ah, 10100000b ; check for ATAPI devices
|
||||
jz @f
|
||||
;--------------------------------------
|
||||
.ch1_pio_set_ATAPI:
|
||||
DEBUGF 1, "K : IDE CH1 PIO, because ATAPI drive present\n"
|
||||
jmp .ch1_pio_set_for_all
|
||||
;--------------------------------------
|
||||
.ch1_pio_set_no_devices:
|
||||
DEBUGF 1, "K : IDE CH1 PIO because no devices\n"
|
||||
jmp .ch1_pio_set_for_all
|
||||
;-------------------------------------
|
||||
.ch1_pio_set:
|
||||
DEBUGF 1, "K : IDE CH1 PIO because device not support UDMA\n"
|
||||
;-------------------------------------
|
||||
.ch1_pio_set_for_all:
|
||||
mov [ecx+IDE_DATA.dma_hdd_channel_1], al
|
||||
jmp .ch2_check
|
||||
;--------------------------------------
|
||||
@@:
|
||||
xor ebx, ebx
|
||||
call calculate_IDE_device_values_storage
|
||||
|
||||
test ah, 1010000b
|
||||
jz .ch1_pio_set_no_devices
|
||||
|
||||
test ah, 1000000b
|
||||
jz @f
|
||||
|
||||
cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al
|
||||
je .ch1_pio_set
|
||||
|
||||
cmp [ebx+IDE_DEVICE.UDMA_set_mode], al
|
||||
je .ch1_pio_set
|
||||
;--------------------------------------
|
||||
@@:
|
||||
test ah, 10000b
|
||||
jz @f
|
||||
|
||||
add ebx, 2
|
||||
|
||||
cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al
|
||||
je .ch1_pio_set
|
||||
|
||||
cmp [ebx+IDE_DEVICE.UDMA_set_mode], al
|
||||
je .ch1_pio_set
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov dx, [ecx+IDE_DATA.BAR1_val] ;0x3F4
|
||||
add dx, 2 ;0x3F6
|
||||
out dx, al
|
||||
DEBUGF 1, "K : IDE CH1 DMA enabled\n"
|
||||
mov [ecx+IDE_DATA.dma_hdd_channel_1], byte 1
|
||||
;--------------------------------------
|
||||
.ch2_check:
|
||||
test ah, 1010b ; check for ATAPI devices
|
||||
jz @f
|
||||
;--------------------------------------
|
||||
.ch2_pio_set_ATAPI:
|
||||
DEBUGF 1, "K : IDE CH2 PIO, because ATAPI drive present\n"
|
||||
jmp .ch2_pio_set_for_all
|
||||
;--------------------------------------
|
||||
.ch2_pio_set_no_devices:
|
||||
DEBUGF 1, "K : IDE CH2 PIO because no devices\n"
|
||||
jmp .ch2_pio_set_for_all
|
||||
;--------------------------------------
|
||||
.ch2_pio_set:
|
||||
DEBUGF 1, "K : IDE CH2 PIO because device not support UDMA\n"
|
||||
;--------------------------------------
|
||||
.ch2_pio_set_for_all:
|
||||
mov [ecx+IDE_DATA.dma_hdd_channel_2], al
|
||||
jmp .set_interrupts_for_IDE_controllers
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov ebx, 4
|
||||
call calculate_IDE_device_values_storage
|
||||
|
||||
test ah, 101b
|
||||
jz .ch2_pio_set_no_devices
|
||||
|
||||
test ah, 100b
|
||||
jz @f
|
||||
|
||||
cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al
|
||||
je .ch2_pio_set
|
||||
|
||||
cmp [ebx+IDE_DEVICE.UDMA_set_mode], al
|
||||
je .ch2_pio_set
|
||||
;--------------------------------------
|
||||
@@:
|
||||
test ah, 1b
|
||||
jz @f
|
||||
|
||||
add ebx, 2
|
||||
|
||||
cmp [ebx+IDE_DEVICE.UDMA_possible_modes], al
|
||||
je .ch2_pio_set
|
||||
|
||||
cmp [ebx+IDE_DEVICE.UDMA_set_mode], al
|
||||
je .ch2_pio_set
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov dx, [ecx+IDE_DATA.BAR3_val] ;0x374
|
||||
add dx, 2 ;0x376
|
||||
out dx, al
|
||||
DEBUGF 1, "K : IDE CH2 DMA enabled\n"
|
||||
mov [ecx+IDE_DATA.dma_hdd_channel_2], byte 1
|
||||
;--------------------------------------
|
||||
.set_interrupts_for_IDE_controllers:
|
||||
mov esi, boot_set_int_IDE
|
||||
call boot_log
|
||||
;--------------------------------------
|
||||
mov eax, [ecx+IDE_DATA.ProgrammingInterface]
|
||||
; cmp ax, 0x0180
|
||||
; je .pata_ide
|
||||
|
||||
; cmp ax, 0x018a
|
||||
; jne .sata_ide
|
||||
|
||||
test al, 1 ; 0 - legacy PCI mode, 1 - native PCI mode
|
||||
jnz .sata_ide
|
||||
;--------------------------------------
|
||||
.pata_ide:
|
||||
cmp [ecx+IDE_DATA.RegsBaseAddres], 0
|
||||
je .end_set_interrupts
|
||||
|
||||
push ecx
|
||||
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
|
||||
pop ecx
|
||||
|
||||
jmp .end_set_interrupts
|
||||
;--------------------------------------
|
||||
.sata_ide:
|
||||
; cmp ax, 0x0185
|
||||
; je .sata_ide_1
|
||||
|
||||
; cmp ax, 0x018f
|
||||
; jne .end_set_interrupts
|
||||
;--------------------------------------
|
||||
;.sata_ide_1:
|
||||
; Some weird controllers generate an interrupt even if IDE interrupts
|
||||
; are disabled and no IDE devices. For example, notebook ASUS K72F -
|
||||
; IDE controller 010185 generates false interrupt when we work with
|
||||
; the IDE controller 01018f. For this reason, the interrupt handler
|
||||
; does not need to be installed if both channel IDE controller
|
||||
; running in PIO mode.
|
||||
cmp [ecx+IDE_DATA.RegsBaseAddres], 0
|
||||
je .end_set_interrupts
|
||||
|
||||
cmp [ecx+IDE_DATA.dma_hdd_channel_1], 0
|
||||
jne @f
|
||||
|
||||
cmp [ecx+IDE_DATA.dma_hdd_channel_2], 0
|
||||
je .end_set_interrupts
|
||||
;--------------------------------------
|
||||
@@:
|
||||
mov ax, [ecx+IDE_DATA.Interrupt]
|
||||
movzx eax, al
|
||||
push ecx
|
||||
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0
|
||||
pop ecx
|
||||
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [ecx+IDE_DATA.Interrupt]:1, eax
|
||||
;--------------------------------------
|
||||
.end_set_interrupts:
|
||||
popfd
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
; END of initialisation IDE ATA code
|
||||
;-----------------------------------------------------------------------------
|
||||
find_IDE_controller_done:
|
||||
mov ecx, IDE_controller_1
|
||||
mov [IDE_controller_pointer], ecx
|
||||
call Init_IDE_ATA_controller
|
||||
mov ecx, IDE_controller_2
|
||||
mov [IDE_controller_pointer], ecx
|
||||
call Init_IDE_ATA_controller
|
||||
mov ecx, IDE_controller_3
|
||||
mov [IDE_controller_pointer], ecx
|
||||
call Init_IDE_ATA_controller
|
||||
;-----------------------------------------------------------------------------
|
||||
mov esi, boot_getcache
|
||||
call boot_log
|
||||
include 'getcache.inc'
|
||||
;-----------------------------------------------------------------------------
|
||||
mov esi, boot_detectpart
|
||||
call boot_log
|
||||
include 'sear_par.inc'
|
||||
;-----------------------------------------------------------------------------
|
||||
mov esi, boot_init_sys
|
||||
call boot_log
|
||||
call Parser_params
|
||||
|
||||
if ~ defined extended_primary_loader
|
||||
; ramdisk image should be loaded by extended primary loader if it exists
|
||||
; READ RAMDISK IMAGE FROM HD
|
||||
include '../boot/rdload.inc'
|
||||
end if
|
||||
;-----------------------------------------------------------------------------
|
||||
mov ecx, IDE_controller_1
|
||||
mov [IDE_controller_pointer], ecx
|
||||
call Init_IDE_ATA_controller_2
|
||||
mov ecx, IDE_controller_2
|
||||
mov [IDE_controller_pointer], ecx
|
||||
call Init_IDE_ATA_controller_2
|
||||
mov ecx, IDE_controller_3
|
||||
mov [IDE_controller_pointer], ecx
|
||||
call Init_IDE_ATA_controller_2
|
||||
;-----------------------------------------------------------------------------
|
|
@ -8,63 +8,203 @@
|
|||
$Revision$
|
||||
|
||||
search_partitions:
|
||||
push ecx
|
||||
; 1. Fill missing parameters in HD_DATA structures.
|
||||
mov eax, [hd_address_table]
|
||||
mov [hd0_data.hdbase], eax ;0x1f0
|
||||
xor eax, eax
|
||||
mov edx, IDE_controller_1
|
||||
mov ax, [edx + IDE_DATA.BAR0_val]
|
||||
mov [hd0_data.hdbase], eax
|
||||
mov [hd1_data.hdbase], eax
|
||||
mov eax, [hd_address_table+16]
|
||||
mov ax, [edx + IDE_DATA.BAR2_val]
|
||||
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
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+2], al
|
||||
pop ecx ; restore the stack
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2b. /hd1: exists if mask 0x10 in [DRIVE_DATA+1] is set,
|
||||
; data: hd1_data,
|
||||
; number of partitions: [DRIVE_DATA+3]
|
||||
test [DRIVE_DATA+1], byte 0x10
|
||||
jz @f
|
||||
|
||||
push 'hd1'
|
||||
mov eax, esp
|
||||
mov edx, hd1_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+3], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2c. /hd2: exists if mask 4 in [DRIVE_DATA+1] is set,
|
||||
; data: hd2_data,
|
||||
; number of partitions: [DRIVE_DATA+4]
|
||||
test [DRIVE_DATA+1], byte 4
|
||||
jz @f
|
||||
|
||||
push 'hd2'
|
||||
mov eax, esp
|
||||
mov edx, hd2_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+4], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2d. /hd3: exists if mask 1 in [DRIVE_DATA+1] is set,
|
||||
; data: hd3_data,
|
||||
; number of partitions: [DRIVE_DATA+5]
|
||||
test [DRIVE_DATA+1], byte 1
|
||||
jz @f
|
||||
|
||||
push 'hd3'
|
||||
mov eax, esp
|
||||
mov edx, hd3_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+5], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2e. /hd4: exists if mask 0x40 in [DRIVE_DATA+6] is set,
|
||||
; data: hd4_data,
|
||||
; number of partitions: [DRIVE_DATA+7]
|
||||
test [DRIVE_DATA+6], byte 0x40
|
||||
jz @f
|
||||
|
||||
push 'hd4'
|
||||
mov eax, esp ; name
|
||||
mov edx, hd4_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+7], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2f. /hd5: exists if mask 0x10 in [DRIVE_DATA+6] is set,
|
||||
; data: hd5_data,
|
||||
; number of partitions: [DRIVE_DATA+8]
|
||||
test [DRIVE_DATA+6], byte 0x10
|
||||
jz @f
|
||||
|
||||
push 'hd5'
|
||||
mov eax, esp
|
||||
mov edx, hd5_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+8], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2g. /hd6: exists if mask 4 in [DRIVE_DATA+6] is set,
|
||||
; data: hd6_data,
|
||||
; number of partitions: [DRIVE_DATA+9]
|
||||
test [DRIVE_DATA+6], byte 4
|
||||
jz @f
|
||||
|
||||
push 'hd6'
|
||||
mov eax, esp
|
||||
mov edx, hd6_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+9], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2h. /hd7: exists if mask 1 in [DRIVE_DATA+6] is set,
|
||||
; data: hd7_data,
|
||||
; number of partitions: [DRIVE_DATA+10]
|
||||
test [DRIVE_DATA+6], byte 1
|
||||
jz @f
|
||||
|
||||
push 'hd7'
|
||||
mov eax, esp
|
||||
mov edx, hd7_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+10], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2i. /hd8: exists if mask 0x40 in [DRIVE_DATA+11] is set,
|
||||
; data: hd8_data,
|
||||
; number of partitions: [DRIVE_DATA+12]
|
||||
test [DRIVE_DATA+11], byte 0x40
|
||||
jz @f
|
||||
|
||||
push 'hd8'
|
||||
mov eax, esp ; name
|
||||
mov edx, hd8_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+12], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2j. /hd9: exists if mask 0x10 in [DRIVE_DATA+11] is set,
|
||||
; data: hd9_data,
|
||||
; number of partitions: [DRIVE_DATA+13]
|
||||
test [DRIVE_DATA+11], byte 0x10
|
||||
jz @f
|
||||
|
||||
push 'hd9'
|
||||
mov eax, esp
|
||||
mov edx, hd9_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+13], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2k. /hd10: exists if mask 4 in [DRIVE_DATA+11] is set,
|
||||
; data: hd10_data,
|
||||
; number of partitions: [DRIVE_DATA+14]
|
||||
test [DRIVE_DATA+14], byte 4
|
||||
jz @f
|
||||
|
||||
push 'hd10'
|
||||
mov eax, esp
|
||||
mov edx, hd10_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+9], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 2l. /hd11: exists if mask 1 in [DRIVE_DATA+11] is set,
|
||||
; data: hd11_data,
|
||||
; number of partitions: [DRIVE_DATA+15]
|
||||
test [DRIVE_DATA+11], byte 1
|
||||
jz @f
|
||||
|
||||
push 'hd11'
|
||||
mov eax, esp
|
||||
mov edx, hd11_data
|
||||
call ide_disk_add
|
||||
mov [DRIVE_DATA+15], al
|
||||
pop ecx
|
||||
;-----------------------------------------------------------------------------
|
||||
@@:
|
||||
; 3. Notify the system about /bd* disks.
|
||||
; 3a. Check whether there are BIOS disks. If no, skip step 3.
|
||||
|
@ -115,10 +255,10 @@ endg
|
|||
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
|
||||
|
@ -134,6 +274,6 @@ proc ide_disk_add
|
|||
@@:
|
||||
ret
|
||||
endp
|
||||
|
||||
end_search_partitions:
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
end_search_partitions:
|
||||
pop ecx
|
||||
|
|
|
@ -86,9 +86,9 @@
|
|||
* рисуется внешняя рамка цвета, указанного в edi,
|
||||
шириной 1 пиксель
|
||||
* рисуется заголовок - прямоугольник с левым верхним углом (1,1)
|
||||
и правым нижним (xsize-1,min(25,ysize)) цвета, указанного в esi
|
||||
и правым нижним (xsize-1,min(20,ysize-1)) цвета, указанного в esi
|
||||
(с учетом градиента)
|
||||
* если ysize>=26, то закрашивается рабочая область окна -
|
||||
* если ysize>21, то закрашивается рабочая область окна -
|
||||
прямоугольник с левым верхним углом (1,21) и правым нижним
|
||||
(xsize-1,ysize-1) (размерами (xsize-1)*(ysize-21)) - цветом,
|
||||
указанным в edx (с учетом градиента)
|
||||
|
@ -151,7 +151,9 @@
|
|||
Возвращаемое значение:
|
||||
* если буфер пуст, возвращается eax=1
|
||||
* если буфер непуст, то возвращается al=0, ah=код нажатой клавиши,
|
||||
старшее слово регистра eax обнулено
|
||||
биты 16-23 содержат сканкод нажатой клавиши в режиме ASCII,
|
||||
в режме сканкодов биты обнулены.
|
||||
биты 23-31 обнулены
|
||||
* если есть "горячая клавиша", то возвращается
|
||||
al=2, ah=сканкод нажатой клавиши (0 для управляющих клавиш),
|
||||
старшее слово регистра eax содержит состояние управляющих клавиш
|
||||
|
@ -816,9 +818,9 @@
|
|||
вызове, оно может измениться в последующих версиях ядра.
|
||||
|
||||
======================================================================
|
||||
======== Функция 18, подфункция 10 - свернуть окно приложения. =======
|
||||
========= Функция 18, подфункция 10 - свернуть активное окно. ========
|
||||
======================================================================
|
||||
Сворачивает собственное окно.
|
||||
Сворачивает активное окно.
|
||||
Параметры:
|
||||
* eax = 18 - номер функции
|
||||
* ebx = 10 - номер подфункции
|
||||
|
@ -843,8 +845,7 @@
|
|||
* eax = 18 - номер функции
|
||||
* ebx = 11 - номер подфункции
|
||||
* ecx = тип таблицы:
|
||||
* 1 = короткая версия, 10 байт
|
||||
* 2 = полная версия, 65536 байт
|
||||
* 1 = короткая версия, 16 байт
|
||||
* edx = указатель на буфер (в приложении) для таблицы
|
||||
Возвращаемое значение:
|
||||
* функция не возвращает значения
|
||||
|
@ -861,6 +862,8 @@
|
|||
Например, для стандартной конфигурации из одного 1.44-дисковода
|
||||
здесь будет 40h, а для случая 1.2Mb на A: и 1.44Mb на B:
|
||||
значение оказывается 24h.
|
||||
|
||||
Первый контроллер IDE:
|
||||
* +1: byte: информация о жёстких дисках и CD-приводах, AABBCCDD,
|
||||
где AA соответствует контроллеру IDE0, ..., DD - IDE3:
|
||||
* 0 = устройство отсутствует
|
||||
|
@ -869,31 +872,36 @@
|
|||
Например, в случае 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 соответствующий байт
|
||||
нулевой, при наличии показывает число распознанных разделов,
|
||||
которых может и не быть (если носитель не отформатирован или
|
||||
если файловая система не поддерживается). В текущей версии ядра
|
||||
для жёстких дисков поддерживаются только 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
|
||||
* формат дальнейших данных зависит от файловой системы,
|
||||
может меняться с изменениями в ядре и поэтому не описывается
|
||||
для жёстких дисков поддерживаются только FAT12/16/32, NTFS,
|
||||
ext2/3/4 и XFS.
|
||||
|
||||
Замечания:
|
||||
* Короткая таблица может быть использована для получения информации
|
||||
* Таблица может быть использована для получения информации
|
||||
об имеющихся устройствах.
|
||||
|
||||
======================================================================
|
||||
|
@ -1208,20 +1216,6 @@ dd 1675
|
|||
соответствующую текущей стране иконку.
|
||||
* Приложение @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 - установить язык системы. ========
|
||||
======================================================================
|
||||
|
@ -1239,52 +1233,6 @@ dd 1675
|
|||
переменную не использует.
|
||||
* Получить язык системы можно вызовом подфункции 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. ==========
|
||||
|
@ -1315,122 +1263,6 @@ dd 1675
|
|||
* Текущая реализация использует только младший бит ecx.
|
||||
* Получить текущее состояние можно вызовом подфункции 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 - установить системную дату/время. ===========
|
||||
======================================================================
|
||||
|
@ -1493,59 +1325,6 @@ dd 1675
|
|||
с eax=0, если сложение ebx с текущим значением счётчика времени
|
||||
вызовет 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 - извлечь лоток привода диска. ======
|
||||
======================================================================
|
||||
|
@ -1553,7 +1332,9 @@ dd 1675
|
|||
* eax = 24 - номер функции
|
||||
* ebx = 4 - номер подфункции
|
||||
* ecx = номер CD/DVD-диска
|
||||
(от 0=Primary Master до 3=Secondary Slave)
|
||||
от 0=Primary Master до 3=Secondary Slave для первого IDE контр.
|
||||
от 4=Primary Master до 7=Secondary Slave для второго IDE контр.
|
||||
от 8=Primary Master до 11=Secondary Slave для третьего IDE контр.
|
||||
Возвращаемое значение:
|
||||
* функция не возвращает значения
|
||||
Замечания:
|
||||
|
@ -1571,7 +1352,9 @@ dd 1675
|
|||
* eax = 24 - номер функции
|
||||
* ebx = 5 - номер подфункции
|
||||
* ecx = номер CD/DVD-диска
|
||||
(от 0=Primary Master до 3=Secondary Slave)
|
||||
от 0=Primary Master до 3=Secondary Slave для первого IDE контр.
|
||||
от 4=Primary Master до 7=Secondary Slave для второго IDE контр.
|
||||
от 8=Primary Master до 11=Secondary Slave для третьего IDE контр.
|
||||
Возвращаемое значение:
|
||||
* функция не возвращает значения
|
||||
Замечания:
|
||||
|
@ -1648,18 +1431,6 @@ dd 1675
|
|||
(используя описываемую функцию).
|
||||
* Приложение @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 - получить язык системы. =========
|
||||
======================================================================
|
||||
|
@ -1674,42 +1445,6 @@ dd 1675
|
|||
соответствующую иконку (используя описываемую функцию).
|
||||
* Установить язык системы можно вызовом подфункции 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 - получить значение счётчика времени. ===
|
||||
======================================================================
|
||||
|
@ -2543,221 +2278,6 @@ dword-значение цвета 0x00RRGGBB
|
|||
* Если BIOS не поддерживает это расширение, поведение функции
|
||||
эмулируется (через аналоги подфункций функции 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). ==========
|
||||
======================================================================
|
||||
|
@ -4544,12 +4064,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
|
|||
Возвращаемое значение:
|
||||
* eax = socketnum1, -1 для ошибки
|
||||
* ebx = socketnum2, код ошибки в случае ошибки
|
||||
Замечания:
|
||||
|
||||
Optstruct: dd level
|
||||
dd optionname
|
||||
dd optlength
|
||||
db options...
|
||||
|
||||
======================================================================
|
||||
========== Функция -1 - завершить выполнение потока/процесса =========
|
||||
|
|
|
@ -82,9 +82,9 @@ Remarks:
|
|||
* 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(25,ysize)) color indicated in esi
|
||||
right lower (xsize-1,min(20,ysize-1)) color indicated in esi
|
||||
(taking a gradient into account)
|
||||
* if ysize>=26, fill the working area of the window -
|
||||
* if ysize>21, 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,7 +148,10 @@ Parameters:
|
|||
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, high word of eax is zero
|
||||
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
|
||||
* 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
|
||||
|
@ -815,9 +818,9 @@ Remarks:
|
|||
changed in future versions of the kernel.
|
||||
|
||||
======================================================================
|
||||
===== Function 18, subfunction 10 - minimize application window. =====
|
||||
======= Function 18, subfunction 10 - minimize topmost window. =======
|
||||
======================================================================
|
||||
Minimizes the own window.
|
||||
Minimizes the topmost (active) window.
|
||||
Parameters:
|
||||
* eax = 18 - function number
|
||||
* ebx = 10 - subfunction number
|
||||
|
@ -828,8 +831,8 @@ Remarks:
|
|||
keeps position and sizes.
|
||||
* Restoring of an application window occurs at its activation by
|
||||
subfunction 3.
|
||||
* Usually there is no necessity to minimize/restire a window
|
||||
obviously: minimization of a window is carried out by the system
|
||||
* Usually there is no necessity to minimize/restore a window
|
||||
explicitly: 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),
|
||||
|
@ -842,8 +845,7 @@ Parameters:
|
|||
* eax = 18 - function number
|
||||
* ebx = 11 - subfunction number
|
||||
* ecx = type of the table:
|
||||
* 1 = short version, 10 bytes
|
||||
* 2 = full version, 65536 bytes
|
||||
* 1 = short version, 16 bytes
|
||||
* edx = pointer to the buffer (in the application) for the table
|
||||
Returned value:
|
||||
* function does not return value
|
||||
|
@ -859,42 +861,49 @@ Format of the table: short version:
|
|||
* 5 = 2.88Mb, 3.5'' (such drives are not used anymore)
|
||||
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.
|
||||
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 is absent
|
||||
* 0 = device not found
|
||||
* 1 = hard drive
|
||||
* 2 = CD-drive
|
||||
For example, in the case HD on IDE0 and CD on IDE2
|
||||
this field contains 48h.
|
||||
* +2: 4 db: number of the retrieved partitions on hard disks
|
||||
at accordingly IDE0,...,IDE3.
|
||||
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 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
|
||||
supports only FAT12/16/32, NTFS, ext2/3/4 and XFS for hard disks.
|
||||
|
||||
Remarks:
|
||||
* The short table can be used for obtaining the information about
|
||||
* The table can be used for obtaining the information about
|
||||
available devices.
|
||||
|
||||
======================================================================
|
||||
|
@ -1208,19 +1217,6 @@ Remarks:
|
|||
the corresponding icon.
|
||||
* 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. =========
|
||||
======================================================================
|
||||
|
@ -1238,49 +1234,6 @@ Remarks:
|
|||
use this variable.
|
||||
* 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.
|
||||
======================================================================
|
||||
|
@ -1309,120 +1262,6 @@ Remarks:
|
|||
* The current implementation uses only low bit of ecx.
|
||||
* 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. ================
|
||||
======================================================================
|
||||
|
@ -1484,58 +1323,6 @@ Remarks:
|
|||
if the addition of ebx with the current value of time counter
|
||||
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. =======
|
||||
======================================================================
|
||||
|
@ -1543,7 +1330,9 @@ Parameters:
|
|||
* eax = 24 - function number
|
||||
* ebx = 4 - subfunction number
|
||||
* ecx = position of CD/DVD-drive
|
||||
(from 0=Primary Master to 3=Secondary Slave)
|
||||
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.
|
||||
Returned value:
|
||||
* function does not return value
|
||||
Remarks:
|
||||
|
@ -1561,7 +1350,9 @@ Parameters:
|
|||
* eax = 24 - function number
|
||||
* ebx = 5 - subfunction number
|
||||
* ecx = position of CD/DVD-drive
|
||||
(from 0=Primary Master to 3=Secondary Slave)
|
||||
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.
|
||||
Returned value:
|
||||
* function does not return value
|
||||
Remarks:
|
||||
|
@ -1635,18 +1426,6 @@ Remarks:
|
|||
the corresponding icon (using this function).
|
||||
* 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. =========
|
||||
======================================================================
|
||||
|
@ -1661,41 +1440,6 @@ Remarks:
|
|||
appropriate icon (using this function).
|
||||
* 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. ==
|
||||
======================================================================
|
||||
|
@ -2315,8 +2059,7 @@ Remarks:
|
|||
Parameters:
|
||||
* eax = 48 - function number
|
||||
* ebx = 8 - subfunction number
|
||||
* ecx = pointer to a block for function 58, in
|
||||
which the fields of intermediate buffer and file name are filled
|
||||
* ecx = pointer to filename of the skin
|
||||
Returned value:
|
||||
* eax = 0 - success
|
||||
* otherwise eax = file system error code; if file does not
|
||||
|
@ -2526,219 +2269,6 @@ Remarks:
|
|||
* If BIOS does not support this extension, its behavior is emulated
|
||||
(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). ==========
|
||||
======================================================================
|
||||
|
@ -4502,12 +4032,6 @@ Parameters:
|
|||
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 ===============
|
||||
|
|
|
@ -186,6 +186,7 @@ USB_STATUS_BUFOVERRUN = 12 ; overflow of internal controller buffer
|
|||
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.
|
||||
|
@ -194,6 +195,11 @@ implicitly due to device disconnect, all callback functions are called
|
|||
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.
|
||||
|
|
|
@ -1,148 +1,133 @@
|
|||
; 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
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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
|
||||
{ local first_byte, b
|
||||
virtual at 0
|
||||
db string
|
||||
if offs >= $
|
||||
char = -1
|
||||
else
|
||||
; fetch first byte
|
||||
load first_byte byte from offs
|
||||
load first_byte byte from addrspace: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 offs + 1
|
||||
load b byte from addrspace: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 offs + 1
|
||||
load b byte from addrspace:offs + 1
|
||||
char = (char shl 6) + (b and 0x3F)
|
||||
load b byte from offs + 2
|
||||
load b byte from addrspace: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 offs + 1
|
||||
load b byte from addrspace:offs + 1
|
||||
char = (char shl 6) + (b and 0x3F)
|
||||
load b byte from offs + 2
|
||||
load b byte from addrspace:offs + 2
|
||||
char = (char shl 6) + (b and 0x3F)
|
||||
load b byte from offs + 3
|
||||
load b byte from addrspace:offs + 3
|
||||
char = (char shl 6) + (b and 0x3F)
|
||||
offs = offs + 4
|
||||
else
|
||||
.err Invalid UTF-8 string
|
||||
end if
|
||||
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 virtual
|
||||
while offs < ..addrspace#.size
|
||||
fetch_utf8_char ..addrspace, offs, char
|
||||
if char = 0x2500
|
||||
graph = 0xC4
|
||||
db 0xC4
|
||||
else if char = 0x2502
|
||||
graph = 0xB3
|
||||
db 0xB3
|
||||
else if char = 0x250C
|
||||
graph = 0xDA
|
||||
db 0xDA
|
||||
else if char = 0x2510
|
||||
graph = 0xBF
|
||||
db 0xBF
|
||||
else if char = 0x2514
|
||||
graph = 0xC0
|
||||
db 0xC0
|
||||
else if char = 0x2518
|
||||
graph = 0xD9
|
||||
db 0xD9
|
||||
else if char = 0x252C
|
||||
graph = 0xC2
|
||||
db 0xC2
|
||||
else if char = 0x2534
|
||||
graph = 0xC1
|
||||
db 0xC1
|
||||
else if char = 0x2551
|
||||
graph = 0xBA
|
||||
db 0xBA
|
||||
else if char < 0x80
|
||||
db char
|
||||
else
|
||||
graph = 0
|
||||
encoding char
|
||||
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
|
||||
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
|
||||
declare_encoding cp866
|
||||
{
|
||||
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
|
||||
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
|
||||
declare_encoding latin1
|
||||
{
|
||||
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
|
||||
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
|
||||
declare_encoding cp850
|
||||
{
|
||||
if char = 0xBF
|
||||
db 0xA8
|
||||
else if char = 0xE1
|
||||
db 0xA0
|
||||
|
@ -157,11 +142,4 @@ macro cp850 [arg]
|
|||
else
|
||||
err Failed to convert to CP850
|
||||
end if
|
||||
end while
|
||||
}
|
||||
|
||||
struc cp850 [arg]
|
||||
{
|
||||
common
|
||||
cp850 arg
|
||||
}
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
;; ;;
|
||||
;; Contains ext2 block handling code. ;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under the terms of the new BSD license. ;;
|
||||
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4891 $
|
||||
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Write ext2 block from memory to disk.
|
||||
; Input: eax = i_block (block number in ext2 terms);
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
;; ;;
|
||||
;; Contains ext2 initialization, plus syscall handling code. ;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under the terms of the new BSD license. ;;
|
||||
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 5089 $
|
||||
|
||||
|
||||
include 'ext2.inc'
|
||||
include 'blocks.inc'
|
||||
include 'inode.inc'
|
||||
|
@ -56,6 +59,8 @@ endp
|
|||
;---------------------------------------------------------------------
|
||||
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.
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
;; ;;
|
||||
;; Contains ext2 structures, and macros. ;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under the terms of the new BSD license. ;;
|
||||
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4891 $
|
||||
|
||||
|
||||
; Future jobs for driver, in order of preference:
|
||||
; * clean up existing extents support.
|
||||
; * add b-tree directories support.
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
;; ;;
|
||||
;; Contains ext2 inode handling code. ;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under the terms of the new BSD license. ;;
|
||||
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4891 $
|
||||
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Receives block number from extent-based inode.
|
||||
; Input: ecx = number of block in inode
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
;; ;;
|
||||
;; Contains common resource allocation + freeing code. ;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Distributed under the terms of the new BSD license. ;;
|
||||
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4891 $
|
||||
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; Frees a resource (block/inode).
|
||||
; Input: eax = resource ID.
|
||||
|
|
|
@ -154,6 +154,9 @@ fat_create_partition.return0:
|
|||
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
|
||||
|
|
|
@ -43,6 +43,30 @@ rootdirs:
|
|||
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
|
||||
|
||||
|
@ -57,6 +81,22 @@ virtual_root_query:
|
|||
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
|
||||
|
@ -149,8 +189,8 @@ file_system_lfn:
|
|||
cmp dword [ebx], 1
|
||||
jnz .access_denied
|
||||
xor eax, eax
|
||||
mov ebp, [ebx+12] ;количество блоков для считывания
|
||||
mov edx, [ebx+16] ;куда записывать рузельтат
|
||||
mov ebp, [ebx+12] ;the number of blocks to read
|
||||
mov edx, [ebx+16] ;where to write the result
|
||||
; add edx, std_application_base_address
|
||||
push dword [ebx+4] ; first block
|
||||
mov ebx, [ebx+8] ; flags
|
||||
|
@ -404,8 +444,7 @@ file_system_lfn:
|
|||
fs_NotImplemented:
|
||||
mov eax, 2
|
||||
ret
|
||||
|
||||
;*******************************************************
|
||||
;-----------------------------------------------------------------------------
|
||||
fs_OnCd0:
|
||||
call reserve_cd
|
||||
mov [ChannelNumber], 1
|
||||
|
@ -413,6 +452,7 @@ fs_OnCd0:
|
|||
push 6
|
||||
push 1
|
||||
jmp fs_OnCd
|
||||
;-----------------------------------------------------------------------------
|
||||
fs_OnCd1:
|
||||
call reserve_cd
|
||||
mov [ChannelNumber], 1
|
||||
|
@ -420,6 +460,7 @@ fs_OnCd1:
|
|||
push 4
|
||||
push 2
|
||||
jmp fs_OnCd
|
||||
;-----------------------------------------------------------------------------
|
||||
fs_OnCd2:
|
||||
call reserve_cd
|
||||
mov [ChannelNumber], 2
|
||||
|
@ -427,22 +468,96 @@ fs_OnCd2:
|
|||
push 2
|
||||
push 3
|
||||
jmp fs_OnCd
|
||||
;-----------------------------------------------------------------------------
|
||||
fs_OnCd3:
|
||||
call reserve_cd
|
||||
mov [ChannelNumber], 2
|
||||
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
|
||||
mov bl, [DRIVE_DATA+1]
|
||||
|
||||
push eax
|
||||
mov eax, [cdpos]
|
||||
dec eax
|
||||
shr eax, 2
|
||||
lea eax, [eax*5]
|
||||
mov bl, [eax+DRIVE_DATA+1]
|
||||
pop eax
|
||||
|
||||
shr bl, cl
|
||||
test bl, 2
|
||||
pop ebx ecx
|
||||
|
@ -472,7 +587,7 @@ fs_OnCd:
|
|||
and [cd_status], 0
|
||||
mov dword [image_of_eax], 2 ; not implemented
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
fs_CdServices:
|
||||
dd fs_CdRead
|
||||
dd fs_CdReadFolder
|
||||
|
@ -485,32 +600,74 @@ fs_CdServices:
|
|||
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
|
||||
|
@ -520,8 +677,6 @@ fs_NextCd:
|
|||
clc
|
||||
@@:
|
||||
ret
|
||||
;*******************************************************
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
process_replace_file_name:
|
||||
; in
|
||||
|
|
|
@ -7,18 +7,15 @@
|
|||
|
||||
$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
|
||||
|
@ -26,9 +23,8 @@ reserve_cd:
|
|||
sti
|
||||
call change_task
|
||||
jmp reserve_cd
|
||||
|
||||
reserve_ok2:
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
reserve_ok2:
|
||||
push eax
|
||||
mov eax, [CURRENT_TASK]
|
||||
shl eax, 5
|
||||
|
@ -37,48 +33,105 @@ reserve_cd:
|
|||
pop eax
|
||||
sti
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
reserve_cd_channel:
|
||||
cmp [ChannelNumber], 1
|
||||
jne .IDE_Channel_2
|
||||
.IDE_Channel_1:
|
||||
pushad
|
||||
mov ecx, ide_channel1_mutex
|
||||
call mutex_lock
|
||||
mov [IDE_Channel_1], 1
|
||||
popad
|
||||
ret
|
||||
.IDE_Channel_2:
|
||||
pushad
|
||||
mov ecx, ide_channel2_mutex
|
||||
call mutex_lock
|
||||
mov [IDE_Channel_2], 1
|
||||
popad
|
||||
ret
|
||||
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
|
||||
;--------------------------------------
|
||||
@@:
|
||||
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
|
||||
popad
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
free_cd_channel:
|
||||
cmp [ChannelNumber], 1
|
||||
jne .IDE_Channel_2
|
||||
.IDE_Channel_1:
|
||||
mov [IDE_Channel_1], 0
|
||||
pushad
|
||||
mov ecx, ide_channel1_mutex
|
||||
call mutex_unlock
|
||||
popad
|
||||
ret
|
||||
.IDE_Channel_2:
|
||||
mov [IDE_Channel_2], 0
|
||||
pushad
|
||||
mov ecx, ide_channel2_mutex
|
||||
call mutex_unlock
|
||||
popad
|
||||
ret
|
||||
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
|
||||
;--------------------------------------
|
||||
@@:
|
||||
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
|
||||
;
|
||||
|
@ -91,91 +144,114 @@ endg
|
|||
; 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] ; реальный размер файловой секции
|
||||
mov eax, [edi+10] ; real size of the file section
|
||||
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; читаем сектор файла
|
||||
call ReadCDWRetr ; read sector of file
|
||||
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; читаем сектор файла
|
||||
call ReadCDWRetr ; read sector of file
|
||||
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
|
||||
|
@ -189,19 +265,19 @@ fs_CdRead:
|
|||
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
|
||||
;
|
||||
|
@ -215,30 +291,37 @@ fs_CdRead:
|
|||
; 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] ; размер директрории
|
||||
mov eax, [edi+10] ; directory size
|
||||
;--------------------------------------
|
||||
.doit:
|
||||
; init header
|
||||
push eax ecx
|
||||
|
@ -250,21 +333,23 @@ fs_CdReadFolder:
|
|||
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 ; читаем сектор директории
|
||||
call ReadCDWRetr ; read sector of directory
|
||||
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]
|
||||
|
@ -272,24 +357,30 @@ fs_CdReadFolder:
|
|||
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
|
||||
|
@ -298,189 +389,209 @@ fs_CdReadFolder:
|
|||
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
|
||||
call uni2ansi_char
|
||||
cld
|
||||
stosb
|
||||
; проверка конца файла
|
||||
; check end of file
|
||||
mov ax, [esi]
|
||||
cmp ax, word 3B00h; сепаратор конца файла ';'
|
||||
cmp ax, word 3B00h ; separator end of file ';'
|
||||
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; сепаратор конца файла ';'
|
||||
cmp ax, word 3B00h; separator end of file ';'
|
||||
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:
|
||||
; метка тома не как в FAT, в этом виде отсутсвует
|
||||
; файл не является системным
|
||||
; not as a volume label in the FAT, in this form not available
|
||||
; file is not a system
|
||||
shl eax, 3
|
||||
; файл является скрытым? (атрибут существование)
|
||||
; file is hidden? (attribute of existence)
|
||||
test [ebp-8], byte 1
|
||||
jz .hidden
|
||||
|
||||
inc eax
|
||||
;--------------------------------------
|
||||
.hidden:
|
||||
shl eax, 1
|
||||
; файл всегда только для чтения, так как это CD
|
||||
; file is always read-only, as this 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
|
||||
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
|
||||
|
@ -493,32 +604,31 @@ fs_CdGetFileInfo:
|
|||
pop edi
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------
|
||||
;-----------------------------------------------------------------------------
|
||||
cd_find_lfn:
|
||||
mov [cd_appl_data], 0
|
||||
; in: esi+ebp -> name
|
||||
; out: CF=1 - file not found
|
||||
; else CF=0 and [cd_current_pointer_of_input] direntry
|
||||
push eax esi
|
||||
; 16 сектор начало набора дескрипторов томов
|
||||
|
||||
; Sector 16 - start set of volume descriptors
|
||||
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
|
||||
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]
|
||||
|
@ -529,7 +639,7 @@ cd_find_lfn:
|
|||
mov [CDSectorAddress], eax
|
||||
; mov [CDSectorAddress],dword 15
|
||||
mov [CDDataBuf_pointer], CDDataBuf
|
||||
|
||||
;--------------------------------------
|
||||
.start:
|
||||
inc dword [CDSectorAddress]
|
||||
call ReadCDWRetr;_1
|
||||
|
@ -537,111 +647,128 @@ cd_find_lfn:
|
|||
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
|
||||
|
||||
; параметры root директрории
|
||||
mov eax, [CDDataBuf+0x9c+2]; начало root директрории
|
||||
; parameters of root directory
|
||||
mov eax, [CDDataBuf+0x9c+2]; start of root directory
|
||||
mov [CDSectorAddress], eax
|
||||
mov eax, [CDDataBuf+0x9c+10]; размер root директрории
|
||||
mov eax, [CDDataBuf+0x9c+10]; size of root directory
|
||||
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 ; читаем сектор директории
|
||||
call ReadCDWRetr ; read sector of directory
|
||||
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
|
||||
; искомый элемент цепочки найден
|
||||
.found:
|
||||
; конец пути файла
|
||||
;--------------------------------------
|
||||
; 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] ; начало директории
|
||||
mov eax, [eax+2+8]; размер директории
|
||||
pop dword [CDSectorAddress] ; beginning of the directory
|
||||
mov eax, [eax+2+8] ; size of directory
|
||||
jmp .mainloop
|
||||
; указатель файла найден
|
||||
.done:
|
||||
;--------------------------------------
|
||||
; 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 ; входы закончились?
|
||||
test eax, eax ; entry's is over?
|
||||
jz .next_sector
|
||||
cmp ebp, CDDataBuf+2048 ; буфер закончился?
|
||||
|
||||
cmp ebp, CDDataBuf+2048 ; buffer is over?
|
||||
jae .next_sector
|
||||
|
||||
movzx eax, byte [ebp]
|
||||
add [cd_current_pointer_of_input_2], eax; следующий вход каталога
|
||||
add ebp, 33; указатель установлен на начало имени
|
||||
add [cd_current_pointer_of_input_2], eax ; next entry of directory
|
||||
add ebp, 33; pointer is set to the beginning of the name
|
||||
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
|
||||
|
@ -650,6 +777,7 @@ cd_compare_name:
|
|||
; destroys eax
|
||||
push esi eax edi
|
||||
mov edi, ebp
|
||||
;--------------------------------------
|
||||
.loop:
|
||||
cld
|
||||
lodsb
|
||||
|
@ -666,94 +794,118 @@ cd_compare_name:
|
|||
sub edi, 2
|
||||
scasw
|
||||
jne .name_not_coincide
|
||||
;--------------------------------------
|
||||
.coincides:
|
||||
cmp [esi], byte '/'; разделитель пути, конец имени текущего элемента
|
||||
cmp [esi], byte '/' ; path separator is end of current element
|
||||
je .done
|
||||
cmp [esi], byte 0; разделитель пути, конец имени текущего элемента
|
||||
|
||||
cmp [esi], byte 0 ; path separator end of name
|
||||
je .done
|
||||
|
||||
jmp .loop
|
||||
;--------------------------------------
|
||||
.name_not_coincide:
|
||||
pop edi eax esi
|
||||
stc
|
||||
ret
|
||||
;--------------------------------------
|
||||
.done:
|
||||
; проверка конца файла
|
||||
cmp [edi], word 3B00h; сепаратор конца файла ';'
|
||||
; check end of file
|
||||
cmp [edi], word 3B00h; separator end of file ';'
|
||||
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
|
||||
inc esi
|
||||
clc
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
char_todown:
|
||||
; convert character to uppercase, using cp866 encoding
|
||||
; in: al=symbol
|
||||
; 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
|
||||
; 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
|
||||
;-----------------------------------------------------------------------------
|
||||
|
|
|
@ -152,6 +152,8 @@ ntfs_test_bootsec:
|
|||
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
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 5089 $
|
||||
|
||||
|
||||
include 'xfs.inc'
|
||||
|
||||
;
|
||||
|
@ -15,6 +25,8 @@ include 'xfs.inc'
|
|||
; 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
|
||||
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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.
|
||||
|
|
|
@ -454,7 +454,11 @@ align 4
|
|||
cmp al, 120
|
||||
jae .result ;overflow
|
||||
inc byte[KEY_COUNT]
|
||||
mov [KEY_COUNT+1+eax], dl
|
||||
mov [KEY_BUFF+eax], dl
|
||||
; store empty scancode
|
||||
add eax, 120+2
|
||||
mov [KEY_BUFF+eax], byte 0
|
||||
sub eax, 120+2
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.result:
|
||||
|
|
|
@ -11,7 +11,7 @@ $Revision$
|
|||
include "skindata.inc"
|
||||
|
||||
;skin_data = 0x00778000
|
||||
;------------------------------------------------------------------------------
|
||||
;-----------------------------------------------------------------
|
||||
align 4
|
||||
read_skin_file:
|
||||
stdcall load_file, ebx
|
||||
|
@ -121,7 +121,7 @@ parse_skin_data:
|
|||
lea esi, [ebx+SKIN_PARAMS.dtp.data]
|
||||
mov edi, common_colours
|
||||
mov ecx, [ebx+SKIN_PARAMS.dtp.size]
|
||||
and ecx, 127
|
||||
and ecx, 255
|
||||
rep movsb
|
||||
mov eax, dword[ebx+SKIN_PARAMS.margin.right]
|
||||
mov dword[_skinmargins+0], eax
|
||||
|
|
|
@ -9,7 +9,7 @@ $Revision$
|
|||
|
||||
|
||||
;
|
||||
; WINDOW SKIN DATA
|
||||
; WINDOW SKIN DATA.
|
||||
;
|
||||
|
||||
iglobal
|
||||
|
|
|
@ -26,7 +26,7 @@ macro FuncTable name, table_name, [label]
|
|||
}
|
||||
|
||||
uglobal
|
||||
common_colours rd 32
|
||||
common_colours rd 48
|
||||
draw_limits RECT
|
||||
endg
|
||||
|
||||
|
@ -34,7 +34,7 @@ align 4
|
|||
;------------------------------------------------------------------------------
|
||||
syscall_draw_window: ;///// system function 0 /////////////////////////////////
|
||||
;------------------------------------------------------------------------------
|
||||
;? <description>
|
||||
;? <description>.
|
||||
;------------------------------------------------------------------------------
|
||||
mov eax, edx
|
||||
shr eax, 24
|
||||
|
@ -173,7 +173,10 @@ align 4
|
|||
syscall_display_settings.02:
|
||||
dec ebx
|
||||
mov esi, ecx
|
||||
and edx, 127
|
||||
cmp edx, 192
|
||||
jnae @f
|
||||
mov edx, 192 ; max size
|
||||
@@:
|
||||
mov edi, common_colours
|
||||
mov ecx, edx
|
||||
rep movsb
|
||||
|
@ -183,7 +186,10 @@ syscall_display_settings.02:
|
|||
align 4
|
||||
syscall_display_settings.03:
|
||||
mov edi, ecx
|
||||
and edx, 127
|
||||
cmp edx, 192
|
||||
jnae @f
|
||||
mov edx, 192 ; max size
|
||||
@@:
|
||||
mov esi, common_colours
|
||||
mov ecx, edx
|
||||
rep movsb
|
||||
|
@ -209,7 +215,7 @@ align 4
|
|||
syscall_display_settings.06:
|
||||
xor esi, esi
|
||||
|
||||
mov edi, [_display.width]
|
||||
mov edi, [Screen_Max_X]
|
||||
mov eax, ecx
|
||||
movsx ebx, ax
|
||||
sar eax, 16
|
||||
|
@ -233,7 +239,7 @@ align 4
|
|||
;--------------------------------------
|
||||
align 4
|
||||
.check_horizontal:
|
||||
mov edi, [_display.height]
|
||||
mov edi, [Screen_Max_Y]
|
||||
mov eax, edx
|
||||
movsx ebx, ax
|
||||
sar eax, 16
|
||||
|
@ -294,8 +300,8 @@ align 4
|
|||
syscall_display_settings._.calculate_whole_screen:
|
||||
xor eax, eax
|
||||
xor ebx, ebx
|
||||
mov ecx, [_display.width]
|
||||
mov edx, [_display.height]
|
||||
mov ecx, [Screen_Max_X]
|
||||
mov edx, [Screen_Max_Y]
|
||||
jmp calculatescreen
|
||||
;------------------------------------------------------------------------------
|
||||
align 4
|
||||
|
@ -303,11 +309,9 @@ syscall_display_settings._.redraw_whole_screen:
|
|||
xor eax, eax
|
||||
mov [draw_limits.left], eax
|
||||
mov [draw_limits.top], eax
|
||||
mov eax, [_display.width]
|
||||
dec eax
|
||||
mov eax, [Screen_Max_X]
|
||||
mov [draw_limits.right], eax
|
||||
mov eax, [_display.height]
|
||||
dec eax
|
||||
mov eax, [Screen_Max_Y]
|
||||
mov [draw_limits.bottom], eax
|
||||
mov eax, window_data
|
||||
jmp redrawscreen
|
||||
|
@ -586,9 +590,9 @@ align 4
|
|||
|
||||
mov eax, [edi + WDATA.box.left]
|
||||
add eax, [edi + WDATA.box.width]
|
||||
mov ebx, [_display.width]
|
||||
mov ebx, [Screen_Max_X]
|
||||
cmp eax, ebx
|
||||
jl .fix_vertical
|
||||
jle .fix_vertical
|
||||
mov eax, [edi + WDATA.box.width]
|
||||
sub eax, ebx
|
||||
jle @f
|
||||
|
@ -603,9 +607,9 @@ align 4
|
|||
.fix_vertical:
|
||||
mov eax, [edi + WDATA.box.top]
|
||||
add eax, [edi + WDATA.box.height]
|
||||
mov ebx, [_display.height]
|
||||
mov ebx, [Screen_Max_Y]
|
||||
cmp eax, ebx
|
||||
jl .fix_client_box
|
||||
jle .fix_client_box
|
||||
mov eax, [edi + WDATA.box.height]
|
||||
sub eax, ebx
|
||||
jle @f
|
||||
|
@ -819,12 +823,8 @@ drawwindow_I: ;////////////////////////////////////////////////////////////////
|
|||
jnz .exit
|
||||
|
||||
; does client area have a positive size on screen?
|
||||
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
|
||||
cmp [esi + WDATA.box.height], 21
|
||||
jle .exit
|
||||
|
||||
; okay, let's draw it
|
||||
mov eax, 1
|
||||
|
@ -1718,9 +1718,9 @@ window._.check_window_position: ;//////////////////////////////////////////////
|
|||
mov ecx, [edi + WDATA.box.width]
|
||||
mov edx, [edi + WDATA.box.height]
|
||||
|
||||
mov esi, [_display.width]
|
||||
mov esi, [Screen_Max_X]
|
||||
cmp ecx, esi
|
||||
jae .fix_width_high
|
||||
ja .fix_width_high
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.check_left:
|
||||
|
@ -1732,9 +1732,9 @@ align 4
|
|||
;--------------------------------------
|
||||
align 4
|
||||
.check_height:
|
||||
mov esi, [_display.height]
|
||||
mov esi, [Screen_Max_Y]
|
||||
cmp edx, esi
|
||||
jae .fix_height_high
|
||||
ja .fix_height_high
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.check_top:
|
||||
|
@ -1992,7 +1992,7 @@ align 4
|
|||
|
||||
sub ebp, [ff_xsz]
|
||||
add ebp, [ff_x]
|
||||
add ebp, [_display.width] ; screen.x
|
||||
add ebp, [Screen_Max_X] ; screen.x
|
||||
inc ebp
|
||||
inc ebx
|
||||
cmp ebx, [ff_ysz]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -25,8 +25,6 @@ VKEY_CONTROL = 0000000000001100b
|
|||
VKEY_ALT = 0000000000110000b
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
kb_state dd 0
|
||||
ext_code db 0
|
||||
|
||||
keyboard_mode db 0
|
||||
|
@ -35,7 +33,6 @@ uglobal
|
|||
altmouseb db 0
|
||||
ctrl_alt_del db 0
|
||||
|
||||
kb_lights db 0
|
||||
old_kb_lights db 0
|
||||
|
||||
align 4
|
||||
|
@ -45,6 +42,13 @@ align 4
|
|||
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
|
||||
|
@ -457,19 +461,40 @@ send_scancode:
|
|||
test bl, bl
|
||||
jz .exit.irq1
|
||||
|
||||
test [kb_state], VKEY_NUMLOCK
|
||||
jz .dowrite
|
||||
cmp cl, 0xE0 ; extended keycode
|
||||
jne @f
|
||||
|
||||
cmp ch, 53
|
||||
jne .dowrite
|
||||
|
||||
cmp cl, 0xE0
|
||||
jz .dowrite
|
||||
mov bl, '/'
|
||||
jmp .dowrite
|
||||
@@:
|
||||
|
||||
cmp ch, 55
|
||||
jnz @f
|
||||
jne @f
|
||||
|
||||
mov bl, 0x2A ;*
|
||||
mov bl, '*'
|
||||
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
|
||||
|
||||
|
@ -488,7 +513,19 @@ send_scancode:
|
|||
jae .exit.irq1
|
||||
inc eax
|
||||
mov [KEY_COUNT], al
|
||||
mov [KEY_COUNT+eax], bl
|
||||
; 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
|
||||
.exit.irq1:
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
|
@ -518,9 +555,9 @@ set_lights:
|
|||
ps2_set_lights:
|
||||
stdcall disable_irq, 1
|
||||
mov al, 0xED
|
||||
call kb_write
|
||||
call kb_write_wait_ack
|
||||
mov al, [esp+8]
|
||||
call kb_write
|
||||
call kb_write_wait_ack
|
||||
stdcall enable_irq, 1
|
||||
ret 8
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -24,16 +24,12 @@ $Revision$
|
|||
uglobal
|
||||
;--------------------------------------
|
||||
align 4
|
||||
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
|
||||
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 ?
|
||||
endg
|
||||
|
||||
iglobal
|
||||
|
@ -44,9 +40,12 @@ mouse_speed_factor:
|
|||
dd 3
|
||||
mouse_timer_ticks dd 0
|
||||
endg
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
draw_mouse_under:
|
||||
|
||||
; return old picture
|
||||
cmp [_display.restore_cursor], 0
|
||||
je @F
|
||||
|
@ -57,15 +56,13 @@ draw_mouse_under:
|
|||
stdcall [_display.restore_cursor], eax, ebx
|
||||
popad
|
||||
ret
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
|
||||
@@:
|
||||
pushad
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
;--------------------------------------
|
||||
align 4
|
||||
mres:
|
||||
|
||||
mres:
|
||||
movzx eax, word [X_UNDER]
|
||||
movzx ebx, word [Y_UNDER]
|
||||
add eax, ecx
|
||||
|
@ -97,7 +94,9 @@ mres:
|
|||
jnz mres
|
||||
popad
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
save_draw_mouse:
|
||||
cmp [_display.move_cursor], 0
|
||||
|
@ -111,6 +110,9 @@ save_draw_mouse:
|
|||
push eax
|
||||
push ebx
|
||||
|
||||
; mov ecx, [Screen_Max_X]
|
||||
; inc ecx
|
||||
; mul ecx
|
||||
mov eax, [d_width_calc_area + eax*4]
|
||||
|
||||
add eax, [_WinMapAddress]
|
||||
|
@ -170,11 +172,13 @@ drm:
|
|||
push edx
|
||||
; helloworld
|
||||
push ecx
|
||||
add eax, ecx; save picture under mouse
|
||||
add eax, ecx ; save picture under mouse
|
||||
add ebx, edx
|
||||
push ecx
|
||||
or ecx, 0x04000000 ; don't load to mouseunder area
|
||||
call getpixel
|
||||
push eax ebx edx edi
|
||||
call [GETPIXEL]
|
||||
pop edi edx ebx eax
|
||||
mov [COLOR_TEMP], ecx
|
||||
pop ecx
|
||||
mov eax, edx
|
||||
|
@ -226,7 +230,9 @@ drm:
|
|||
add esp, 8
|
||||
popad
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
combine_colors:
|
||||
; in
|
||||
|
@ -241,7 +247,7 @@ combine_colors:
|
|||
push edx
|
||||
push ecx
|
||||
xor ecx, ecx
|
||||
; byte 2
|
||||
; byte 0
|
||||
mov eax, 0xff
|
||||
sub al, [esi+0]
|
||||
mov ebx, [esp]
|
||||
|
@ -295,7 +301,9 @@ combine_colors:
|
|||
pop ebx
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
check_mouse_area_for_getpixel:
|
||||
; in:
|
||||
|
@ -314,18 +322,18 @@ check_mouse_area_for_getpixel:
|
|||
cmp ebx, ecx
|
||||
ja .no_mouse_area
|
||||
; offset Y
|
||||
sub bx, [Y_UNDER] ;[MOUSE_Y]
|
||||
sub bx, [Y_UNDER] ; [MOUSE_Y]
|
||||
;--------------------------------------
|
||||
; check for X
|
||||
xor ecx, ecx
|
||||
mov cx, [X_UNDER] ;[MOUSE_X]
|
||||
mov cx, [X_UNDER] ; [MOUSE_X]
|
||||
cmp eax, ecx
|
||||
jb .no_mouse_area
|
||||
add ecx, 15 ; mouse cursor X size
|
||||
cmp eax, ecx
|
||||
ja .no_mouse_area
|
||||
; offset X
|
||||
sub ax, [X_UNDER] ;[MOUSE_X]
|
||||
sub ax, [X_UNDER] ; [MOUSE_X]
|
||||
;--------------------------------------
|
||||
; eax = offset x
|
||||
; ebx = offset y
|
||||
|
@ -338,13 +346,14 @@ check_mouse_area_for_getpixel:
|
|||
or ecx, 0xff000000
|
||||
pop ebx eax
|
||||
ret
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.no_mouse_area:
|
||||
|
||||
.no_mouse_area:
|
||||
xor ecx, ecx
|
||||
pop ebx eax
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
check_mouse_area_for_putpixel:
|
||||
; in:
|
||||
|
@ -361,12 +370,12 @@ check_mouse_area_for_putpixel:
|
|||
cmp cx, ax
|
||||
ja .no_mouse_area
|
||||
; offset Y
|
||||
sub cx, [Y_UNDER] ;[MOUSE_Y]
|
||||
sub cx, [Y_UNDER] ; [MOUSE_Y]
|
||||
mov ax, cx
|
||||
shl eax, 16
|
||||
;--------------------------------------
|
||||
|
||||
; check for X
|
||||
mov ax, [X_UNDER] ;[MOUSE_X]
|
||||
mov ax, [X_UNDER] ; [MOUSE_X]
|
||||
shr ecx, 16
|
||||
cmp cx, ax
|
||||
jb .no_mouse_area
|
||||
|
@ -374,9 +383,9 @@ check_mouse_area_for_putpixel:
|
|||
cmp cx, ax
|
||||
ja .no_mouse_area
|
||||
; offset X
|
||||
sub cx, [X_UNDER] ;[MOUSE_X]
|
||||
sub cx, [X_UNDER] ; [MOUSE_X]
|
||||
mov ax, cx
|
||||
;--------------------------------------
|
||||
|
||||
; eax = (offset y) shl 16 + (offset x)
|
||||
|
||||
pop ecx
|
||||
|
@ -384,8 +393,8 @@ check_mouse_area_for_putpixel:
|
|||
push eax ebx
|
||||
|
||||
mov ebx, eax
|
||||
shr ebx, 16 ;y
|
||||
and eax, 0xffff ;x
|
||||
shr ebx, 16 ; y
|
||||
and eax, 0xffff ; x
|
||||
|
||||
shl ebx, 6
|
||||
shl eax, 2
|
||||
|
@ -408,17 +417,15 @@ check_mouse_area_for_putpixel:
|
|||
add esi, 16*24*3
|
||||
call combine_colors
|
||||
pop edi esi
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.end:
|
||||
mov eax, ecx
|
||||
ret
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.no_mouse_area:
|
||||
|
||||
.no_mouse_area:
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
__sys_draw_pointer:
|
||||
pushad
|
||||
|
@ -430,14 +437,14 @@ __sys_draw_pointer:
|
|||
je @f
|
||||
mov [redrawmouse_unconditional], 0
|
||||
jmp redrawmouse
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
@@:
|
||||
cmp eax, ecx
|
||||
jne redrawmouse
|
||||
cmp ebx, edx
|
||||
je nodmp
|
||||
|
||||
;--------------------------------------
|
||||
|
||||
align 4
|
||||
redrawmouse:
|
||||
pushfd
|
||||
|
@ -465,62 +472,62 @@ redrawmouse:
|
|||
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:
|
||||
nodmp:
|
||||
popad
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword
|
||||
proc set_mouse_data stdcall uses edx, 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];[XCoordinate]
|
||||
add ax, [MOUSE_X]
|
||||
cmp ax, 0
|
||||
jge @@M1
|
||||
jge .check_x
|
||||
mov eax, 0
|
||||
jmp @@M2
|
||||
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
|
||||
;--------------------------------------
|
||||
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];[YCoordinate]
|
||||
add ax, [MOUSE_Y]
|
||||
cmp ax, 0
|
||||
jge @@M3
|
||||
jge .check_y
|
||||
mov ax, 0
|
||||
jmp @@M4
|
||||
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
|
||||
;--------------------------------------
|
||||
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
|
||||
|
||||
|
@ -533,7 +540,9 @@ align 4
|
|||
call wakeup_osloop
|
||||
ret
|
||||
endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
mouse_acceleration:
|
||||
push eax
|
||||
|
@ -545,8 +554,5 @@ mouse_acceleration:
|
|||
;push edx
|
||||
imul eax, [mouse_speed_factor]
|
||||
;pop edx
|
||||
;--------------------------------------
|
||||
align 4
|
||||
@@:
|
||||
@@:
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
|
|
|
@ -128,12 +128,12 @@ proc init_mem
|
|||
mov [pg_data.kernel_tables-OS_BASE], edx
|
||||
|
||||
xor eax, eax
|
||||
mov edi, sys_pgdir-OS_BASE
|
||||
mov ecx, 4096/4
|
||||
mov edi, sys_proc-OS_BASE
|
||||
mov ecx, 8192/4
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20)
|
||||
mov edx, (sys_proc-OS_BASE+PROC.pdt_0)+ 0x800; (OS_BASE shr 20)
|
||||
bt [cpu_caps-OS_BASE], CAPS_PSE
|
||||
jnc .no_PSE
|
||||
|
||||
|
@ -177,9 +177,9 @@ proc init_mem
|
|||
dec ecx
|
||||
jnz .map_kernel_tabs
|
||||
|
||||
mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE
|
||||
mov dword [sys_proc-OS_BASE+PROC.pdt_0+(page_tabs shr 20)], sys_proc+PROC.pdt_0+PG_SW-OS_BASE
|
||||
|
||||
mov edi, (sys_pgdir-OS_BASE)
|
||||
mov edi, (sys_proc+PROC.pdt_0-OS_BASE)
|
||||
lea esi, [edi+(OS_BASE shr 20)]
|
||||
movsd
|
||||
movsd
|
||||
|
@ -345,15 +345,13 @@ align 4
|
|||
proc test_cpu
|
||||
locals
|
||||
cpu_type dd ?
|
||||
cpu_id dd ?
|
||||
cpu_Intel dd ?
|
||||
cpu_AMD dd ?
|
||||
endl
|
||||
|
||||
xor eax, eax
|
||||
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
|
||||
|
@ -378,7 +376,6 @@ proc test_cpu
|
|||
pop eax
|
||||
xor eax, ecx
|
||||
je .end_cpuid
|
||||
mov [cpu_id], 1
|
||||
|
||||
xor eax, eax
|
||||
cpuid
|
||||
|
@ -386,13 +383,7 @@ proc test_cpu
|
|||
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
|
||||
|
@ -402,42 +393,26 @@ proc test_cpu
|
|||
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
|
||||
.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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -98,17 +98,35 @@ struct DBG_REGS
|
|||
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
|
||||
|
||||
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
|
||||
list LHEAD ;+16
|
||||
process dd ? ;+24
|
||||
fpu_state dd ? ;+28
|
||||
exc_handler dd ? ;+32
|
||||
except_mask dd ? ;+36
|
||||
pl0_stack dd ? ;+40
|
||||
cursor dd ? ;+44
|
||||
fd_ev dd ? ;+48
|
||||
bk_ev dd ? ;+52
|
||||
|
@ -124,7 +142,7 @@ struct APPDATA
|
|||
wait_test dd ? ;+96 +++
|
||||
wait_param dd ? ;+100 +++
|
||||
tls_base dd ? ;+104
|
||||
dlls_list_ptr dd ? ;+108
|
||||
dd ? ;+108
|
||||
event_filter dd ? ;+112
|
||||
draw_bgr_x dd ? ;+116
|
||||
draw_bgr_y dd ? ;+120
|
||||
|
@ -133,7 +151,7 @@ struct APPDATA
|
|||
wnd_shape dd ? ;+128
|
||||
wnd_shape_scale dd ? ;+132
|
||||
dd ? ;+136
|
||||
mem_size dd ? ;+140
|
||||
dd ? ;+140
|
||||
saved_box BOX ;+144
|
||||
ipc_start dd ? ;+160
|
||||
ipc_size dd ? ;+164
|
||||
|
@ -142,7 +160,7 @@ struct APPDATA
|
|||
terminate_protection dd ? ;+176
|
||||
keyboard_mode db ? ;+180
|
||||
rb 3
|
||||
dir_table dd ? ;+184
|
||||
dd ? ;+184
|
||||
dbg_event_mem dd ? ;+188
|
||||
dbg_regs DBG_REGS ;+192
|
||||
wnd_caption dd ? ;+212
|
||||
|
@ -152,6 +170,36 @@ struct APPDATA
|
|||
|
||||
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
|
||||
|
@ -160,6 +208,7 @@ include "core/sched.inc" ; process scheduling
|
|||
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"
|
||||
|
@ -242,7 +291,6 @@ include "blkdev/bd_drv.inc"
|
|||
|
||||
; CD drive controller
|
||||
|
||||
include "blkdev/cdrom.inc"
|
||||
include "blkdev/cd_drv.inc"
|
||||
|
||||
; Character devices
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 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
|
||||
|
|
|
@ -89,6 +89,12 @@ macro Mov op1,op2,op3 ; op1 = op2 = op3
|
|||
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
|
||||
|
@ -111,10 +117,10 @@ macro list_add_tail new, head
|
|||
|
||||
macro list_del entry
|
||||
{
|
||||
mov edx, [entry+list_fd]
|
||||
mov ecx, [entry+list_bk]
|
||||
mov [edx+list_bk], ecx
|
||||
mov [ecx+list_fd], edx
|
||||
mov edx, [entry+LHEAD.next]
|
||||
mov ecx, [entry+LHEAD.prev]
|
||||
mov [edx+LHEAD.prev], ecx
|
||||
mov [ecx+LHEAD.next], edx
|
||||
}
|
||||
|
||||
; MOV Immediate.
|
||||
|
|
|
@ -1,47 +1,38 @@
|
|||
FASM=fasm
|
||||
FLAGS=-m 65536
|
||||
languages=en|ru|ge|et|sp
|
||||
drivers_src=com_mouse emu10k1x fm801 infinity sis sound vt823x
|
||||
|
||||
.PHONY: all kernel drivers bootloader clean
|
||||
|
||||
all: kernel drivers bootloader
|
||||
|
||||
kernel: check_lang
|
||||
@echo "*** building kernel with language '$(lang)' ..."
|
||||
@mkdir -p bin
|
||||
@echo "lang fix $(lang)" > lang.inc
|
||||
@echo "--- building 'bin/kernel.mnt' ..."
|
||||
@$(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
|
||||
@echo "lang fix $(lang)" > lang.inc
|
||||
@echo "--- building 'bin/boot_fat12.bin' ..."
|
||||
@$(FASM) $(FLAGS) bootloader/boot_fat12.asm bin/boot_fat12.bin
|
||||
@rm -f lang.inc
|
||||
|
||||
|
||||
check_lang:
|
||||
@case "$(lang)" in \
|
||||
$(languages)) \
|
||||
;; \
|
||||
*) \
|
||||
echo "*** error: language is incorrect or not specified"; \
|
||||
exit 1; \
|
||||
;; \
|
||||
esac
|
||||
|
||||
clean:
|
||||
rm -rf bin
|
||||
rm -f lang.inc
|
||||
FASM=fasm
|
||||
FLAGS=-m 65536
|
||||
languages=en|ru|ge|et|sp
|
||||
|
||||
.PHONY: all kernel bootloader clean
|
||||
|
||||
all: kernel bootloader
|
||||
|
||||
kernel: check_lang
|
||||
@echo "*** building kernel with language '$(lang)' ..."
|
||||
@mkdir -p bin
|
||||
@echo "lang fix $(lang)" > lang.inc
|
||||
@echo "--- building 'bin/kernel.mnt' ..."
|
||||
@$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt
|
||||
@rm -f lang.inc
|
||||
|
||||
bootloader: check_lang
|
||||
@echo "*** building bootloader with language '$(lang)' ..."
|
||||
@mkdir -p bin
|
||||
@echo "lang fix $(lang)" > lang.inc
|
||||
@echo "--- building 'bin/boot_fat12.bin' ..."
|
||||
@$(FASM) $(FLAGS) bootloader/boot_fat12.asm bin/boot_fat12.bin
|
||||
@rm -f lang.inc
|
||||
|
||||
|
||||
check_lang:
|
||||
@case "$(lang)" in \
|
||||
$(languages)) \
|
||||
;; \
|
||||
*) \
|
||||
echo "*** error: language is incorrect or not specified"; \
|
||||
exit 1; \
|
||||
;; \
|
||||
esac
|
||||
|
||||
clean:
|
||||
rm -rf bin
|
||||
rm -f lang.inc
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; ARP.INC ;;
|
||||
|
@ -318,10 +318,9 @@ ARP_output_request:
|
|||
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
|
||||
|
||||
lea eax, [ebx + ETH_DEVICE.mac] ; local device mac
|
||||
mov edx, ETH_BROADCAST ; broadcast mac
|
||||
mov ax, ETHER_PROTO_ARP
|
||||
mov ecx, sizeof.ARP_header
|
||||
mov di, ETHER_PROTO_ARP
|
||||
mov edx, ETH_BROADCAST ; broadcast mac
|
||||
call ETH_output
|
||||
jz .exit
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; IPv4.INC ;;
|
||||
|
@ -267,10 +267,9 @@ IPv4_input: ; TODO: add IPv4
|
|||
cmp eax, 224
|
||||
je .ip_ok
|
||||
|
||||
; or a loopback address (127.0.0.0/8)
|
||||
; maybe we just dont have an IP yet and should accept everything on the IP level
|
||||
|
||||
and eax, 0x00ffffff
|
||||
cmp eax, 127
|
||||
cmp [IP_LIST + edi], 0
|
||||
je .ip_ok
|
||||
|
||||
; or it's just not meant for us.. :(
|
||||
|
@ -577,11 +576,11 @@ IPv4_find_fragment_slot:
|
|||
; edx = Source IP
|
||||
; di = TTL shl 8 + protocol
|
||||
;
|
||||
; 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)
|
||||
; 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
|
||||
;
|
||||
;------------------------------------------------------------------
|
||||
align 4
|
||||
|
@ -595,7 +594,6 @@ IPv4_output:
|
|||
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
|
||||
|
||||
|
@ -607,12 +605,11 @@ IPv4_output:
|
|||
|
||||
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 di, ETHER_PROTO_IPv4
|
||||
mov edx, esp
|
||||
call ETH_output
|
||||
jz .eth_error
|
||||
add esp, 6 ; pop the mac out of the stack
|
||||
|
@ -642,18 +639,18 @@ IPv4_output:
|
|||
.eth_error:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ethernet error\n"
|
||||
add esp, 3*4+2+6
|
||||
xor edi, edi
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.arp_error:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
|
||||
add esp, 3*4+2
|
||||
xor edi, edi
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.too_large:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: Packet too large!\n"
|
||||
xor edi, edi
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.loopback:
|
||||
|
@ -675,7 +672,7 @@ IPv4_output:
|
|||
; ecx = data length
|
||||
; esi = data ptr
|
||||
;
|
||||
; OUT: /
|
||||
; OUT: eax = -1 on error
|
||||
;
|
||||
;------------------------------------------------------------------
|
||||
align 4
|
||||
|
@ -699,15 +696,13 @@ IPv4_output_raw:
|
|||
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 di, ETHER_PROTO_IPv4
|
||||
mov edx, esp
|
||||
call ETH_output
|
||||
jz .error
|
||||
|
||||
add esp, 6 ; pop the mac
|
||||
|
||||
mov dword[esp+4+4], edx
|
||||
|
@ -746,7 +741,7 @@ IPv4_output_raw:
|
|||
add esp, 8+4+4
|
||||
.too_large:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n"
|
||||
sub edi, edi
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
|
||||
|
@ -795,13 +790,9 @@ IPv4_fragment:
|
|||
.new_fragment:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
|
||||
|
||||
|
||||
mov eax, [esp + 3*4]
|
||||
mov ax, ETHER_PROTO_IPv4
|
||||
lea ebx, [esp + 4*4]
|
||||
mov di , ETHER_PROTO_IPv4
|
||||
call ETH_output
|
||||
|
||||
cmp edi, -1
|
||||
jz .err
|
||||
|
||||
; copy header
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2012-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2012-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; PPPoE.INC ;;
|
||||
|
@ -14,6 +14,9 @@
|
|||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 5015 $
|
||||
|
||||
|
||||
struct PPPoE_frame
|
||||
VersionAndType db ?
|
||||
Code db ?
|
||||
|
@ -240,17 +243,15 @@ PPPoE_session_input:
|
|||
;
|
||||
; PPPoE_output
|
||||
;
|
||||
; IN:
|
||||
; IN: ax = protocol
|
||||
; 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)
|
||||
; OUT: eax = buffer start / 0 on error
|
||||
; ebx = device ptr
|
||||
; ecx = packet size
|
||||
; edx = size of complete buffer
|
||||
; edi = start of PPP payload
|
||||
;
|
||||
;-----------------------------------------------------------------
|
||||
align 4
|
||||
|
@ -258,13 +259,12 @@ PPPoE_output:
|
|||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: size=%u device=%x\n", ecx, ebx
|
||||
|
||||
pushw di
|
||||
pushw ax
|
||||
pushw [PPPoE_SID]
|
||||
|
||||
lea eax, [ebx + ETH_DEVICE.mac]
|
||||
lea edx, [PPPoE_MAC]
|
||||
mov ax, ETHER_PROTO_PPP_SESSION
|
||||
add ecx, PPPoE_frame.Payload + 2
|
||||
mov di, ETHER_PROTO_PPP_SESSION
|
||||
lea edx, [PPPoE_MAC]
|
||||
call ETH_output
|
||||
jz .eth_error
|
||||
|
||||
|
@ -287,8 +287,7 @@ PPPoE_output:
|
|||
|
||||
.eth_error:
|
||||
add esp, 4
|
||||
xor edi, edi
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; ETHERNET.INC ;;
|
||||
|
@ -86,11 +86,7 @@ ETH_input:
|
|||
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
|
||||
|
@ -102,10 +98,9 @@ ETH_input:
|
|||
ret
|
||||
|
||||
.fail:
|
||||
popf
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
|
||||
|
||||
add esp, sizeof.ETH_queue_entry - 8
|
||||
pop ebx
|
||||
call NET_packet_free
|
||||
add esp, 4
|
||||
|
||||
|
@ -150,14 +145,14 @@ ETH_process_input:
|
|||
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
|
||||
|
||||
|
@ -171,17 +166,16 @@ ETH_process_input:
|
|||
;
|
||||
; ETH_output
|
||||
;
|
||||
; IN: eax = pointer to source mac
|
||||
; IN: ax = protocol
|
||||
; ebx = device ptr
|
||||
; ecx = packet size
|
||||
; ecx = payload size
|
||||
; edx = pointer to destination mac
|
||||
; 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
|
||||
; OUT: eax = start of ethernet frame / 0 on error
|
||||
; ebx = device ptr
|
||||
; ecx = payload size
|
||||
; edx = ethernet frame size
|
||||
; edi = start of ethernet payload
|
||||
;
|
||||
;-----------------------------------------------------------------
|
||||
align 4
|
||||
|
@ -189,11 +183,11 @@ ETH_output:
|
|||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
|
||||
|
||||
cmp ecx, [ebx + NET_DEVICE.mtu]
|
||||
cmp ecx, [ebx + ETH_DEVICE.mtu]
|
||||
ja .exit
|
||||
|
||||
push ecx
|
||||
push di eax edx
|
||||
push ax edx
|
||||
|
||||
add ecx, sizeof.ETH_header
|
||||
stdcall kernel_alloc, ecx
|
||||
|
@ -204,7 +198,7 @@ ETH_output:
|
|||
pop esi
|
||||
movsd
|
||||
movsw
|
||||
pop esi
|
||||
lea esi, [ebx + ETH_DEVICE.mac]
|
||||
movsd
|
||||
movsw
|
||||
pop ax
|
||||
|
@ -227,13 +221,13 @@ ETH_output:
|
|||
|
||||
.out_of_ram:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
|
||||
add esp, 4+4+2+4
|
||||
sub edi, edi
|
||||
add esp, 4+2+4
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.exit:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
|
||||
sub edi, edi
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
|
|
|
@ -294,12 +294,12 @@ ICMP_input:
|
|||
call mutex_unlock
|
||||
popa
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: no socket found\n"
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
|
||||
jmp .dump
|
||||
|
||||
|
||||
.checksum_mismatch:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n"
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
|
||||
|
||||
.dump:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
|
||||
|
|
|
@ -28,7 +28,6 @@ struct queue
|
|||
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
|
||||
|
||||
|
@ -47,18 +46,12 @@ macro add_to_queue ptr, size, entry_size, failaddr {
|
|||
|
||||
local .ok, .no_wrap
|
||||
|
||||
pusha
|
||||
lea ecx, [ptr + queue.mutex]
|
||||
call mutex_lock
|
||||
popa
|
||||
spin_lock_irqsave
|
||||
|
||||
cmp [ptr + queue.size], size ; Check if queue isnt full
|
||||
jb .ok
|
||||
|
||||
pusha
|
||||
lea ecx, [ptr + queue.mutex]
|
||||
call mutex_unlock
|
||||
popa
|
||||
spin_unlock_irqrestore
|
||||
jmp failaddr
|
||||
|
||||
.ok:
|
||||
|
@ -76,10 +69,7 @@ local .ok, .no_wrap
|
|||
.no_wrap:
|
||||
mov [ptr + queue.w_ptr], edi
|
||||
|
||||
pusha
|
||||
lea ecx, [ptr + queue.mutex]
|
||||
call mutex_unlock
|
||||
popa
|
||||
spin_unlock_irqrestore
|
||||
|
||||
}
|
||||
|
||||
|
@ -89,18 +79,12 @@ macro get_from_queue ptr, size, entry_size, failaddr {
|
|||
|
||||
local .ok, .no_wrap
|
||||
|
||||
pusha
|
||||
lea ecx, [ptr + queue.mutex]
|
||||
call mutex_lock
|
||||
popa
|
||||
spin_lock_irqsave
|
||||
|
||||
cmp [ptr + queue.size], 0 ; any packets queued?
|
||||
ja .ok
|
||||
|
||||
pusha
|
||||
lea ecx, [ptr + queue.mutex]
|
||||
call mutex_unlock
|
||||
popa
|
||||
spin_unlock_irqrestore
|
||||
jmp failaddr
|
||||
|
||||
.ok:
|
||||
|
@ -122,10 +106,7 @@ local .ok, .no_wrap
|
|||
|
||||
pop esi
|
||||
|
||||
pusha
|
||||
lea ecx, [ptr + queue.mutex]
|
||||
call mutex_unlock
|
||||
popa
|
||||
spin_unlock_irqrestore
|
||||
|
||||
}
|
||||
|
||||
|
@ -136,6 +117,4 @@ macro init_queue ptr {
|
|||
mov [ptr + queue.w_ptr], edi
|
||||
mov [ptr + queue.r_ptr], edi
|
||||
|
||||
lea ecx, [ptr + queue.mutex]
|
||||
call mutex_init
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; Part of the TCP/IP network stack for KolibriOS ;;
|
||||
|
@ -293,6 +293,7 @@ SOCKET_open:
|
|||
push ecx edx esi
|
||||
call SOCKET_alloc
|
||||
pop esi edx ecx
|
||||
test eax, eax
|
||||
jz .nobuffs
|
||||
|
||||
mov [esp+32], edi ; return socketnumber
|
||||
|
@ -697,7 +698,7 @@ SOCKET_close:
|
|||
|
||||
test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state?
|
||||
jz @f
|
||||
call SOCKET_notify.unblock ; Unblock it.
|
||||
call SOCKET_notify ; Unblock it.
|
||||
@@:
|
||||
|
||||
cmp [eax + SOCKET.Domain], AF_INET4
|
||||
|
@ -1192,6 +1193,7 @@ SOCKET_pair:
|
|||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n"
|
||||
|
||||
call SOCKET_alloc
|
||||
test eax, eax
|
||||
jz .nomem1
|
||||
mov [esp+32], edi ; application's eax
|
||||
|
||||
|
@ -1204,6 +1206,7 @@ SOCKET_pair:
|
|||
mov ebx, eax
|
||||
|
||||
call SOCKET_alloc
|
||||
test eax, eax
|
||||
jz .nomem2
|
||||
mov [esp+20], edi ; application's ebx
|
||||
|
||||
|
@ -1220,10 +1223,13 @@ SOCKET_pair:
|
|||
|
||||
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
|
||||
pop eax
|
||||
test eax, eax
|
||||
jz .nomem2
|
||||
|
||||
ret
|
||||
|
||||
|
@ -1465,7 +1471,8 @@ SOCKET_input:
|
|||
|
||||
;--------------------------
|
||||
;
|
||||
; eax = ptr to ring struct (just a buffer of the right size)
|
||||
; IN: eax = ptr to ring struct (just a buffer of the right size)
|
||||
; OUT: eax = unchanged / 0 on error
|
||||
;
|
||||
align 4
|
||||
SOCKET_ring_create:
|
||||
|
@ -1476,6 +1483,8 @@ SOCKET_ring_create:
|
|||
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
|
||||
|
||||
|
@ -1493,6 +1502,7 @@ SOCKET_ring_create:
|
|||
mov eax, esi
|
||||
pop esi
|
||||
|
||||
.fail:
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
|
@ -1536,6 +1546,7 @@ SOCKET_ring_write:
|
|||
jb @f
|
||||
sub edi, SOCKET_MAXDATA ; WRAP
|
||||
@@:
|
||||
|
||||
mov [eax + RING_BUFFER.write_ptr], edi
|
||||
pop edi
|
||||
|
||||
|
@ -1707,8 +1718,9 @@ SOCKET_block:
|
|||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
|
||||
|
||||
pushf
|
||||
push eax
|
||||
|
||||
pushf
|
||||
cli
|
||||
|
||||
; Set the 'socket is blocked' flag
|
||||
|
@ -1724,12 +1736,12 @@ SOCKET_block:
|
|||
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: continueing\n"
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continuing\n"
|
||||
|
||||
ret
|
||||
|
||||
|
@ -1752,70 +1764,54 @@ SOCKET_notify:
|
|||
call SOCKET_check
|
||||
jz .error
|
||||
|
||||
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
|
||||
; Find the associated thread's TASK_DATA
|
||||
push ebx ecx esi
|
||||
mov ebx, [eax + SOCKET.TID]
|
||||
test ebx, ebx
|
||||
jz .error2
|
||||
xor ecx, ecx
|
||||
inc ecx
|
||||
mov esi, TASK_DATA
|
||||
.next:
|
||||
cmp [esi + TASKDATA.pid], eax
|
||||
cmp [esi + TASKDATA.pid], ebx
|
||||
je .found
|
||||
inc ecx
|
||||
add esi, 0x20
|
||||
cmp ecx, [TASK_COUNT]
|
||||
jbe .next
|
||||
jmp .error
|
||||
.found:
|
||||
|
||||
; Run the thread
|
||||
mov [esi + TASKDATA.state], 0 ; Running
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n"
|
||||
|
||||
.done:
|
||||
pop esi ecx eax
|
||||
.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
|
||||
|
||||
.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
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax
|
||||
pop esi ecx ebx
|
||||
ret
|
||||
|
||||
|
||||
.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
|
||||
ret
|
||||
|
||||
|
||||
|
@ -1830,7 +1826,6 @@ SOCKET_notify:
|
|||
; IN: /
|
||||
; OUT: eax = 0 on error, socket ptr otherwise
|
||||
; edi = socket number
|
||||
; ZF = cleared on error
|
||||
;
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
|
@ -1917,7 +1912,6 @@ SOCKET_alloc:
|
|||
@@:
|
||||
|
||||
mov [net_sockets + SOCKET.NextPtr], eax
|
||||
or eax, eax ; used to clear zero flag
|
||||
|
||||
pusha
|
||||
mov ecx, socket_mutex
|
||||
|
@ -1968,8 +1962,14 @@ SOCKET_free:
|
|||
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,6 +2022,7 @@ SOCKET_fork:
|
|||
push ebx
|
||||
call SOCKET_alloc
|
||||
pop ebx
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
push eax
|
||||
|
@ -2101,7 +2102,8 @@ SOCKET_num_to_ptr:
|
|||
call mutex_unlock
|
||||
popa
|
||||
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: not found\n", eax
|
||||
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]
|
||||
ret
|
||||
|
||||
|
||||
|
@ -2210,6 +2212,8 @@ SOCKET_check_owner:
|
|||
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
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ SS_MORETOCOME = 0x4000
|
|||
SS_BLOCKED = 0x8000
|
||||
|
||||
|
||||
SOCKET_MAXDATA = 4096*8 ; must be 4096*(power of 2) where 'power of 2' is at least 8
|
||||
SOCKET_MAXDATA = 4096*64 ; 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,10 +313,15 @@ stack_handler:
|
|||
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
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; Part of the TCP/IP network stack for KolibriOS ;;
|
||||
|
@ -96,6 +96,7 @@ TCP_RTTVAR_SHIFT = 2
|
|||
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
|
||||
|
||||
|
@ -119,13 +120,13 @@ ends
|
|||
|
||||
struct TCP_queue_entry
|
||||
|
||||
ip_ptr dd ?
|
||||
segment_ptr dd ?
|
||||
segment_size dd ?
|
||||
device_ptr dd ?
|
||||
ip_ptr dd ?
|
||||
segment_ptr dd ?
|
||||
segment_size dd ?
|
||||
device_ptr dd ?
|
||||
|
||||
buffer_ptr dd ?
|
||||
timestamp dd ?
|
||||
buffer_ptr dd ?
|
||||
timestamp dd ?
|
||||
|
||||
ends
|
||||
|
||||
|
@ -141,6 +142,7 @@ align 4
|
|||
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
|
||||
|
@ -224,7 +226,15 @@ macro TCP_init {
|
|||
call new_sys_threads
|
||||
test eax, eax
|
||||
jns @f
|
||||
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP, error %d\n', eax
|
||||
DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for TCP input, 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
|
||||
@@:
|
||||
|
||||
}
|
||||
|
@ -264,6 +274,8 @@ TCP_api:
|
|||
jz .packets_missed ; 2
|
||||
dec bl
|
||||
jz .packets_dumped ; 3
|
||||
dec bl
|
||||
jz .packets_queued ; 4
|
||||
|
||||
.error:
|
||||
mov eax, -1
|
||||
|
@ -284,3 +296,7 @@ TCP_api:
|
|||
.packets_dumped:
|
||||
mov eax, [TCP_segments_dumped + eax]
|
||||
ret
|
||||
|
||||
.packets_queued:
|
||||
mov eax, [TCP_queue + queue.size]
|
||||
ret
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; Part of the TCP/IP network stack for KolibriOS ;;
|
||||
;; ;;
|
||||
;; Written by hidnplayr@kolibrios.org ;;
|
||||
;; ;;
|
||||
;; Based on the code of 4.4BSD ;;
|
||||
;; Based on the algorithms used in 4.4BSD ;;
|
||||
;; ;;
|
||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||
;; Version 2, June 1991 ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 3407 $
|
||||
$Revision: 5155 $
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
|
@ -43,11 +43,7 @@ TCP_input:
|
|||
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
|
||||
|
@ -62,7 +58,6 @@ TCP_input:
|
|||
ret
|
||||
|
||||
.fail:
|
||||
popf
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
|
||||
|
||||
call NET_ptr_to_num4
|
||||
|
@ -536,11 +531,9 @@ endl
|
|||
cmp eax, [ebx + TCP_SOCKET.SND_UNA]
|
||||
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
|
||||
; - The reassembly list of out-of-order segments for the connection is empty.
|
||||
cmp [ebx + TCP_SOCKET.seg_next], 0
|
||||
jne .not_uni_xfer
|
||||
|
||||
; Complete processing of received data
|
||||
|
||||
|
@ -845,7 +838,7 @@ endl
|
|||
pop word [ebx + TCP_SOCKET.SND_SCALE]
|
||||
@@:
|
||||
|
||||
;;; TODO: call TCP_reassemble
|
||||
call TCP_reassemble
|
||||
|
||||
mov eax, [edx + TCP_header.SequenceNumber]
|
||||
dec eax
|
||||
|
@ -1099,8 +1092,7 @@ endl
|
|||
pop ebx edx ecx
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is acked\n"
|
||||
stc
|
||||
|
||||
or [temp_bits], TCP_BIT_FIN_IS_ACKED
|
||||
jmp .wakeup
|
||||
|
||||
.finiacked:
|
||||
|
@ -1114,19 +1106,15 @@ endl
|
|||
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]
|
||||
|
@ -1134,8 +1122,6 @@ endl
|
|||
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
|
||||
|
@ -1158,7 +1144,8 @@ endl
|
|||
|
||||
|
||||
.ack_fw1:
|
||||
jnc .ack_processed
|
||||
test [temp_bits], TCP_BIT_FIN_IS_ACKED
|
||||
jz .ack_processed
|
||||
|
||||
test [ebx + SOCKET.state], SS_CANTRCVMORE
|
||||
jnz @f
|
||||
|
@ -1171,7 +1158,8 @@ endl
|
|||
jmp .ack_processed
|
||||
|
||||
.ack_c:
|
||||
jnc .ack_processed
|
||||
test [temp_bits], TCP_BIT_FIN_IS_ACKED
|
||||
jz .ack_processed
|
||||
|
||||
mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
|
||||
mov eax, ebx
|
||||
|
@ -1183,7 +1171,8 @@ endl
|
|||
jmp .ack_processed
|
||||
|
||||
.ack_la:
|
||||
jnc .ack_processed
|
||||
test [temp_bits], TCP_BIT_FIN_IS_ACKED
|
||||
jz .ack_processed
|
||||
|
||||
push ebx
|
||||
lea ecx, [ebx + SOCKET.mutex]
|
||||
|
@ -1246,9 +1235,13 @@ align 4
|
|||
|
||||
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
|
||||
|
||||
|
@ -1257,7 +1250,7 @@ align 4
|
|||
call SOCKET_notify
|
||||
popa
|
||||
|
||||
jmp .trim_then_step6
|
||||
jmp .trim
|
||||
|
||||
;------------
|
||||
; Active Open
|
||||
|
@ -1350,9 +1343,9 @@ align 4
|
|||
|
||||
mov eax, [ebx + TCP_SOCKET.t_rtt]
|
||||
test eax, eax
|
||||
je .trim_then_step6
|
||||
je .trim
|
||||
call TCP_xmit_timer
|
||||
jmp .trim_then_step6
|
||||
jmp .trim
|
||||
|
||||
.simultaneous_open:
|
||||
|
||||
|
@ -1363,8 +1356,7 @@ align 4
|
|||
;-------------------------------------
|
||||
; Common processing for receipt of SYN
|
||||
|
||||
.trim_then_step6:
|
||||
|
||||
.trim:
|
||||
inc [edx + TCP_header.SequenceNumber]
|
||||
|
||||
; Drop any received data that doesnt fit in the receive window.
|
||||
|
@ -1377,17 +1369,12 @@ align 4
|
|||
;;; 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"
|
||||
|
||||
;----------------------------------------------
|
||||
|
@ -1592,14 +1579,14 @@ align 4
|
|||
jnz .need_output
|
||||
|
||||
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW
|
||||
jz .dumpit
|
||||
jz .done
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n"
|
||||
|
||||
.need_output:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n"
|
||||
call TCP_output
|
||||
|
||||
.dumpit:
|
||||
.done:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
|
||||
|
||||
call NET_packet_free
|
||||
|
@ -1619,7 +1606,7 @@ align 4
|
|||
pop eax edx
|
||||
|
||||
test [edx + TCP_header.Flags], TH_RST
|
||||
jnz .dumpit
|
||||
jnz .done
|
||||
|
||||
or [eax + TCP_SOCKET.t_flags], TF_ACKNOW
|
||||
jmp .need_output
|
||||
|
@ -1633,7 +1620,7 @@ align 4
|
|||
pop edx ebx
|
||||
|
||||
test [edx + TCP_header.Flags], TH_RST
|
||||
jnz .dumpit
|
||||
jnz .done
|
||||
|
||||
;;; if its a multicast/broadcast, also drop
|
||||
|
||||
|
@ -1642,7 +1629,7 @@ align 4
|
|||
|
||||
test [edx + TCP_header.Flags], TH_SYN
|
||||
jnz .respond_syn
|
||||
jmp .dumpit
|
||||
jmp .done
|
||||
|
||||
;---------
|
||||
; Respond
|
||||
|
@ -1661,8 +1648,10 @@ align 4
|
|||
pop ebx
|
||||
jmp .destroy_new_socket
|
||||
|
||||
.no_socket:
|
||||
;-----------------------------------------
|
||||
; The connection has no associated socket
|
||||
|
||||
.no_socket:
|
||||
pusha
|
||||
mov ecx, socket_mutex
|
||||
call mutex_unlock
|
||||
|
@ -1692,8 +1681,8 @@ align 4
|
|||
call TCP_respond_segment
|
||||
jmp .drop_no_socket
|
||||
|
||||
;-----
|
||||
; Drop
|
||||
;------------------------------------------------
|
||||
; Unlock socket mutex and prepare to drop segment
|
||||
|
||||
.drop:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Dropping segment\n"
|
||||
|
@ -1703,6 +1692,9 @@ align 4
|
|||
call mutex_unlock
|
||||
popa
|
||||
|
||||
;--------------------------------------------
|
||||
; Destroy the newly created socket if needed
|
||||
|
||||
.destroy_new_socket:
|
||||
test [temp_bits], TCP_BIT_DROPSOCKET
|
||||
jz .drop_no_socket
|
||||
|
@ -1710,6 +1702,9 @@ align 4
|
|||
mov eax, ebx
|
||||
call SOCKET_free
|
||||
|
||||
;------------------
|
||||
; Drop the segment
|
||||
|
||||
.drop_no_socket:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. 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: 3514 $
|
||||
$Revision: 5015 $
|
||||
|
||||
align 4
|
||||
iglobal
|
||||
|
@ -143,7 +143,7 @@ TCP_pull_out_of_band:
|
|||
;
|
||||
;-------------------------
|
||||
align 4
|
||||
TCP_drop:
|
||||
TCP_drop: ; FIXME CHECKME TODO
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_drop: %x\n", eax
|
||||
|
||||
|
@ -290,7 +290,6 @@ TCP_respond:
|
|||
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
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 3143 $
|
||||
$Revision: 5013 $
|
||||
|
||||
timer_flag_retransmission = 1 shl 0
|
||||
timer_flag_keepalive = 1 shl 1
|
||||
|
@ -61,13 +61,18 @@ local .exit
|
|||
}
|
||||
|
||||
|
||||
;----------------------
|
||||
; 640 ms timer
|
||||
;----------------------
|
||||
macro TCP_timer_640ms { ; TODO: implement timed wait timer!
|
||||
align 4
|
||||
proc TCP_timer_640ms ; TODO: implement timed wait timer!
|
||||
|
||||
local .loop
|
||||
local .exit
|
||||
xor esi, esi
|
||||
mov ecx, MANUAL_DESTROY
|
||||
call create_event
|
||||
mov [TCP_timer1_event], eax
|
||||
|
||||
.wait:
|
||||
mov eax, [TCP_timer1_event]
|
||||
mov ebx, [eax + EVENT.id]
|
||||
call wait_event
|
||||
|
||||
; Update TCP sequence number
|
||||
|
||||
|
@ -81,7 +86,7 @@ local .exit
|
|||
mov eax, [eax + SOCKET.NextPtr]
|
||||
.check_only:
|
||||
or eax, eax
|
||||
jz .exit
|
||||
jz .wait
|
||||
|
||||
cmp [eax + SOCKET.Domain], AF_INET4
|
||||
jne .loop
|
||||
|
@ -157,9 +162,8 @@ local .exit
|
|||
mov [eax + TCP_SOCKET.t_force], 0
|
||||
|
||||
jmp .loop
|
||||
.exit:
|
||||
|
||||
}
|
||||
endp
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 4850 $
|
||||
|
||||
|
||||
;-------------------------
|
||||
;
|
||||
|
@ -186,7 +188,7 @@ TCP_connect:
|
|||
mov eax, [esp+4]
|
||||
mov [eax + SOCKET.errorcode], ETIMEDOUT
|
||||
and [eax + SOCKET.state], not SS_ISCONNECTING
|
||||
call SOCKET_notify.unblock
|
||||
call SOCKET_notify
|
||||
ret 4
|
||||
|
||||
.fail:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; UDP.INC ;;
|
||||
|
@ -245,6 +245,8 @@ UDP_input:
|
|||
; ecx = number of bytes to send
|
||||
; esi = pointer to data
|
||||
;
|
||||
; OUT: eax = -1 on error
|
||||
;
|
||||
;-----------------------------------------------------------------
|
||||
|
||||
align 4
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2011-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 5164 $
|
||||
|
||||
|
||||
struct BLITTER_BLOCK
|
||||
xmin dd ?
|
||||
ymin dd ?
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -295,15 +295,17 @@ proc set_cursor stdcall, hcursor:dword
|
|||
; jne .fail
|
||||
mov ebx, [current_slot]
|
||||
xchg eax, [ebx+APPDATA.cursor]
|
||||
mov [redrawmouse_unconditional], 1
|
||||
call __sys_draw_pointer
|
||||
ret
|
||||
jmp .end
|
||||
;--------------------------------------
|
||||
align 4
|
||||
.fail:
|
||||
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
|
||||
;------------------------------------------------------------------------------
|
||||
|
@ -578,6 +580,40 @@ align 4
|
|||
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 ?
|
||||
|
@ -817,6 +853,129 @@ align 4
|
|||
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
|
||||
|
@ -852,7 +1011,10 @@ check_mouse_area_for_getpixel_new:
|
|||
add eax, ebx
|
||||
mov ebx, eax
|
||||
shl eax, 2
|
||||
cmp byte [_display.bpp], 32
|
||||
cmp byte [_display.bits_per_pixel], 32
|
||||
je @f
|
||||
sub eax, ebx
|
||||
cmp byte [_display.bits_per_pixel], 24
|
||||
je @f
|
||||
sub eax, ebx
|
||||
;--------------------------------------
|
||||
|
@ -927,13 +1089,29 @@ align 4
|
|||
add ecx, ebx
|
||||
mov ebx, ecx
|
||||
shl ecx, 2
|
||||
cmp byte [_display.bpp], 24
|
||||
cmp byte [_display.bits_per_pixel], 16
|
||||
je .16
|
||||
cmp byte [_display.bits_per_pixel], 24
|
||||
je .24
|
||||
and eax, 0xFFFFFF
|
||||
mov [ecx + cur_saved_data], eax ;store new color to
|
||||
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
|
||||
|
@ -1001,9 +1179,9 @@ init_display:
|
|||
mov ebx, restore_32
|
||||
mov ecx, move_cursor_32
|
||||
mov edx, Vesa20_putpixel32_new
|
||||
mov eax, [_display.bpp]
|
||||
mov eax, [_display.bits_per_pixel]
|
||||
cmp al, 32
|
||||
jne .24
|
||||
jne .not_32bpp
|
||||
|
||||
.set:
|
||||
mov [_display.select_cursor], select_cursor
|
||||
|
@ -1022,12 +1200,30 @@ init_display:
|
|||
mov [def_cursor], eax
|
||||
ret
|
||||
|
||||
.24:
|
||||
.not_32bpp:
|
||||
cmp al, 24
|
||||
jne .not_24bpp
|
||||
|
||||
mov ebx, restore_24
|
||||
mov ecx, move_cursor_24
|
||||
mov edx, Vesa20_putpixel24_new
|
||||
cmp al, 24
|
||||
je .set
|
||||
jmp .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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue