acpi: update

git-svn-id: svn://kolibrios.org@5201 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge)
2014-12-01 03:51:07 +00:00
parent 1ae250fff2
commit e6265b4399
90 changed files with 8528 additions and 6039 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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 ;; ;; 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_INVALID_CALL = 1 ; invalid input parameters
DISK_STATUS_NO_MEDIA = 2 ; no media present DISK_STATUS_NO_MEDIA = 2 ; no media present
DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data 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. ; Driver flags. Represent bits in DISK.DriverFlags.
DISK_NO_INSERT_NOTIFICATION = 1 DISK_NO_INSERT_NOTIFICATION = 1
; Media flags. Represent bits in DISKMEDIAINFO.Flags. ; 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 ; there are two distinct caches for a disk, one for "system" data,and the other
; for "application" data. ; for "application" data.
struct DISKCACHE struct DISKCACHE
mutex MUTEX
; Lock to protect the cache.
; The following fields are inherited from data32.inc:cache_ideX. ; The following fields are inherited from data32.inc:cache_ideX.
pointer dd ? pointer dd ?
data_size dd ? ; unused data_size dd ? ; unused
data dd ? data dd ?
sad_size dd ? sad_size dd ?
search_start dd ? search_start dd ?
sector_size_log dd ?
ends ends
; This structure represents a disk device and its media for the kernel. ; 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. ; Pointer to array of .NumPartitions pointers to PARTITION structures.
cache_size dd ? cache_size dd ?
; inherited from cache_ideX_size ; inherited from cache_ideX_size
CacheLock MUTEX
; Lock to protect both caches.
SysCache DISKCACHE SysCache DISKCACHE
AppCache DISKCACHE AppCache DISKCACHE
; Two caches for the disk. ; Two caches for the disk.
@@ -270,13 +272,13 @@ disk_list_mutex MUTEX
endg endg
iglobal 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 ; 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. ; 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 ; 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' ; 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 ; 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 ; 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 ; 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 ; 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. ; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list.
and [esi+DISK.NumPartitions], 0 and [esi+DISK.NumPartitions], 0
and [esi+DISK.Partitions], 0 and [esi+DISK.Partitions], 0
; 2. Currently we can work only with 512-bytes sectors. Check this restriction. ; 2. Acquire the buffer for MBR and bootsector tests. See the comment before
; The only exception is 2048-bytes CD/DVD, but they are not supported yet by
; this code.
cmp [esi+DISK.MediaInfo.SectorSize], 512
jz .doscan
DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize]
ret
.doscan:
; 3. Acquire the buffer for MBR and bootsector tests. See the comment before
; the 'partition_buffer_users' variable. ; 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 mov ebx, mbr_buffer ; assume the global buffer is free
lock inc [partition_buffer_users] lock inc [partition_buffer_users]
jz .buffer_acquired ; yes, it is free jz .buffer_acquired ; yes, it is free
lock dec [partition_buffer_users] ; no, we must allocate 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 test eax, eax
jz .nothing jz .nothing
xchg eax, ebx xchg eax, ebx
.buffer_acquired: .buffer_acquired:
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no ; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no
; more than MAX_NUM_PARTITION times. ; 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. ; ebp will hold the sector number for current MBR/EBR.
; [esp] will hold the sector number for current extended partition, if there ; [esp] will hold the sector number for current extended partition, if there
; is one. ; is one.
@@ -667,6 +666,10 @@ disk_scan_partitions:
push MAX_NUM_PARTITIONS ; the counter of max MBRs to process push MAX_NUM_PARTITIONS ; the counter of max MBRs to process
xor ebp, ebp ; start from sector zero xor ebp, ebp ; start from sector zero
push ebp ; no extended partition yet 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: .new_mbr:
; 5. Read the current sector. ; 5. Read the current sector.
; Note that 'read' callback operates with 64-bit sector numbers, so we must ; 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 ; a three-sectors-sized buffer. This function saves ebx in the stack
; immediately before ebp. ; immediately before ebp.
mov ebx, [ebp-4] ; get buffer 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 add ebp, 8 ; ebp points to part of PARTITION structure
xor eax, eax ; first sector of the partition xor eax, eax ; first sector of the partition
call fs_read32_sys call fs_read32_sys
@@ -996,7 +999,7 @@ end virtual
; ebp -> first three fields of PARTITION structure, .start, .length, .disk; ; ebp -> first three fields of PARTITION structure, .start, .length, .disk;
; [esp] = error code after bootsector read: 0 = ok, otherwise = failed, ; [esp] = error code after bootsector read: 0 = ok, otherwise = failed,
; ebx points to the buffer for bootsector, ; 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 call fat_create_partition
test eax, eax test eax, eax
jnz .success jnz .success

File diff suppressed because it is too large Load Diff

View File

@@ -379,10 +379,16 @@ RecalibrateFDD:
mov al, 8 mov al, 8
call FDCDataOutput call FDCDataOutput
call FDCDataInput call FDCDataInput
push eax
; DEBUGF 1,' %x',al ; DEBUGF 1,' %x',al
call FDCDataInput call FDCDataInput
; DEBUGF 1,' %x',al ; DEBUGF 1,' %x',al
; DEBUGF 1,'\n' ; DEBUGF 1,'\n'
pop eax
test al, 0xC0
jz @f
mov [FDC_Status], FDC_DiskNotFound
@@:
.fail: .fail:
call save_timer_fdd_motor call save_timer_fdd_motor
popa popa

View File

@@ -17,7 +17,7 @@ hdbase dd ?
hdid dd ? hdid dd ?
hdpos dd ? hdpos dd ?
ends ends
;-----------------------------------------------------------------------------
iglobal iglobal
align 4 align 4
ide_callbacks: ide_callbacks:
@@ -35,18 +35,34 @@ hd0_data HD_DATA ?, 0, 1
hd1_data HD_DATA ?, 0x10, 2 hd1_data HD_DATA ?, 0x10, 2
hd2_data HD_DATA ?, 0, 3 hd2_data HD_DATA ?, 0, 3
hd3_data HD_DATA ?, 0x10, 4 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: ide_mutex_table:
dd 0x1f0, 0x00, 0x1f0, 0x10 dd ide_channel1_mutex
dd 0x170, 0x00, 0x170, 0x10 dd ide_channel2_mutex
dd ide_channel3_mutex
dd ide_channel4_mutex
dd ide_channel5_mutex
dd ide_channel6_mutex
endg endg
;-----------------------------------------------------------------------------
uglobal uglobal
ide_mutex MUTEX ide_mutex MUTEX
ide_channel1_mutex MUTEX ide_channel1_mutex MUTEX
ide_channel2_mutex MUTEX ide_channel2_mutex MUTEX
ide_channel3_mutex MUTEX
ide_channel4_mutex MUTEX
ide_channel5_mutex MUTEX
ide_channel6_mutex MUTEX
endg endg
;-----------------------------------------------------------------------------
proc ide_read stdcall uses edi, \ proc ide_read stdcall uses edi, \
hd_data, buffer, startsector:qword, numsectors hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data ; hd_data = pointer to hd*_data
@@ -67,15 +83,13 @@ endl
; 2. Acquire the global lock. ; 2. Acquire the global lock.
mov ecx, ide_mutex mov ecx, ide_mutex
call mutex_lock call mutex_lock
mov ecx, ide_channel2_mutex
mov eax, [hd_data] mov ecx, [hd_data]
push ecx mov ecx, [ecx+HD_DATA.hdpos]
mov ecx, [hd_address_table] dec ecx
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0 shr ecx, 1
pop ecx shl ecx, 2
jne .IDE_Channel_2 mov ecx, [ecx + ide_mutex_table]
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov [channel_lock], ecx mov [channel_lock], ecx
call mutex_lock call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures. ; 3. Convert parameters to the form suitable for worker procedures.
@@ -83,6 +97,7 @@ endl
; Worker procedures use global variables and edi for [buffer]. ; Worker procedures use global variables and edi for [buffer].
cmp dword [startsector+4], 0 cmp dword [startsector+4], 0
jnz .fail jnz .fail
and [hd_error], 0 and [hd_error], 0
mov ecx, [hd_data] mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase] mov eax, [ecx+HD_DATA.hdbase]
@@ -98,55 +113,65 @@ endl
; DMA read is permitted if [allow_dma_access]=1 or 2 ; DMA read is permitted if [allow_dma_access]=1 or 2
cmp [allow_dma_access], 2 cmp [allow_dma_access], 2
ja .nodma 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 jnz .nodma
jmp .dma
@@:
test [DRIVE_DATA+1], byte 1010b
jnz .nodma
.dma:
;--------------------------------------
call hd_read_dma call hd_read_dma
jmp @f jmp @f
;--------------------------------------
.nodma: .nodma:
call hd_read_pio call hd_read_pio
;--------------------------------------
@@: @@:
cmp [hd_error], 0 cmp [hd_error], 0
jnz .fail jnz .fail
mov ecx, [numsectors] mov ecx, [numsectors]
inc dword [ecx] ; one more sector is read inc dword [ecx] ; one more sector is read
dec [sectors_todo] dec [sectors_todo]
jz .done jz .done
inc eax inc eax
jnz .sectors_loop jnz .sectors_loop
;--------------------------------------
; 5. Loop is done, either due to error or because everything is done. ; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status. ; Release the global lock and return the corresponding status.
.fail: .fail:
mov ecx, [channel_lock] mov ecx, [channel_lock]
call mutex_unlock call mutex_unlock
mov ecx, ide_mutex mov ecx, ide_mutex
call mutex_unlock call mutex_unlock
or eax, -1 or eax, -1
ret ret
;--------------------------------------
.done: .done:
mov ecx, [channel_lock] mov ecx, [channel_lock]
call mutex_unlock call mutex_unlock
mov ecx, ide_mutex mov ecx, ide_mutex
call mutex_unlock call mutex_unlock
xor eax, eax xor eax, eax
ret ret
endp endp
;-----------------------------------------------------------------------------
proc ide_write stdcall uses esi edi, \ proc ide_write stdcall uses esi edi, \
hd_data, buffer, startsector:qword, numsectors hd_data, buffer, startsector:qword, numsectors
; hd_data = pointer to hd*_data ; hd_data = pointer to hd*_data
@@ -167,15 +192,13 @@ endl
; 2. Acquire the global lock. ; 2. Acquire the global lock.
mov ecx, ide_mutex mov ecx, ide_mutex
call mutex_lock call mutex_lock
mov ecx, ide_channel2_mutex
mov eax, [hd_data] mov ecx, [hd_data]
push ecx mov ecx, [ecx+HD_DATA.hdpos]
mov ecx, [hd_address_table] dec ecx
cmp [eax+HD_DATA.hdbase], ecx ; 0x1F0 shr ecx, 1
pop ecx shl ecx, 2
jne .IDE_Channel_2 mov ecx, [ecx + ide_mutex_table]
mov ecx, ide_channel1_mutex
.IDE_Channel_2:
mov [channel_lock], ecx mov [channel_lock], ecx
call mutex_lock call mutex_lock
; 3. Convert parameters to the form suitable for worker procedures. ; 3. Convert parameters to the form suitable for worker procedures.
@@ -183,6 +206,7 @@ endl
; Worker procedures use global variables and esi for [buffer]. ; Worker procedures use global variables and esi for [buffer].
cmp dword [startsector+4], 0 cmp dword [startsector+4], 0
jnz .fail jnz .fail
and [hd_error], 0 and [hd_error], 0
mov ecx, [hd_data] mov ecx, [hd_data]
mov eax, [ecx+HD_DATA.hdbase] mov eax, [ecx+HD_DATA.hdbase]
@@ -200,66 +224,79 @@ endl
mov ecx, 16 mov ecx, 16
cmp ecx, [sectors_todo] cmp ecx, [sectors_todo]
jbe @f jbe @f
mov ecx, [sectors_todo] mov ecx, [sectors_todo]
;--------------------------------------
@@: @@:
mov [cache_chain_size], cl mov [cache_chain_size], cl
; DMA write is permitted only if [allow_dma_access]=1 ; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2 cmp [allow_dma_access], 2
jae .nodma 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 jnz .nodma
jmp .dma
@@:
test [DRIVE_DATA+1], byte 1010b
jnz .nodma
.dma:
;--------------------------------------
call cache_write_dma call cache_write_dma
jmp .common jmp .common
;--------------------------------------
.nodma: .nodma:
mov [cache_chain_size], 1 mov [cache_chain_size], 1
call cache_write_pio call cache_write_pio
;--------------------------------------
.common: .common:
cmp [hd_error], 0 cmp [hd_error], 0
jnz .fail jnz .fail
movzx ecx, [cache_chain_size] movzx ecx, [cache_chain_size]
mov eax, [numsectors] mov eax, [numsectors]
add [eax], ecx add [eax], ecx
sub [sectors_todo], ecx sub [sectors_todo], ecx
jz .done jz .done
add [edi], ecx add [edi], ecx
jc .fail jc .fail
shl ecx, 9 shl ecx, 9
add esi, ecx add esi, ecx
jmp .sectors_loop jmp .sectors_loop
;--------------------------------------
; 5. Loop is done, either due to error or because everything is done. ; 5. Loop is done, either due to error or because everything is done.
; Release the global lock and return the corresponding status. ; Release the global lock and return the corresponding status.
.fail: .fail:
mov ecx, [channel_lock] mov ecx, [channel_lock]
call mutex_unlock call mutex_unlock
mov ecx, ide_mutex mov ecx, ide_mutex
call mutex_unlock call mutex_unlock
or eax, -1 or eax, -1
ret ret
;--------------------------------------
.done: .done:
mov ecx, [channel_lock] mov ecx, [channel_lock]
call mutex_unlock call mutex_unlock
mov ecx, ide_mutex mov ecx, ide_mutex
call mutex_unlock call mutex_unlock
xor eax, eax xor eax, eax
ret ret
endp endp
;-----------------------------------------------------------------------------
; This is a stub. ; This is a stub.
proc ide_querymedia stdcall, hd_data, mediainfo proc ide_querymedia stdcall, hd_data, mediainfo
mov eax, [mediainfo] mov eax, [mediainfo]
@@ -270,14 +307,12 @@ proc ide_querymedia stdcall, hd_data, mediainfo
xor eax, eax xor eax, eax
ret ret
endp endp
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
; input: eax = sector, edi -> buffer ; input: eax = sector, edi -> buffer
; output: edi = edi + 512 ; output: edi = edi + 512
hd_read_pio: hd_read_pio:
push eax edx push eax edx
; Select the desired drive ; Select the desired drive
mov edx, [hdbase] mov edx, [hdbase]
add edx, 6 ;адрес регистра головок add edx, 6 ;адрес регистра головок
@@ -286,9 +321,9 @@ hd_read_pio:
out dx, al; номер головки/номер диска out dx, al; номер головки/номер диска
call wait_for_hd_idle call wait_for_hd_idle
cmp [hd_error], 0 cmp [hd_error], 0
jne hd_read_error jne hd_read_error
; ATA with 28 or 48 bit for sector number? ; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4] mov eax, [esp+4]
cmp eax, 0x10000000 cmp eax, 0x10000000
@@ -372,7 +407,6 @@ hd_read_pio:
pushfd pushfd
cli cli
mov ecx, 256 mov ecx, 256
mov edx, [hdbase] mov edx, [hdbase]
cld cld
@@ -393,6 +427,7 @@ cache_write_pio:
out dx, al ; номер головки/номер диска out dx, al ; номер головки/номер диска
call wait_for_hd_idle call wait_for_hd_idle
cmp [hd_error], 0 cmp [hd_error], 0
jne hd_write_error jne hd_write_error
@@ -550,13 +585,14 @@ wait_for_hd_idle:
align 4 align 4
wfhil1: wfhil1:
call check_hd_wait_timeout call check_hd_wait_timeout
cmp [hd_error], 0 cmp [hd_error], 0
jne @f jne @f
in al, dx in al, dx
test al, 128 test al, 128
jnz wfhil1 jnz wfhil1
;--------------------------------------
@@: @@:
pop edx eax pop edx eax
ret ret
@@ -573,6 +609,7 @@ wait_for_sector_buffer:
align 4 align 4
hdwait_sbuf: ; wait for sector buffer to be ready hdwait_sbuf: ; wait for sector buffer to be ready
call check_hd_wait_timeout call check_hd_wait_timeout
cmp [hd_error], 0 cmp [hd_error], 0
jne @f 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 test al, 1 ; previous command ended up with an error
jz buf_wait_ok jz buf_wait_ok
;--------------------------------------
@@: @@:
mov [hd_error], 1 mov [hd_error], 1
;--------------------------------------
buf_wait_ok: buf_wait_ok:
pop edx eax pop edx eax
ret ret
@@ -606,22 +644,17 @@ wait_for_sector_dma_ide0:
align 4 align 4
.wait: .wait:
call change_task call change_task
cmp [IDE_common_irq_param], 0 cmp [IDE_common_irq_param], 0
jz .done jz .done
call check_hd_wait_timeout call check_hd_wait_timeout
cmp [hd_error], 0 cmp [hd_error], 0
jz .wait jz .wait
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0 mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
popfd
;-------------------------------------- ;--------------------------------------
align 4
.done: .done:
pop edx pop edx
pop eax pop eax
@@ -636,23 +669,17 @@ wait_for_sector_dma_ide1:
align 4 align 4
.wait: .wait:
call change_task call change_task
cmp [IDE_common_irq_param], 0 cmp [IDE_common_irq_param], 0
jz .done jz .done
call check_hd_wait_timeout call check_hd_wait_timeout
cmp [hd_error], 0 cmp [hd_error], 0
jz .wait jz .wait
; clear Bus Master IDE Command register
pushfd
cli
mov [IDE_common_irq_param], 0 mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
popfd
;-------------------------------------- ;--------------------------------------
align 4
.done: .done:
pop edx pop edx
pop eax pop eax
@@ -660,7 +687,8 @@ align 4
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
iglobal iglobal
align 4 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: IDE_descriptor_table:
dd IDE_DMA dd IDE_DMA
dw 0x2000 dw 0x2000
@@ -673,19 +701,14 @@ endg
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
uglobal uglobal
; all uglobals are zeroed at boot ; 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_ptr dd 0
cache_chain_size db 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 allow_dma_access db 0
endg endg
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
IDE_irq_14_handler: 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 cmp [IDE_common_irq_param], irq14_num
jne .exit jne .exit
@@ -693,7 +716,8 @@ IDE_irq_14_handler:
cli cli
pushad pushad
mov [IDE_common_irq_param], 0 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? ; test whether it is our interrupt?
add edx, 2 add edx, 2
in al, dx in al, dx
@@ -715,18 +739,17 @@ IDE_irq_14_handler:
mov al, 1 mov al, 1
ret ret
;-------------------------------------- ;--------------------------------------
align 4
@@: @@:
popad popad
popfd popfd
;-------------------------------------- ;--------------------------------------
align 4
.exit: .exit:
mov al, 0 mov al, 0
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
IDE_irq_15_handler: 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 cmp [IDE_common_irq_param], irq15_num
jne .exit jne .exit
@@ -734,7 +757,8 @@ IDE_irq_15_handler:
cli cli
pushad pushad
mov [IDE_common_irq_param], 0 mov [IDE_common_irq_param], 0
mov dx, [IDEContrRegsBaseAddr] mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
add dx, 8 add dx, 8
; test whether it is our interrupt? ; test whether it is our interrupt?
add edx, 2 add edx, 2
@@ -757,26 +781,26 @@ IDE_irq_15_handler:
mov al, 1 mov al, 1
ret ret
;-------------------------------------- ;--------------------------------------
align 4
@@: @@:
popad popad
popfd popfd
;-------------------------------------- ;--------------------------------------
align 4
.exit: .exit:
mov al, 0 mov al, 0
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
IDE_common_irq_handler: 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 cmp [IDE_common_irq_param], 0
je .exit je .exit
pushfd
cli
pushad pushad
xor ebx, ebx xor ebx, ebx
mov dx, [IDEContrRegsBaseAddr] mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
mov eax, IDE_common_irq_param mov eax, IDE_common_irq_param
cmp [eax], irq14_num cmp [eax], irq14_num
mov [eax], bl mov [eax], bl
@@ -784,7 +808,6 @@ IDE_common_irq_handler:
add dx, 8 add dx, 8
;-------------------------------------- ;--------------------------------------
align 4
@@: @@:
; test whether it is our interrupt? ; test whether it is our interrupt?
add edx, 2 add edx, 2
@@ -807,13 +830,11 @@ align 4
mov al, 1 mov al, 1
ret ret
;-------------------------------------- ;--------------------------------------
align 4
@@: @@:
popad popad
popfd
;-------------------------------------- ;--------------------------------------
align 4
.exit: .exit:
popfd
mov al, 0 mov al, 0
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
@@ -824,26 +845,31 @@ hd_read_dma:
mov edx, [dma_hdpos] mov edx, [dma_hdpos]
cmp edx, [hdpos] cmp edx, [hdpos]
jne .notread jne .notread
mov edx, [dma_cur_sector] mov edx, [dma_cur_sector]
cmp eax, edx cmp eax, edx
jb .notread jb .notread
add edx, 15 add edx, 15
cmp [esp+4], edx cmp [esp+4], edx
ja .notread ja .notread
mov eax, [esp+4] mov eax, [esp+4]
sub eax, [dma_cur_sector] sub eax, [dma_cur_sector]
shl eax, 9 shl eax, 9
add eax, (OS_BASE+IDE_DMA) add eax, (OS_BASE+IDE_DMA)
push ecx esi push ecx esi
mov esi, eax mov esi, eax
mov ecx, 512/4 mov ecx, 512/4
cld cld
rep movsd rep movsd
pop esi ecx pop esi ecx
pop edx pop edx
pop eax pop eax
ret ret
;--------------------------------------
.notread: .notread:
; set data for PRD Table ; set data for PRD Table
mov eax, IDE_descriptor_table mov eax, IDE_descriptor_table
@@ -851,13 +877,18 @@ hd_read_dma:
mov word [eax+4], 0x2000 mov word [eax+4], 0x2000
sub eax, OS_BASE sub eax, OS_BASE
; select controller Primary or Secondary ; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr] mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
push eax push eax
mov eax, [hd_address_table] mov eax, [hdpos]
cmp [hdbase], eax ; 0x1F0 dec eax
test eax, 10b
pop eax pop eax
jz @f jz @f
add edx, 8 add edx, 8
;--------------------------------------
@@: @@:
push edx push edx
; Bus Master IDE PRD Table Address ; Bus Master IDE PRD Table Address
@@ -881,9 +912,9 @@ hd_read_dma:
out dx, al ; номер головки/номер диска out dx, al ; номер головки/номер диска
call wait_for_hd_idle call wait_for_hd_idle
cmp [hd_error], 0 cmp [hd_error], 0
jnz hd_read_error jnz hd_read_error
; ATA with 28 or 48 bit for sector number? ; ATA with 28 or 48 bit for sector number?
mov eax, [esp+4] mov eax, [esp+4]
; -10h because the PreCache hits the boundary between lba28 and lba48 ; -10h because the PreCache hits the boundary between lba28 and lba48
@@ -961,47 +992,55 @@ hd_read_dma:
;-------------------------------------- ;--------------------------------------
.continue: .continue:
; select controller Primary or Secondary ; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr] mov ecx, [IDE_controller_pointer]
mov eax, [hd_address_table] mov dx, [ecx+IDE_DATA.RegsBaseAddres]
cmp [hdbase], eax ; 0x1F0
mov eax, [hdpos]
dec eax
test eax, 10b
jz @f jz @f
add dx, 8 add dx, 8
;--------------------------------------
@@: @@:
; set write to memory and Start Bus Master ; set write to memory and Start Bus Master
mov al, 9 mov al, 9
out dx, al out dx, al
mov eax, [CURRENT_TASK] mov eax, [hdpos]
mov [dma_process], eax dec eax
test eax, 10b
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1 jnz .ide1
mov [IDE_common_irq_param], irq14_num mov [IDE_common_irq_param], irq14_num
jmp @f jmp @f
;--------------------------------------
.ide1: .ide1:
mov [IDE_common_irq_param], irq15_num mov [IDE_common_irq_param], irq15_num
;--------------------------------------
@@: @@:
popfd popfd
; wait for interrupt ; wait for interrupt
mov eax, [hd_address_table] mov eax, [hdpos]
cmp [hdbase], eax ; 0x1F0 dec eax
test eax, 10b
jnz .wait_ide1 jnz .wait_ide1
call wait_for_sector_dma_ide0 call wait_for_sector_dma_ide0
jmp @f jmp @f
;--------------------------------------
.wait_ide1: .wait_ide1:
call wait_for_sector_dma_ide1 call wait_for_sector_dma_ide1
;--------------------------------------
@@: @@:
cmp [hd_error], 0 cmp [hd_error], 0
jnz hd_read_error jnz hd_read_error
mov eax, [hdpos] mov eax, [hdpos]
mov [dma_hdpos], eax mov [dma_hdpos], eax
pop edx pop edx
pop eax pop eax
mov [dma_cur_sector], eax mov [dma_cur_sector], eax
jmp hd_read_dma jmp hd_read_dma
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
@@ -1011,6 +1050,7 @@ cache_write_dma:
; set data for PRD Table ; set data for PRD Table
mov eax, IDE_descriptor_table mov eax, IDE_descriptor_table
mov edx, eax mov edx, eax
pusha pusha
mov edi, (OS_BASE+IDE_DMA) mov edi, (OS_BASE+IDE_DMA)
mov dword [edx], IDE_DMA mov dword [edx], IDE_DMA
@@ -1021,15 +1061,21 @@ cache_write_dma:
cld cld
rep movsd rep movsd
popa popa
sub eax, OS_BASE sub eax, OS_BASE
; select controller Primary or Secondary ; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr] mov ecx, [IDE_controller_pointer]
mov dx, [ecx+IDE_DATA.RegsBaseAddres]
push eax push eax
mov eax, [hd_address_table] mov eax, [hdpos]
cmp [hdbase], eax ; 0x1F0 dec eax
test eax, 10b
pop eax pop eax
jz @f jz @f
add edx, 8 add edx, 8
;--------------------------------------
@@: @@:
push edx push edx
; Bus Master IDE PRD Table Address ; Bus Master IDE PRD Table Address
@@ -1053,9 +1099,9 @@ cache_write_dma:
out dx, al ; номер головки/номер диска out dx, al ; номер головки/номер диска
call wait_for_hd_idle call wait_for_hd_idle
cmp [hd_error], 0 cmp [hd_error], 0
jnz hd_write_error_dma jnz hd_write_error_dma
; ATA with 28 or 48 bit for sector number? ; ATA with 28 or 48 bit for sector number?
mov esi, [cache_chain_ptr] mov esi, [cache_chain_ptr]
mov eax, [esi] mov eax, [esi]
@@ -1134,52 +1180,93 @@ cache_write_dma:
;-------------------------------------- ;--------------------------------------
.continue: .continue:
; select controller Primary or Secondary ; select controller Primary or Secondary
mov dx, [IDEContrRegsBaseAddr] mov ecx, [IDE_controller_pointer]
mov eax, [hd_address_table] mov dx, [ecx+IDE_DATA.RegsBaseAddres]
cmp [hdbase], eax ; 0x1F0
mov eax, [hdpos]
dec eax
test eax, 10b
jz @f jz @f
add dx, 8 add dx, 8
;--------------------------------------
@@: @@:
; set write to device and Start Bus Master ; set write to device and Start Bus Master
mov al, 1 mov al, 1
out dx, al out dx, al
mov eax, [CURRENT_TASK]
mov [dma_process], eax mov eax, [hdpos]
mov eax, [TASK_BASE] dec eax
mov [dma_slot_ptr], eax test eax, 10b
mov eax, [hd_address_table]
cmp [hdbase], eax ; 0x1F0
jnz .ide1 jnz .ide1
mov [IDE_common_irq_param], irq14_num mov [IDE_common_irq_param], irq14_num
jmp @f jmp @f
;--------------------------------------
.ide1: .ide1:
mov [IDE_common_irq_param], irq15_num mov [IDE_common_irq_param], irq15_num
;--------------------------------------
@@: @@:
popfd popfd
; wait for interrupt ; wait for interrupt
mov [dma_cur_sector], not 0x40 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 jnz .wait_ide1
call wait_for_sector_dma_ide0 call wait_for_sector_dma_ide0
jmp @f jmp @f
;--------------------------------------
.wait_ide1: .wait_ide1:
call wait_for_sector_dma_ide1 call wait_for_sector_dma_ide1
;--------------------------------------
@@: @@:
cmp [hd_error], 0 cmp [hd_error], 0
jnz hd_write_error_dma jnz hd_write_error_dma
pop esi pop esi
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
uglobal proc clear_pci_ide_interrupts
mov esi, pcidev_list
;--------------------------------------
align 4 align 4
IDE_Interrupt dw ? .loop:
IDEContrRegsBaseAddr dw ? mov esi, [esi+PCIDEV.fd]
IDEContrProgrammingInterface dw ? cmp esi, pcidev_list
IDE_BAR0_val dw ? jz .done
IDE_BAR1_val dw ?
IDE_BAR2_val dw ? ; cmp [esi+PCIDEV.class], 0x01018F
IDE_BAR3_val dw ? mov eax, [esi+PCIDEV.class]
endg 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
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------

View File

@@ -41,53 +41,29 @@ find_empty_slot_CD_cache:
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
clear_CD_cache: clear_CD_cache:
DEBUGF 1, 'K : clear_CD_cache\n'
pusha pusha
.ide0:
mov esi, [cdpos]
dec esi
imul esi, sizeof.IDE_CACHE
add esi, cache_ide0
xor eax, eax xor eax, eax
cmp [cdpos], 1
jne .ide1 mov [esi+IDE_CACHE.search_start], eax
mov [cache_ide0_search_start], eax mov ecx, [esi+IDE_CACHE.system_sad_size]
mov ecx, [cache_ide0_system_sad_size] mov edi, [esi+IDE_CACHE.pointer]
mov edi, [cache_ide0_pointer]
call .clear call .clear
mov [cache_ide0_appl_search_start], eax
mov ecx, [cache_ide0_appl_sad_size] mov [esi+IDE_CACHE.appl_search_start], eax
mov edi, [cache_ide0_data_pointer] mov ecx, [esi+IDE_CACHE.appl_sad_size]
jmp .continue mov edi, [esi+IDE_CACHE.data_pointer]
.ide1:
cmp [cdpos], 2
jne .ide2
mov [cache_ide1_search_start], eax
mov ecx, [cache_ide1_system_sad_size]
mov edi, [cache_ide1_pointer]
call .clear
mov [cache_ide1_appl_search_start], eax
mov ecx, [cache_ide1_appl_sad_size]
mov edi, [cache_ide1_data_pointer]
jmp .continue
.ide2:
cmp [cdpos], 3
jne .ide3
mov [cache_ide2_search_start], eax
mov ecx, [cache_ide2_system_sad_size]
mov edi, [cache_ide2_pointer]
call .clear
mov [cache_ide2_appl_search_start], eax
mov ecx, [cache_ide2_appl_sad_size]
mov edi, [cache_ide2_data_pointer]
jmp .continue
.ide3:
mov [cache_ide3_search_start], eax
mov ecx, [cache_ide3_system_sad_size]
mov edi, [cache_ide3_pointer]
call .clear
mov [cache_ide3_appl_search_start], eax
mov ecx, [cache_ide3_appl_sad_size]
mov edi, [cache_ide3_data_pointer]
.continue:
call .clear call .clear
popa popa
ret ret
;--------------------------------------
.clear: .clear:
shl ecx, 1 shl ecx, 1
cld cld
@@ -96,272 +72,131 @@ clear_CD_cache:
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache: cd_calculate_cache:
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 12 - IDE11
.ide0: push eax
cmp [cdpos], 1
jne .ide1 mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0 cmp [cd_appl_data], 0
jne .ide0_appl_data jne @f
mov ecx, [cache_ide0_system_sad_size]
mov esi, [cache_ide0_pointer] mov ecx, [eax+IDE_CACHE.system_sad_size]
mov esi, [eax+IDE_CACHE.pointer]
pop eax
ret ret
.ide0_appl_data: ;--------------------------------------
mov ecx, [cache_ide0_appl_sad_size] @@:
mov esi, [cache_ide0_data_pointer] mov ecx, [eax+IDE_CACHE.appl_sad_size]
ret mov esi, [eax+IDE_CACHE.data_pointer]
.ide1: pop eax
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx, [cache_ide1_appl_sad_size]
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx, [cache_ide2_appl_sad_size]
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx, [cache_ide3_appl_sad_size]
mov esi, [cache_ide3_data_pointer]
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_1: cd_calculate_cache_1:
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 12 - IDE11
.ide0: push eax
cmp [cdpos], 1
jne .ide1 mov eax, [cdpos]
dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0 cmp [cd_appl_data], 0
jne .ide0_appl_data jne @f
mov esi, [cache_ide0_pointer]
mov esi, [eax+IDE_CACHE.pointer]
pop eax
ret ret
.ide0_appl_data: ;--------------------------------------
mov esi, [cache_ide0_data_pointer] @@:
ret mov esi, [eax+IDE_CACHE.data_pointer]
.ide1: pop eax
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi, [cache_ide3_data_pointer]
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_2: cd_calculate_cache_2:
; 1 - IDE0 ... 4 - IDE3 ; 1 - IDE0 ... 12 - IDE11
.ide0: mov eax, [cdpos]
cmp [cdpos], 1 dec eax
jne .ide1 imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0 cmp [cd_appl_data], 0
jne .ide0_appl_data jne @f
mov eax, [cache_ide0_system_data]
mov eax, [eax+IDE_CACHE.system_data]
ret ret
.ide0_appl_data: ;--------------------------------------
mov eax, [cache_ide0_appl_data] @@:
ret mov eax, [eax+IDE_CACHE.appl_data]
.ide1:
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov eax, [cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax, [cache_ide1_appl_data]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov eax, [cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax, [cache_ide2_appl_data]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov eax, [cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax, [cache_ide3_appl_data]
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_3: cd_calculate_cache_3:
; mov ecx,cache_max*10/100 ; 1 - IDE0 ... 12 - IDE11
; mov edi,[cache_search_start] 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 cmp [cd_appl_data], 0
jne .ide0_appl_data jne @f
mov edi, [cache_ide0_search_start]
mov edi, [eax+IDE_CACHE.search_start]
pop eax
ret ret
.ide0_appl_data: ;--------------------------------------
mov edi, [cache_ide0_appl_search_start] @@:
ret mov edi, [eax+IDE_CACHE.appl_search_start]
.ide1: pop eax
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov edi, [cache_ide1_search_start]
ret
.ide1_appl_data:
mov edi, [cache_ide1_appl_search_start]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov edi, [cache_ide2_search_start]
ret
.ide2_appl_data:
mov edi, [cache_ide2_appl_search_start]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov edi, [cache_ide3_search_start]
ret
.ide3_appl_data:
mov edi, [cache_ide3_appl_search_start]
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_4: cd_calculate_cache_4:
; cmp edi,cache_max ; 1 - IDE0 ... 12 - IDE11
; 1 - IDE0 ... 4 - IDE3 push eax
.ide0:
cmp [cdpos], 1 mov eax, [cdpos]
jne .ide1 dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0 cmp [cd_appl_data], 0
jne .ide0_appl_data jne @f
cmp edi, [cache_ide0_system_sad_size]
cmp edi, [eax+IDE_CACHE.system_sad_size]
pop eax
ret ret
.ide0_appl_data: ;--------------------------------------
cmp edi, [cache_ide0_appl_sad_size] @@:
ret cmp edi, [eax+IDE_CACHE.appl_sad_size]
.ide1: pop eax
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
cmp edi, [cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi, [cache_ide1_appl_sad_size]
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
cmp edi, [cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi, [cache_ide2_appl_sad_size]
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
cmp edi, [cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi, [cache_ide3_appl_sad_size]
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
cd_calculate_cache_5: cd_calculate_cache_5:
; mov [cache_search_start],edi ; 1 - IDE0 ... 12 - IDE11
; 1 - IDE0 ... 4 - IDE3 push eax
.ide0:
cmp [cdpos], 1 mov eax, [cdpos]
jne .ide1 dec eax
imul eax, sizeof.IDE_CACHE
add eax, cache_ide0
cmp [cd_appl_data], 0 cmp [cd_appl_data], 0
jne .ide0_appl_data jne @f
mov [cache_ide0_search_start], edi
mov [eax+IDE_CACHE.search_start], edi
pop eax
ret ret
.ide0_appl_data: ;--------------------------------------
mov [cache_ide0_appl_search_start], edi @@:
ret mov [eax+IDE_CACHE.appl_search_start], edi
.ide1: pop eax
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov [cache_ide1_search_start], edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start], edi
ret
.ide2:
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov [cache_ide2_search_start], edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start], edi
ret
.ide3:
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov [cache_ide3_search_start], edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start], edi
ret ret
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
;align 4
;calculate_linear_to_real:
; shr eax, 12
; mov eax, [page_tabs+eax*4]
; and eax, 0xFFFFF000
; ret

View File

@@ -22,11 +22,6 @@ ramdisk_functions:
.size = $ - ramdisk_functions .size = $ - ramdisk_functions
endg 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 iglobal
align 4 align 4
ramdisk_actual_size dd RAMDISK_CAPACITY ramdisk_actual_size dd RAMDISK_CAPACITY

View File

@@ -394,145 +394,27 @@ sayerr:
push 0 push 0
popf popf
sti
; set up esp ; set up esp
movzx esp, sp movzx esp, sp
push 0 push 0
pop es 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 xor cx, cx
.no_Interrupt: @@:
pop cx in al, 64h
;-------------------------------------- test al, 2
; get memory base BAR0 loopnz @b
mov ax, 0xB10A
mov di, 0x10 ; memory base is config register at 0x10
push cx
int 0x1A
jc .no_BAR0 ;.nopci
mov [es:BOOT_IDE_BAR0_16], cx
.no_BAR0:
pop cx
;--------------------------------------
; get memory base BAR1
mov ax, 0xB10A
mov di, 0x14 ; memory base is config register at 0x14
push cx
int 0x1A
jc .no_BAR1 ;.nopci
mov [es:BOOT_IDE_BAR1_16], cx
.no_BAR1:
pop cx
;--------------------------------------
; get memory base BAR2
mov ax, 0xB10A
mov di, 0x18 ; memory base is config register at 0x18
push cx
int 0x1A
jc .no_BAR2 ;.nopci
mov [es:BOOT_IDE_BAR2_16], cx
.no_BAR2:
pop cx
;--------------------------------------
; get memory base BAR3
mov ax, 0xB10A
mov di, 0x1C ; memory base is config register at 0x1c
push cx
int 0x1A
jc .no_BAR3 ;.nopci
mov [es:BOOT_IDE_BAR3_16], cx
.no_BAR3:
pop cx
;--------------------------------------
.nopci:
; \end{Mario79}
mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование
out 0x60, al out 0x60, al
xor cx, cx xor cx, cx
wait_loop: ; variant 2 @@:
; reading state of port of 8042 controller
in al, 64h in al, 64h
and al, 00000010b ; ready flag test al, 1
; wait until 8042 controller is ready loopz @b
loopnz wait_loop in al, 0x60
;;;/diamond today 5.02.2008 ;;;/diamond today 5.02.2008
; set keyboard typematic rate & delay ; set keyboard typematic rate & delay
@@ -541,16 +423,19 @@ wait_loop: ; variant 2
xor cx, cx xor cx, cx
@@: @@:
in al, 64h in al, 64h
test al, 2 test al, 1
loopnz @b loopz @b
in al, 0x60
mov al, 0 mov al, 0
out 0x60, al out 0x60, al
xor cx, cx xor cx, cx
@@: @@:
in al, 64h in al, 64h
test al, 2 test al, 1
loopnz @b loopz @b
in al, 0x60
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sti
; --------------- APM --------------------- ; --------------- APM ---------------------
and word [es:BOOT_APM_VERSION], 0 ; ver = 0.0 (APM not found) and word [es:BOOT_APM_VERSION], 0 ; ver = 0.0 (APM not found)
mov ax, 0x5300 mov ax, 0x5300

View File

@@ -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 start_msg db "Press [abcde] to change settings, press [Enter] to continue booting",13,10,0
time_msg db " or wait " time_msg db " or wait "
time_str db " 5 seconds" 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 current_cfg_msg db "Current settings:",13,10,0
curvideo_msg db " [a] Videomode: ",0 curvideo_msg db " [a] Videomode: ",0

View File

@@ -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 ;; ;; 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 cmp [es:mi.BitsPerPixel], 32 ;It show only videomodes to have support 24 and 32 bpp
jb @f jb @f
; cmp [es:mi.BitsPerPixel],16 ; 16 bpp might actually be 15 bpp
; jne .l0 cmp [es:mi.BitsPerPixel], 16
; cmp [es:mi.GreenMaskSize],5 jne .l0
; jne .l0 cmp [es:mi.GreenMaskSize], 5
jne .l0
; mov [es:mi.BitsPerPixel],15 ; mov [es:mi.BitsPerPixel],15
jmp @f ; 15 bpp isnt supported ATM
.l0: .l0:
@@ -368,6 +370,8 @@ if defined extended_primary_loader
je .ok_found_mode je .ok_found_mode
cmp word [es:si+8], 24 cmp word [es:si+8], 24
je .ok_found_mode je .ok_found_mode
cmp word [es:si+8], 16
je .ok_found_mode
@@: @@:
add si, size_of_step add si, size_of_step
cmp word [es:si], -1 cmp word [es:si], -1
@@ -392,7 +396,8 @@ end if
; mov word [home_cursor],ax ; mov word [home_cursor],ax
; mov word [preboot_graph],ax ; mov word [preboot_graph],ax
;SET default video of mode first probe will fined a move of work 1024x768@32 ;SET default video of mode first probe will fined a move of work 1024x768@32
mov cx, 32
.find_mode:
mov ax, 1024 mov ax, 1024
mov bx, 768 mov bx, 768
mov si, modes_table mov si, modes_table
@@ -411,6 +416,8 @@ end if
call .loops call .loops
test ax, ax test ax, ax
jz .ok_found_mode jz .ok_found_mode
sub cx, 8
jnz .find_mode
mov si, modes_table mov si, modes_table
if ~ defined extended_primary_loader if ~ defined extended_primary_loader
@@ -474,18 +481,15 @@ end if
jne .next jne .next
cmp bx, word [es:si+2] cmp bx, word [es:si+2]
jne .next jne .next
cmp word [es:si+8], 32 cmp cx, word [es:si+8]
je .ok jne .next
cmp word [es:si+8], 24 xor ax, ax
je .ok ret
.next: .next:
add si, size_of_step add si, size_of_step
cmp word [es:si], -1 cmp word [es:si], -1
je .exit je .exit
jmp .loops jmp .loops
.ok:
xor ax, ax
ret
.exit: .exit:
or ax, -1 or ax, -1
ret ret

View File

@@ -9,10 +9,10 @@ $Revision$
read_ramdisk: 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 cmp [boot_dev+OS_BASE+0x10000], 1
jne no_sys_on_hd jne no_sys_on_hd.1
xor ebp, ebp xor ebp, ebp
.hd_loop: .hd_loop:
@@ -69,9 +69,19 @@ read_ramdisk:
jb .hd_loop jb .hd_loop
jmp no_sys_on_hd jmp no_sys_on_hd
.yes: .yes:
DEBUGF 1, "K : RD found: %s\n", read_image_fsinfo.name
pop edi esi eax 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 iglobal
align 4 align 4
read_image_fsinfo: read_image_fsinfo:
@@ -79,7 +89,7 @@ read_image_fsinfo:
dq 0 ; offset: zero dq 0 ; offset: zero
dd 1474560 ; size dd 1474560 ; size
dd RAMDISK ; buffer dd RAMDISK ; buffer
db '/hd' .name db '/hd'
.name_digit db '0' .name_digit db '0'
db '/' db '/'
.partition: .partition:
@@ -99,6 +109,8 @@ read_image:
ret ret
no_sys_on_hd: no_sys_on_hd:
DEBUGF 1, "K : RD not found\n"
.1:
; test_to_format_ram_disk (need if not using ram disk) ; test_to_format_ram_disk (need if not using ram disk)
cmp [boot_dev+OS_BASE+0x10000], 3 cmp [boot_dev+OS_BASE+0x10000], 3
jne not_format_ram_disk jne not_format_ram_disk

View File

@@ -13,8 +13,24 @@
$Revision$ $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: pr_mode_exit:
; setup stack ; setup stack
@@ -166,7 +182,7 @@ restart_kernel_4000:
pop es pop es
mov cx, 0x8000 mov cx, 0x8000
push cx push cx
push 0x7000 push 0x7100
pop ds pop ds
xor si, si xor si, si
xor di, di xor di, di

View File

@@ -1,11 +1,10 @@
@echo off @echo off
cls cls
set languages=en ru ge et sp set languages=en ru ge et sp
set drivers=com_mouse emu10k1x fm801 infinity sis sound viasound vt823x set targets=kernel clean
set targets=all kernel drivers clean
call :Check_Target %1 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% call :Target_%target%
if ERRORLEVEL 0 goto Exit_OK if ERRORLEVEL 0 goto Exit_OK
@@ -56,51 +55,6 @@ goto :eof
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 :Target_clean
echo *** cleaning ... echo *** cleaning ...
rmdir /S /Q bin rmdir /S /Q bin
@@ -114,14 +68,6 @@ echo.
pause pause
exit 1 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 :Exit_OK
echo. echo.
echo all operations have been done echo all operations have been done

View File

@@ -6,7 +6,7 @@
; ============================================================================= ; =============================================================================
; Version of all structures related to host controllers. ; Version of all structures related to host controllers.
; Must be the same in kernel and *hci-drivers. ; 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 ; 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 ; 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 USB_STATUS_CLOSED = 16 ; pipe closed
; either explicitly with USBClosePipe ; either explicitly with USBClosePipe
; or implicitly due to device disconnect ; or implicitly due to device disconnect
USB_STATUS_CANCELLED = 17 ; transfer cancelled with USBAbortPipe
; Possible speeds of USB devices ; Possible speeds of USB devices
USB_SPEED_FS = 0 ; full-speed USB_SPEED_FS = 0 ; full-speed
@@ -63,6 +64,9 @@ USB_FLAG_CAN_FREE = 2
USB_FLAG_EXTRA_WAIT = 4 USB_FLAG_EXTRA_WAIT = 4
; The pipe was in wait list, while another event occured; ; The pipe was in wait list, while another event occured;
; when the first wait will be done, reinsert the pipe to wait list ; 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 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 ; Initiate configuration of a new device (create pseudo-pipe describing that
; device and call usb_new_device). ; device and call usb_new_device).
; esi -> usb_controller, eax = speed (one of USB_SPEED_* constants). ; 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 ends
; pointers to kernel API functions that are called from *HCI-drivers ; pointers to kernel API functions that are called from *HCI-drivers
@@ -307,6 +319,8 @@ NextVirt dd ?
PrevVirt dd ? PrevVirt dd ?
; Previous endpoint in the processing list. ; Previous endpoint in the processing list.
; See also NextVirt field and the description before NextVirt field. ; 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 ; Every pipe has the associated transfer queue, that is, the double-linked
; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt ; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt
@@ -427,6 +441,8 @@ DeviceDescrSize db ?
; Size of device descriptor. ; Size of device descriptor.
Speed db ? Speed db ?
; Device speed, one of USB_SPEED_*. ; Device speed, one of USB_SPEED_*.
Timer dd ?
; Handle of timer that handles request timeout.
NumInterfaces dd ? NumInterfaces dd ?
; Number of interfaces. ; Number of interfaces.
ConfigDataSize dd ? ConfigDataSize dd ?

View File

@@ -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, ; USB Host Controller support code: hardware-independent part,
; common for all controller types. ; common for all controller types.
@@ -114,7 +124,7 @@ proc get_phys_addr
ret ret
endp 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 ; 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, ; needs to be synchronized. When it will be known that the cache is updated,
; usb_subscription_done procedure will be called. ; usb_subscription_done procedure will be called.
@@ -128,6 +138,17 @@ proc usb_subscribe_control
ret ret
endp 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. ; Called after synchronization of hardware cache with software changes.
; Continues process of device enumeration based on when it was delayed ; Continues process of device enumeration based on when it was delayed
; due to call to usb_subscribe_control. ; due to call to usb_subscribe_control.
@@ -254,13 +275,18 @@ proc usb_process_one_wait_list
mov [esi+usb_controller.WaitPipeListAsync+edx], ebx mov [esi+usb_controller.WaitPipeListAsync+edx], ebx
jmp .continue jmp .continue
.process: .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 or [ebx+usb_pipe.NextWait], -1
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED
jz .nodisconnect jz .nodisconnect
call usb_pipe_closed call usb_pipe_closed
jmp .continue jmp .continue
.nodisconnect: .nodisconnect:
test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED
jz .nodisabled
call usb_pipe_disabled
jmp .continue
.nodisabled:
call usb_subscription_done call usb_subscription_done
.continue: .continue:
; 8. Restore edx and next pipe saved in step 5 and continue the loop. ; 8. Restore edx and next pipe saved in step 5 and continue the loop.

View File

@@ -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: ; Support for USB (non-root) hubs:
; powering up/resetting/disabling ports, ; powering up/resetting/disabling ports,
; watching for adding/removing devices. ; watching for adding/removing devices.

View File

@@ -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. ; Initialization of the USB subsystem.
; Provides usb_init procedure, includes all needed files. ; Provides usb_init procedure, includes all needed files.
@@ -55,7 +65,7 @@ proc usb_init
mov esi, pcidev_list mov esi, pcidev_list
push 0 push 0
.kickoff: .kickoff:
mov esi, [esi+PCIDEV.list.next] mov esi, [esi+PCIDEV.fd]
cmp esi, pcidev_list cmp esi, pcidev_list
jz .done_kickoff jz .done_kickoff
cmp word [esi+PCIDEV.class+1], 0x0C03 cmp word [esi+PCIDEV.class+1], 0x0C03
@@ -108,7 +118,7 @@ proc usb_init
; for all EHCI controllers. ; for all EHCI controllers.
mov eax, pcidev_list mov eax, pcidev_list
.scan_ehci: .scan_ehci:
mov eax, [eax+PCIDEV.list.next] mov eax, [eax+PCIDEV.fd]
cmp eax, pcidev_list cmp eax, pcidev_list
jz .done_ehci jz .done_ehci
cmp [eax+PCIDEV.class], 0x0C0320 cmp [eax+PCIDEV.class], 0x0C0320
@@ -120,7 +130,7 @@ proc usb_init
; for all UHCI and OHCI controllers. ; for all UHCI and OHCI controllers.
mov eax, pcidev_list mov eax, pcidev_list
.scan_usb1: .scan_usb1:
mov eax, [eax+PCIDEV.list.next] mov eax, [eax+PCIDEV.fd]
cmp eax, pcidev_list cmp eax, pcidev_list
jz .done_usb1 jz .done_usb1
cmp [eax+PCIDEV.class], 0x0C0300 cmp [eax+PCIDEV.class], 0x0C0300

View File

@@ -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. ; Memory management for USB structures.
; Protocol layer uses the common kernel heap malloc/free. ; Protocol layer uses the common kernel heap malloc/free.
; Hardware layer has special requirements: ; Hardware layer has special requirements:

View File

@@ -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. ; Functions for USB pipe manipulation: opening/closing, sending data etc.
; ;
USB_STDCALL_VERIFY = 1 USB_STDCALL_VERIFY = 1
@@ -13,6 +23,11 @@ else
stdcall arg stdcall arg
end if end if
} }
if USB_STDCALL_VERIFY
STDCALL_VERIFY_EXTRA = 20h
else
STDCALL_VERIFY_EXTRA = 0
end if
; Initialization of usb_static_ep structure, ; Initialization of usb_static_ep structure,
; called from controller-specific initialization; edi -> usb_static_ep ; called from controller-specific initialization; edi -> usb_static_ep
@@ -238,8 +253,17 @@ proc usb_close_pipe_nolock
call mutex_lock call mutex_lock
push ecx push ecx
; 3b. Let the controller-specific code do its job. ; 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] mov eax, [esi+usb_controller.HardwareFunc]
call [eax+usb_hardware_func.UnlinkPipe] 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. ; 3c. Release the corresponding lock.
pop ecx pop ecx
call mutex_unlock call mutex_unlock
@@ -262,36 +286,66 @@ proc usb_close_pipe_nolock
ret ret
endp 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 ; 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. ; corresponding wait list. It means that the hardware has fully forgot about it.
; ebx -> usb_pipe, esi -> usb_controller ; ebx -> usb_pipe, esi -> usb_controller
proc usb_pipe_closed proc usb_pipe_closed
push edi push edi
mov edi, [esi+usb_controller.HardwareFunc] mov edi, [esi+usb_controller.HardwareFunc]
; 1. Loop over all transfers, calling the driver with USB_STATUS_CLOSED ; 1. Notify all registered callbacks with status USB_STATUS_CLOSED, if any,
; and freeing all descriptors. ; and free all transfer descriptors, including the last one.
lea ecx, [ebx+usb_pipe.Lock]
call mutex_lock
mov edx, [ebx+usb_pipe.LastTD] mov edx, [ebx+usb_pipe.LastTD]
test edx, edx test edx, edx
jz .no_transfer jz .no_transfer
mov edx, [edx+usb_gtd.NextVirt] mov eax, [edx+usb_gtd.NextVirt]
.transfer_loop:
cmp edx, [ebx+usb_pipe.LastTD]
jz .transfer_done
mov ecx, [edx+usb_gtd.Callback]
test ecx, ecx
jz .no_callback
push edx push edx
stdcall_verify ecx, ebx, USB_STATUS_CLOSED, \ push eax
[edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData] call mutex_unlock
pop edx push USB_STATUS_CLOSED
.no_callback: call usb_pipe_aborted
push [edx+usb_gtd.NextVirt] ; It is safe to free LastTD here:
stdcall [edi+usb_hardware_func.FreeTD], edx ; usb_*_transfer_async do not enqueue new transfers if USB_FLAG_CLOSED is set.
pop edx stdcall [edi+usb_hardware_func.FreeTD], [ebx+usb_pipe.LastTD]
jmp .transfer_loop jmp @f
.transfer_done:
stdcall [edi+usb_hardware_func.FreeTD], edx
.no_transfer: .no_transfer:
call mutex_unlock
@@:
; 2. Decrement number of pipes for the device. ; 2. Decrement number of pipes for the device.
; If this pipe is the last pipe, go to 5. ; If this pipe is the last pipe, go to 5.
mov ecx, [ebx+usb_pipe.DeviceData] mov ecx, [ebx+usb_pipe.DeviceData]
@@ -342,14 +396,23 @@ proc usb_pipe_closed
dec eax dec eax
jnz .notify_loop jnz .notify_loop
.notify_done: .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] call [edi+usb_hardware_func.GetDeviceAddress]
test eax, eax test eax, eax
jz @f jz @f
bts [esi+usb_controller.ExistingAddresses], eax bts [esi+usb_controller.ExistingAddresses], eax
@@: @@:
dbgstr 'USB device disconnected' 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. ; so all drivers should not use any device-related pipes.
; Free the remaining pipes. ; Free the remaining pipes.
mov eax, [ebx+usb_pipe.DeviceData] mov eax, [ebx+usb_pipe.DeviceData]
@@ -366,15 +429,74 @@ proc usb_pipe_closed
.free_done: .free_done:
stdcall [edi+usb_hardware_func.FreePipe], ebx stdcall [edi+usb_hardware_func.FreePipe], ebx
pop eax 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 sub eax, usb_device_data.ClosedPipeList - usb_pipe.NextSibling
call free call free
; 9. Return. ; 10. Return.
.nothing: .nothing:
pop edi pop edi
ret ret
endp 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. ; Part of API for drivers, see documentation for USBNormalTransferAsync.
proc usb_normal_transfer_async stdcall uses ebx edi,\ proc usb_normal_transfer_async stdcall uses ebx edi,\
pipe:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword pipe:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword
@@ -508,6 +630,69 @@ endl
ret ret
endp 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. ; Part of API for drivers, see documentation for USBGetParam.
proc usb_get_param proc usb_get_param
virtual at esp virtual at esp

View File

@@ -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. ; Implementation of the USB protocol for device enumeration.
; Manage a USB device when it becomes ready for USB commands: ; Manage a USB device when it becomes ready for USB commands:
; configure, enumerate, load the corresponding driver(s), ; configure, enumerate, load the corresponding driver(s),
@@ -33,6 +43,19 @@ USB_INTERFACE_POWER_DESCR = 8
; read to the debug board. ; read to the debug board.
USB_DUMP_DESCRIPTORS = 1 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 ================================= ; ================================ Structures =================================
; ============================================================================= ; =============================================================================
@@ -179,21 +202,36 @@ ends
; out: eax = 0 <=> failed, the caller should disable the port. ; out: eax = 0 <=> failed, the caller should disable the port.
proc usb_new_device proc usb_new_device
push ebx edi ; save used registers to be stdcall 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 ; - device address in the bus
; - memory for device data ; - memory for device data
; - pipe for zero endpoint ; - pipe for zero endpoint
; If some allocation fails, we must undo our actions. Closing the pipe ; 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. ; 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. ; The order for other two allocations is quite arbitrary.
; 1a. Allocate a bus address. ; 2a. Allocate a bus address.
push ecx push ecx
call usb_set_address_request call usb_set_address_request
pop ecx pop ecx
; 1b. If failed, just return zero. ; 2b. If failed, just return zero.
test eax, eax test eax, eax
jz .nothing 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 ; 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 ; input and output, see usb_after_set_address. Later we will reallocate it
; to actual size needed for descriptors. ; to actual size needed for descriptors.
@@ -201,10 +239,10 @@ proc usb_new_device
push ecx push ecx
call malloc call malloc
pop ecx 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 test eax, eax
jz .nomemory 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 now, we do not know the actual maximum packet size;
; for full-speed devices it can be any of 8, 16, 32, 64 bytes, ; 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. ; 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. ; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes.
xchg eax, ebx xchg eax, ebx
pop eax 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 test ebx, ebx
jz .freememory 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 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.TTHub], edi
mov [eax+usb_device_data.TTPort], 0 mov [eax+usb_device_data.TTPort], 0
mov [eax+usb_device_data.NumInterfaces], edi mov [eax+usb_device_data.NumInterfaces], edi
@@ -268,7 +308,7 @@ proc usb_new_device
mov [eax+usb_device_data.Port], cl mov [eax+usb_device_data.Port], cl
mov edx, [esi+usb_controller.ResettingHub] mov edx, [esi+usb_controller.ResettingHub]
mov [eax+usb_device_data.Hub], edx 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. ; Config pipe serves as device identifier.
; Root hubs use the array inside usb_controller structure, ; Root hubs use the array inside usb_controller structure,
; non-root hubs use the array immediately after usb_hub 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 mov [esi+usb_controller.DevicesByPort+ecx*4], ebx
@@: @@:
call usb_reinit_pipe_list call usb_reinit_pipe_list
; 5. Issue SET_ADDRESS control request, using buffer filled in step 1a. ; 6. Issue SET_ADDRESS control request, using buffer filled in step 2a.
; Use the return value from usb_control_async as our return value; ; 6a. Configure timer to force reset after timeout.
; if it is zero, then something has failed. ; 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] lea eax, [esi+usb_controller.SetAddressBuffer]
stdcall usb_control_async, ebx, eax, edi, edi, usb_set_address_callback, edi, edi 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: .nothing:
; 6. Return. ; 7. Return.
pop edi ebx ; restore used registers to be stdcall pop edi ebx ; restore used registers to be stdcall
ret ret
; Handlers of failures in steps 1b, 1d, 1f. ; Handlers of failures in steps 2b, 2d, 2f.
.freememory: .freememory:
call free call free
jmp .freeaddr jmp .freeaddr
@@ -349,16 +402,23 @@ endp
; Note that USB stack uses esi = pointer to usb_controller. ; 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 proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
push ebx ; save ebx to be stdcall push ebx ; save ebx to be stdcall
; Load data to registers for further references.
mov ebx, [pipe] 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 ecx, dword [esi+usb_controller.SetAddressBuffer+2]
mov eax, [esi+usb_controller.HardwareFunc] mov eax, [esi+usb_controller.HardwareFunc]
; 1. Check whether the device has accepted new address. If so, proceed to 2. ; 2. Check whether the device has accepted new address. If so, proceed to 3.
; Otherwise, go 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 cmp [status], 0
jnz .error jnz .error
; 2. Address accepted. ; 3. Address accepted.
; 2a. The controller-specific structure for the control pipe still uses ; 3a. The controller-specific structure for the control pipe still uses
; zero address. Call the controller-specific function to change it to ; zero address. Call the controller-specific function to change it to
; the actual address. ; the actual address.
; Note that the hardware could cache the controller-specific structure, ; 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. ; be safe to continue.
; dbgstr 'address set in device' ; dbgstr 'address set in device'
call [eax+usb_hardware_func.SetDeviceAddress] call [eax+usb_hardware_func.SetDeviceAddress]
; 2b. If the port is in non-root hub, clear 'reset in progress' flag. ; 3b. If the port is in non-root hub, clear 'reset in progress' flag.
; In any case, proceed to 4. ; In any case, proceed to 6.
mov eax, [esi+usb_controller.ResettingHub] mov eax, [esi+usb_controller.ResettingHub]
test eax, eax test eax, eax
jz .return jz .return
and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS
.return: .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 the worker function for that.
call usb_test_pending_port call usb_test_pending_port
.wakeup:
push esi edi
call usb_wakeup
pop edi esi
.nothing: .nothing:
pop ebx ; restore ebx to be stdcall pop ebx ; restore ebx to be stdcall
ret 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: .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] 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 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 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 ; 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). ; could take some time, the hub code is responsible for proceeding).
@@ -642,7 +726,7 @@ end if
; 3d. Free old memory. ; 3d. Free old memory.
call free call free
pop eax 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] movzx ecx, [eax+usb_device_data.DeviceDescrSize]
mov edx, [eax+usb_device_data.ConfigDataSize] mov edx, [eax+usb_device_data.ConfigDataSize]
lea eax, [eax+ecx+sizeof.usb_device_data] lea eax, [eax+ecx+sizeof.usb_device_data]

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -179,8 +179,7 @@ struct TSS
_io_map_1 rb 4096 _io_map_1 rb 4096
ends ends
PARTITION_COUNT equ 64 DRIVE_DATA_SIZE equ 16
DRIVE_DATA_SIZE equ (16+PARTITION_COUNT*100)
OS_BASE equ 0x80000000 OS_BASE equ 0x80000000
@@ -205,7 +204,7 @@ FDD_BUFF equ (OS_BASE+0x000D000) ;512
WIN_TEMP_XY equ (OS_BASE+0x000F300) WIN_TEMP_XY equ (OS_BASE+0x000F300)
KEY_COUNT equ (OS_BASE+0x000F400) 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_COUNT equ (OS_BASE+0x000F500)
BTN_BUFF equ (OS_BASE+0x000F501) BTN_BUFF equ (OS_BASE+0x000F501)
@@ -220,11 +219,7 @@ TASK_ACTIVATE equ (OS_BASE+0x000FF01)
TMP_STACK_TOP equ 0x006CC00 TMP_STACK_TOP equ 0x006CC00
sys_pgdir equ (OS_BASE+0x006F000) sys_proc equ (OS_BASE+0x006F000)
lfb_pd_0 equ (OS_BASE+0x0070000)
lfb_pd_1 equ (OS_BASE+0x0071000)
lfb_pd_2 equ (OS_BASE+0x0072000)
lfb_pd_3 equ (OS_BASE+0x0073000)
SLOT_BASE equ (OS_BASE+0x0080000) SLOT_BASE equ (OS_BASE+0x0080000)
@@ -233,10 +228,6 @@ VGABasePtr equ (OS_BASE+0x00A0000)
CLEAN_ZONE equ (_CLEAN_ZONE-OS_BASE) CLEAN_ZONE equ (_CLEAN_ZONE-OS_BASE)
IDE_DMA equ (_IDE_DMA-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) UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000)
virtual at (OS_BASE+0x05FFF80) 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 master_tab equ (page_tabs+ (page_tabs shr 10)) ;0xFDFF70000
LFB_BASE equ 0xFE000000 LFB_BASE equ 0xFE000000
LFB_SIZE equ 12*1024*1024
new_app_base equ 0; 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 REG_RET equ (RING0_STACK_SIZE-56) ;irq0.return
PAGE_SIZE equ 4096
PG_UNMAP equ 0x000 PG_UNMAP equ 0x000
PG_MAP equ 0x001 PG_MAP equ 0x001
PG_WRITE equ 0x002 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_DMA equ 0x901F ;
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data BOOT_PCI_DATA equ 0x9020 ;8bytes pci data
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no 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_MEM_AMOUNT equ 0x9034 ;dword memory amount
BOOT_APM_ENTRY equ 0x9040 BOOT_APM_ENTRY equ 0x9040
@@ -315,12 +308,12 @@ BOOT_APM_FLAGS equ 0x9046 ;unused
BOOT_APM_CODE_32 equ 0x9050 BOOT_APM_CODE_32 equ 0x9050
BOOT_APM_CODE_16 equ 0x9052 BOOT_APM_CODE_16 equ 0x9052
BOOT_APM_DATA_16 equ 0x9054 BOOT_APM_DATA_16 equ 0x9054
BOOT_IDE_BAR0_16 equ 0x9056 ;BOOT_IDE_BAR0_16 equ 0x9056 ; now free and is not used
BOOT_IDE_BAR1_16 equ 0x9058 ;BOOT_IDE_BAR1_16 equ 0x9058 ; now free and is not used
BOOT_IDE_BAR2_16 equ 0x905A ;BOOT_IDE_BAR2_16 equ 0x905A ; now free and is not used
BOOT_IDE_BAR3_16 equ 0x905C ;BOOT_IDE_BAR3_16 equ 0x905C ; now free and is not used
BOOT_IDE_PI_16 equ 0x905E ;BOOT_IDE_PI_16 equ 0x905E ; now free and is not used
BOOT_IDE_INTERR_16 equ 0x9060 ;BOOT_IDE_INTERR_16 equ 0x9060 ; now free and is not used
TMP_FILE_NAME equ 0 TMP_FILE_NAME equ 0
TMP_CMD_LINE equ 1024 TMP_CMD_LINE equ 1024
@@ -437,7 +430,7 @@ struct display_t
y dd ? y dd ?
width dd ? width dd ?
height dd ? height dd ?
bpp dd ? bits_per_pixel dd ?
vrefresh dd ? vrefresh dd ?
pitch dd ? pitch dd ?
lfb dd ? lfb dd ?
@@ -461,6 +454,8 @@ struct display_t
mask_seqno dd ? mask_seqno dd ?
check_mouse dd ? check_mouse dd ?
check_m_pixel dd ? check_m_pixel dd ?
bytes_per_pixel dd ?
ends ends
struct BOOT_DATA struct BOOT_DATA
@@ -507,14 +502,13 @@ struct MUTEX
ends ends
struct PCIDEV struct PCIDEV
list LHEAD bk dd ?
vid_did dd ? fd dd ?
vendor_device_id dd ?
class dd ? class dd ?
svid_sdid dd ?
devfn db ? devfn db ?
bus db ? bus db ?
irq_line db ? rb 2
rb 1
owner dd ? ; pointer to SRV or 0 owner dd ? ; pointer to SRV or 0
ends ends
@@ -625,6 +619,28 @@ struct COFF_SYM
NumAuxSymbols db ? NumAuxSymbols db ?
ends 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 struct IOCTL
handle dd ? handle dd ?
io_code dd ? io_code dd ?

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
iglobal iglobal
IRQ_COUNT dd 24 IRQ_COUNT dd 24

View File

@@ -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 align 4
sys_clipboard: sys_clipboard:

View File

@@ -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 ; Éste archivo debe ser editado con codificación CP866
ugui_mouse_speed cp850 'velocidad del ratón',0 ugui_mouse_speed cp850 'velocidad del ratón',0

View File

@@ -136,9 +136,18 @@ debug_getcontext:
; ecx=pid ; ecx=pid
; edx=sizeof(CONTEXT) ; edx=sizeof(CONTEXT)
; esi->CONTEXT ; esi->CONTEXT
; destroys eax,ecx,edx,esi,edi ; destroys eax,ebx,ecx,edx,esi,edi
cmp edx, 28h
jnz .ret 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 ; push ecx
; mov ecx, esi ; mov ecx, esi
call check_region call check_region
@@ -147,8 +156,15 @@ debug_getcontext:
jnz .ret jnz .ret
call get_debuggee_slot call get_debuggee_slot
jc .ret jc .ret
shr eax, 5
cmp eax, [fpu_owner]
jne @f
inc bh ; set swap context flag
@@:
shl eax, 8
mov edi, esi 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] lea esi, [eax+RING0_STACK_SIZE]
.ring0: .ring0:
@@ -178,6 +194,29 @@ debug_getcontext:
mov [edi+4], eax mov [edi+4], eax
lodsd ;esp lodsd ;esp
mov [edi+18h], eax 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: .ret:
sti sti
ret ret

View File

@@ -123,13 +123,13 @@ proc get_service stdcall, sz_name:dword
stdcall strncmp, edx, [sz_name], 16 stdcall strncmp, edx, [sz_name], 16
test eax, eax test eax, eax
je .ok mov eax, edx
je .nothing
mov edx, [edx+SRV.fd] mov edx, [edx+SRV.fd]
jmp @B jmp @B
.not_load: .not_load:
mov eax, [sz_name] mov eax, [sz_name]
; Try to load .dll driver first. If not, fallback to .obj.
push edi push edi
sub esp, 36 sub esp, 36
mov edi, esp mov edi, esp
@@ -150,12 +150,6 @@ proc get_service stdcall, sz_name:dword
stdcall load_pe_driver, edi, 0 stdcall load_pe_driver, edi, 0
add esp, 36 add esp, 36
pop edi pop edi
test eax, eax
jnz .nothing
pop ebp
jmp load_driver
.ok:
mov eax, edx
.nothing: .nothing:
ret ret
endp endp
@@ -794,177 +788,6 @@ proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
ret ret
endp 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 ; in: edx -> COFF_SECTION struct
; out: eax = alignment as mask for bits to drop ; out: eax = alignment as mask for bits to drop
coff_get_align: coff_get_align:
@@ -1009,10 +832,9 @@ proc load_library stdcall, file_name:dword
; ignore timestamp ; ignore timestamp
cli cli
mov esi, [CURRENT_TASK] mov esi, [current_process]
shl esi, 8
lea edi, [fullname] lea edi, [fullname]
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr] mov ebx, [esi+PROC.dlls_list_ptr]
test ebx, ebx test ebx, ebx
jz .not_in_process jz .not_in_process
mov esi, [ebx+HDLL.fd] mov esi, [ebx+HDLL.fd]
@@ -1372,28 +1194,21 @@ endp
; out: eax = APPDATA.dlls_list_ptr if all is OK, ; out: eax = APPDATA.dlls_list_ptr if all is OK,
; NULL if memory allocation failed ; NULL if memory allocation failed
init_dlls_in_thread: init_dlls_in_thread:
mov ebx, [current_slot] mov ebx, [current_process]
mov eax, [ebx+APPDATA.dlls_list_ptr] mov eax, [ebx+PROC.dlls_list_ptr]
test eax, eax test eax, eax
jnz .ret jnz .ret
push [ebx+APPDATA.dir_table]
mov eax, 8 mov eax, 8
call malloc call malloc ; FIXME
pop edx
test eax, eax test eax, eax
jz .ret jz .ret
mov [eax], eax mov [eax], eax
mov [eax+4], eax mov [eax+4], eax
mov ecx, [TASK_COUNT]
mov ebx, SLOT_BASE+256 mov ebx, [current_process]
.set: mov [ebx+PROC.dlls_list_ptr], eax
cmp [ebx+APPDATA.dir_table], edx
jnz @f
mov [ebx+APPDATA.dlls_list_ptr], eax
@@:
add ebx, 256
dec ecx
jnz .set
.ret: .ret:
ret ret
@@ -1414,59 +1229,10 @@ dereference_dll:
destroy_hdll: destroy_hdll:
push ebx ecx esi edi push ebx ecx esi edi
push eax
mov ebx, [eax+HDLL.base] mov ebx, [eax+HDLL.base]
mov esi, [eax+HDLL.parent] mov esi, [eax+HDLL.parent]
mov edx, [esi+DLLDESCR.size] 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 push eax
mov esi, [eax+HDLL.parent] mov esi, [eax+HDLL.parent]
mov eax, [eax+HDLL.refcount] mov eax, [eax+HDLL.refcount]

View File

@@ -7,11 +7,6 @@
$Revision$ $Revision$
iglobal
szKernel db 'KERNEL', 0
szVersion db 'version',0
endg
align 4 align 4
__exports: __exports:
export 'KERNEL', \ export 'KERNEL', \
@@ -48,6 +43,7 @@ __exports:
get_phys_addr, 'GetPhysAddr', \ ; eax get_phys_addr, 'GetPhysAddr', \ ; eax
map_space, 'MapSpace', \ map_space, 'MapSpace', \
release_pages, 'ReleasePages', \ release_pages, 'ReleasePages', \
alloc_dma24, 'AllocDMA24', \ ; stdcall
\ \
mutex_init, 'MutexInit', \ ; gcc fastcall mutex_init, 'MutexInit', \ ; gcc fastcall
mutex_lock, 'MutexLock', \ ; gcc fastcall mutex_lock, 'MutexLock', \ ; gcc fastcall
@@ -94,6 +90,7 @@ __exports:
load_cursor, 'LoadCursor', \ ;stdcall load_cursor, 'LoadCursor', \ ;stdcall
\ \
get_curr_task, 'GetCurrentTask', \ get_curr_task, 'GetCurrentTask', \
change_task, 'ChangeTask', \
load_file, 'LoadFile', \ ;retval eax, ebx load_file, 'LoadFile', \ ;retval eax, ebx
delay_ms, 'Sleep', \ delay_ms, 'Sleep', \
\ \
@@ -105,6 +102,7 @@ __exports:
strrchr, 'strrchr', \ strrchr, 'strrchr', \
\ \
timer_hs, 'TimerHS', \ timer_hs, 'TimerHS', \
timer_hs, 'TimerHs', \ ; shit happens
cancel_timer_hs, 'CancelTimerHS', \ cancel_timer_hs, 'CancelTimerHS', \
\ \
reg_usb_driver, 'RegUSBDriver', \ reg_usb_driver, 'RegUSBDriver', \
@@ -120,6 +118,8 @@ __exports:
NET_ptr_to_num, 'NetPtrToNum', \ NET_ptr_to_num, 'NetPtrToNum', \
NET_link_changed, 'NetLinkChanged', \ NET_link_changed, 'NetLinkChanged', \
ETH_input, 'Eth_input', \ ETH_input, 'Eth_input', \
\
get_pcidev_list, 'GetPCIList', \
\ \
0, 'LFBAddress' ; must be the last one 0, 'LFBAddress' ; must be the last one
load kernel_exports_count dword from __exports + 24 load kernel_exports_count dword from __exports + 24

View File

@@ -129,15 +129,11 @@ proc init_kernel_heap
loop @B loop @B
stdcall alloc_pages, dword 32 stdcall alloc_pages, dword 32
or eax, PG_SW
mov ebx, HEAP_BASE
mov ecx, 32 mov ecx, 32
mov edx, eax call commit_pages
mov edi, HEAP_BASE
.l1:
stdcall map_page, edi, edx, PG_SW
add edi, 0x1000
add edx, 0x1000
dec ecx
jnz .l1
mov edi, HEAP_BASE ;descriptors mov edi, HEAP_BASE ;descriptors
mov ebx, HEAP_BASE+sizeof.MEM_BLOCK ;free space mov ebx, HEAP_BASE+sizeof.MEM_BLOCK ;free space
@@ -480,46 +476,39 @@ proc kernel_alloc stdcall, size:dword
mov [pages_count], ebx mov [pages_count], ebx
stdcall alloc_kernel_space, eax stdcall alloc_kernel_space, eax
mov [lin_addr], eax
mov ebx, [pages_count]
test eax, eax test eax, eax
jz .err jz .err
mov [lin_addr], eax
mov ecx, [pages_count]
mov edx, eax mov edx, eax
mov ebx, ecx
shr ecx, 3 shr ebx, 3
jz .next jz .tail
and ebx, not 7 shl ebx, 3
push ebx
stdcall alloc_pages, ebx stdcall alloc_pages, ebx
pop ecx ; yes ecx!!! test eax, eax
and eax, eax
jz .err jz .err
mov edi, eax mov ecx, ebx
mov edx, [lin_addr] or eax, PG_SW
@@: mov ebx, [lin_addr]
stdcall map_page, edx, edi, dword PG_SW call commit_pages
add edx, 0x1000
add edi, 0x1000 mov edx, ebx ; this dirty hack
dec ecx .tail:
jnz @B mov ebx, [pages_count]
.next: and ebx, 7
mov ecx, [pages_count]
and ecx, 7
jz .end jz .end
@@: @@:
push ecx
call alloc_page call alloc_page
pop ecx
test eax, eax test eax, eax
jz .err jz .err
stdcall map_page, edx, eax, dword PG_SW stdcall map_page, edx, eax, dword PG_SW
add edx, 0x1000 add edx, 0x1000
dec ecx dec ebx
jnz @B jnz @B
.end: .end:
mov eax, [lin_addr] mov eax, [lin_addr]
@@ -569,33 +558,36 @@ restore block_base
restore block_size restore block_size
restore block_flags restore block_flags
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;; USER HEAP ;;;;;;;;;;;;;;;;;
HEAP_TOP equ 0x80000000 HEAP_TOP equ 0x80000000
align 4 align 4
proc init_heap proc init_heap
mov ebx, [current_slot] mov ebx, [current_process]
mov eax, [ebx+APPDATA.heap_top] mov eax, [ebx+PROC.heap_top]
test eax, eax test eax, eax
jz @F jz @F
sub eax, [ebx+APPDATA.heap_base] sub eax, [ebx+PROC.heap_base]
sub eax, 4096 sub eax, PAGE_SIZE
ret 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 add esi, 4095
and esi, not 4095 and esi, not 4095
mov [ebx+APPDATA.mem_size], esi mov [ebx+PROC.mem_used], esi
mov eax, HEAP_TOP mov eax, HEAP_TOP
mov [ebx+APPDATA.heap_base], esi mov [ebx+PROC.heap_base], esi
mov [ebx+APPDATA.heap_top], eax mov [ebx+PROC.heap_top], eax
sub eax, esi sub eax, esi
shr esi, 10 shr esi, 10
mov ecx, eax mov ecx, eax
sub eax, 4096 sub eax, PAGE_SIZE
or ecx, FREE_BLOCK or ecx, FREE_BLOCK
mov [page_tabs+esi], ecx mov [page_tabs+esi], ecx
ret ret
@@ -608,25 +600,28 @@ proc user_alloc stdcall, alloc_size:dword
push esi push esi
push edi push edi
mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
mov ecx, [alloc_size] mov ecx, [alloc_size]
add ecx, (4095+4096) add ecx, (4095+PAGE_SIZE)
and ecx, not 4095 and ecx, not 4095
mov ebx, [current_slot] mov esi, dword [ebx+PROC.heap_base] ; heap_base
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base mov edi, dword [ebx+PROC.heap_top] ; heap_top
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top .scan:
l_0:
cmp esi, edi cmp esi, edi
jae m_exit jae .m_exit
mov ebx, esi mov ebx, esi
shr ebx, 12 shr ebx, 12
mov eax, [page_tabs+ebx*4] mov eax, [page_tabs+ebx*4]
test al, FREE_BLOCK test al, FREE_BLOCK
jz test_used jz .test_used
and eax, 0xFFFFF000 and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size cmp eax, ecx ;alloc_size
jb m_next jb .m_next
jz @f jz @f
lea edx, [esi+ecx] lea edx, [esi+ecx]
@@ -648,12 +643,14 @@ l_0:
jnz @B jnz @B
.no: .no:
mov edx, [current_slot] mov edx, [current_process]
mov ebx, [alloc_size] mov ebx, [alloc_size]
add ebx, 0xFFF add ebx, 0xFFF
and ebx, not 0xFFF and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size] add [edx+PROC.mem_used], ebx
call update_mem_size
lea ecx, [edx+PROC.heap_lock]
call mutex_unlock
lea eax, [esi+4096] lea eax, [esi+4096]
@@ -661,15 +658,19 @@ l_0:
pop esi pop esi
pop ebx pop ebx
ret ret
test_used: .test_used:
test al, USED_BLOCK test al, USED_BLOCK
jz m_exit jz .m_exit
and eax, 0xFFFFF000 and eax, 0xFFFFF000
m_next: .m_next:
add esi, eax add esi, eax
jmp l_0 jmp .scan
m_exit: .m_exit:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
xor eax, eax xor eax, eax
pop edi pop edi
pop esi pop esi
@@ -684,14 +685,17 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
push esi push esi
push edi push edi
mov ebx, [current_slot] mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
mov edx, [address] mov edx, [address]
and edx, not 0xFFF and edx, not 0xFFF
mov [address], edx mov [address], edx
sub edx, 0x1000 sub edx, 0x1000
jb .error jb .error
mov esi, [ebx+APPDATA.heap_base] mov esi, [ebx+PROC.heap_base]
mov edi, [ebx+APPDATA.heap_top] mov edi, [ebx+PROC.heap_top]
cmp edx, esi cmp edx, esi
jb .error jb .error
.scan: .scan:
@@ -708,6 +712,10 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
mov esi, ecx mov esi, ecx
jmp .scan jmp .scan
.error: .error:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
xor eax, eax xor eax, eax
pop edi pop edi
pop esi pop esi
@@ -759,13 +767,14 @@ proc user_alloc_at stdcall, address:dword, alloc_size:dword
mov [page_tabs+ebx*4], ecx mov [page_tabs+ebx*4], ecx
.nothird: .nothird:
mov edx, [current_process]
mov edx, [current_slot]
mov ebx, [alloc_size] mov ebx, [alloc_size]
add ebx, 0xFFF add ebx, 0xFFF
and ebx, not 0xFFF and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size] add [edx+PROC.mem_used], ebx
call update_mem_size
lea ecx, [edx+PROC.heap_lock]
call mutex_unlock
mov eax, [address] mov eax, [address]
@@ -782,10 +791,14 @@ proc user_free stdcall, base:dword
mov esi, [base] mov esi, [base]
test esi, esi test esi, esi
jz .exit jz .fail
push ebx push ebx
mov ebx, [current_process]
lea ecx, [ebx+PROC.heap_lock]
call mutex_lock
xor ebx, ebx xor ebx, ebx
shr esi, 12 shr esi, 12
mov eax, [page_tabs+(esi-1)*4] mov eax, [page_tabs+(esi-1)*4]
@@ -821,25 +834,30 @@ proc user_free stdcall, base:dword
.released: .released:
push edi push edi
mov edx, [current_slot] mov edx, [current_process]
mov esi, dword [edx+APPDATA.heap_base] lea ecx, [edx+PROC.heap_lock]
mov edi, dword [edx+APPDATA.heap_top] mov esi, dword [edx+PROC.heap_base]
sub ebx, [edx+APPDATA.mem_size] mov edi, dword [edx+PROC.heap_top]
sub ebx, [edx+PROC.mem_used]
neg ebx neg ebx
call update_mem_size mov [edx+PROC.mem_used], ebx
call user_normalize call user_normalize
pop edi pop edi
pop ebx
pop esi
ret
.exit: .exit:
call mutex_unlock
xor eax, eax xor eax, eax
inc eax inc eax
pop ebx
pop esi pop esi
ret ret
.cantfree: .cantfree:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
jmp .exit
.fail:
xor eax, eax xor eax, eax
pop ebx
pop esi pop esi
ret ret
endp endp
@@ -968,6 +986,13 @@ user_realloc:
ret ret
@@: @@:
push ecx edx push ecx edx
push eax
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_lock
pop eax
lea ecx, [eax - 0x1000] lea ecx, [eax - 0x1000]
shr ecx, 12 shr ecx, 12
mov edx, [page_tabs+ecx*4] mov edx, [page_tabs+ecx*4]
@@ -975,6 +1000,10 @@ user_realloc:
jnz @f jnz @f
; attempt to realloc invalid pointer ; attempt to realloc invalid pointer
.ret0: .ret0:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop edx ecx pop edx ecx
xor eax, eax xor eax, eax
ret ret
@@ -1009,16 +1038,16 @@ user_realloc:
jnz .nofreeall jnz .nofreeall
mov eax, [page_tabs+ecx*4] mov eax, [page_tabs+ecx*4]
and eax, not 0xFFF and eax, not 0xFFF
mov edx, [current_slot] mov edx, [current_process]
mov ebx, [APPDATA.mem_size+edx] mov ebx, [edx+PROC.mem_used]
sub ebx, eax sub ebx, eax
add ebx, 0x1000 add ebx, 0x1000
or al, FREE_BLOCK or al, FREE_BLOCK
mov [page_tabs+ecx*4], eax mov [page_tabs+ecx*4], eax
push esi edi push esi edi
mov esi, [APPDATA.heap_base+edx] mov esi, [edx+PROC.heap_base]
mov edi, [APPDATA.heap_top+edx] mov edi, [edx+PROC.heap_top]
call update_mem_size mov [edx+PROC.mem_used], ebx
call user_normalize call user_normalize
pop edi esi pop edi esi
jmp .ret0 ; all freed jmp .ret0 ; all freed
@@ -1030,11 +1059,11 @@ user_realloc:
shr ebx, 12 shr ebx, 12
sub ebx, edx sub ebx, edx
push ebx ecx edx push ebx ecx edx
mov edx, [current_slot] mov edx, [current_process]
shl ebx, 12 shl ebx, 12
sub ebx, [APPDATA.mem_size+edx] sub ebx, [edx+PROC.mem_used]
neg ebx neg ebx
call update_mem_size mov [edx+PROC.mem_used], ebx
pop edx ecx ebx pop edx ecx ebx
lea eax, [ecx+1] lea eax, [ecx+1]
shl eax, 12 shl eax, 12
@@ -1044,8 +1073,8 @@ user_realloc:
shl ebx, 12 shl ebx, 12
jz .ret jz .ret
push esi push esi
mov esi, [current_slot] mov esi, [current_process]
mov esi, [APPDATA.heap_top+esi] mov esi, [esi+PROC.heap_top]
shr esi, 12 shr esi, 12
@@: @@:
cmp edx, esi cmp edx, esi
@@ -1064,12 +1093,16 @@ user_realloc:
or ebx, FREE_BLOCK or ebx, FREE_BLOCK
mov [page_tabs+ecx*4], ebx mov [page_tabs+ecx*4], ebx
.ret: .ret:
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop eax edx ecx pop eax edx ecx
ret ret
.realloc_add: .realloc_add:
; get some additional memory ; get some additional memory
mov eax, [current_slot] mov eax, [current_process]
mov eax, [APPDATA.heap_top+eax] mov eax, [eax+PROC.heap_top]
shr eax, 12 shr eax, 12
cmp edx, eax cmp edx, eax
jae .cant_inplace jae .cant_inplace
@@ -1101,17 +1134,21 @@ user_realloc:
cld cld
rep stosd rep stosd
pop edi pop edi
mov edx, [current_slot] mov edx, [current_process]
shl ebx, 12 shl ebx, 12
add ebx, [APPDATA.mem_size+edx] add [edx+PROC.mem_used], ebx
call update_mem_size
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop eax edx ecx pop eax edx ecx
ret ret
.cant_inplace: .cant_inplace:
push esi edi push esi edi
mov eax, [current_slot] mov eax, [current_process]
mov esi, [APPDATA.heap_base+eax] mov esi, [eax+PROC.heap_base]
mov edi, [APPDATA.heap_top+eax] mov edi, [eax+PROC.heap_top]
shr esi, 12 shr esi, 12
shr edi, 12 shr edi, 12
sub ebx, ecx sub ebx, ecx
@@ -1174,58 +1211,25 @@ user_realloc:
jnz @b jnz @b
.no: .no:
push ebx push ebx
mov edx, [current_slot] mov edx, [current_process]
shl ebx, 12 shl ebx, 12
add ebx, [APPDATA.mem_size+edx] add [edx+PROC.mem_used], ebx
call update_mem_size
pop ebx pop ebx
@@: @@:
mov dword [page_tabs+esi*4], 2 mov dword [page_tabs+esi*4], 2
inc esi inc esi
dec ebx dec ebx
jnz @b jnz @b
mov ecx, [current_process]
lea ecx, [ecx+PROC.heap_lock]
call mutex_unlock
pop eax edi esi edx ecx pop eax edi esi edx ecx
ret 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 ; param

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
IRQ_RESERVED equ 24 IRQ_RESERVED equ 24
IRQ_POOL_SIZE equ 48 IRQ_POOL_SIZE equ 48

View File

@@ -123,19 +123,19 @@ proc alloc_pages stdcall, count:dword
endp endp
align 4 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 push ebx
mov eax, [phis_addr] mov eax, [esp+12] ; phis_addr
and eax, not 0xFFF and eax, not 0xFFF
or eax, [flags] or eax, [esp+16] ; flags
mov ebx, [lin_addr] mov ebx, [esp+8] ; lin_addr
shr ebx, 12 shr ebx, 12
mov [page_tabs+ebx*4], eax mov [page_tabs+ebx*4], eax
mov eax, [lin_addr] mov eax, [esp+8] ; lin_addr
invlpg [eax]
pop ebx pop ebx
ret invlpg [eax]
endp ret 12
align 4 align 4
map_space: ;not implemented map_space: ;not implemented
@@ -350,9 +350,64 @@ proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
ret ret
endp 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 align 4
init_LFB: proc init_LFB
xchg bx, bx locals
pg_count dd ?
endl
cmp dword [LFBAddress], -1 cmp dword [LFBAddress], -1
jne @f jne @f
@@ -381,34 +436,62 @@ init_LFB:
@@: @@:
call init_mtrr call init_mtrr
xor edx, edx mov edx, LFB_BASE
mov eax, [LFBAddress] 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 bt [cpu_caps], CAPS_PGE
setc dh ;eliminate branch and jnc @F
mov ecx, LFB_SIZE/4096 or dword [sys_proc+PROC.pdt_0+(LFB_BASE shr 20)], PG_GLOBAL
mov edi, lfb_pd_0 @@:
lea eax, [eax+edx+PG_UW] ;set PG_GLOBAL if supported
.map_pte:
stosd
add eax, 0x1000
loop .map_pte
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 dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB mov eax, cr3 ;flush TLB
mov cr3, eax mov cr3, eax
ret ret
.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
dec ecx
jnz @B
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
endp
align 4 align 4
proc new_mem_resize stdcall, new_size:dword proc new_mem_resize stdcall, new_size:dword
@@ -417,7 +500,9 @@ proc new_mem_resize stdcall, new_size:dword
push edi push edi
mov edx, [current_slot] mov edx, [current_slot]
cmp [edx+APPDATA.heap_base], 0 mov ebx, [edx+APPDATA.process]
cmp [ebx+PROC.heap_base], 0
jne .exit jne .exit
mov edi, [new_size] mov edi, [new_size]
@@ -425,7 +510,7 @@ proc new_mem_resize stdcall, new_size:dword
and edi, not 4095 and edi, not 4095
mov [new_size], edi mov [new_size], edi
mov esi, [edx+APPDATA.mem_size] mov esi, [ebx+PROC.mem_used]
add esi, 4095 add esi, 4095
and esi, not 4095 and esi, not 4095
@@ -460,7 +545,8 @@ proc new_mem_resize stdcall, new_size:dword
.update_size: .update_size:
mov edx, [current_slot] mov edx, [current_slot]
mov ebx, [new_size] mov ebx, [new_size]
call update_mem_size mov edx, [edx+APPDATA.process]
mov [edx+PROC.mem_used], ebx
.exit: .exit:
pop edi pop edi
pop esi pop esi
@@ -536,38 +622,6 @@ proc new_mem_resize stdcall, new_size:dword
endp 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 ; param
; eax= linear address ; eax= linear address
; ;
@@ -624,11 +678,6 @@ end if
pop ebx ;restore exception number (#PF) pop ebx ;restore exception number (#PF)
ret ret
; xchg bx, bx
; add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
; restore_ring3_context
; iretd
.user_space: .user_space:
test eax, PG_MAP test eax, PG_MAP
jnz .err_access ;Страница присутствует jnz .err_access ;Страница присутствует
@@ -668,9 +717,8 @@ end if
; access denied? this may be a result of copy-on-write protection for DLL ; access denied? this may be a result of copy-on-write protection for DLL
; check list of HDLLs ; check list of HDLLs
and ebx, not 0xFFF and ebx, not 0xFFF
mov eax, [CURRENT_TASK] mov eax, [current_process]
shl eax, 8 mov eax, [eax+PROC.dlls_list_ptr]
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
test eax, eax test eax, eax
jz .fail jz .fail
mov esi, [eax+HDLL.fd] mov esi, [eax+HDLL.fd]
@@ -746,120 +794,129 @@ end if
endp endp
; returns number of mapped bytes ; 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 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 cmp [buf_size], 0
jz .exit jz .exit
mov eax, [slot] mov eax, [slot]
shl eax, 8 shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table] mov eax, [SLOT_BASE+eax+APPDATA.process]
and eax, 0xFFFFF000 test eax, eax
jz .exit
stdcall map_page, [ipc_pdir], eax, PG_UW mov [process], eax
mov ebx, [ofs] mov ebx, [ofs]
shr ebx, 22 shr ebx, 22
mov esi, [ipc_pdir] mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table
mov edi, [ipc_ptab] mov esi, [ipc_ptab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000 and eax, 0xFFFFF000
jz .exit jz .exit
stdcall map_page, edi, eax, PG_UW stdcall map_page, esi, eax, PG_SW
; inc ebx
; add edi, 0x1000
; mov eax, [esi+ebx*4]
; test eax, eax
; jz @f
; and eax, 0xFFFFF000
; stdcall map_page, edi, eax
@@: @@:
mov edi, [lin_addr] mov edi, [lin_addr]
and edi, 0xFFFFF000 and edi, 0xFFFFF000
mov ecx, [buf_size] mov ecx, [buf_size]
add ecx, 4095 add ecx, 4095
shr ecx, 12 shr ecx, 12
inc ecx inc ecx ; ???????????
mov edx, [ofs] mov edx, [ofs]
shr edx, 12 shr edx, 12
and edx, 0x3FF and edx, 0x3FF
mov esi, [ipc_ptab]
.map: .map:
stdcall safe_map_page, [slot], [req_access], [ofs] stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit jnc .exit
add dword [ebp-4], 4096 add [count], PAGE_SIZE
add [ofs], 4096 add [ofs], PAGE_SIZE
dec ecx dec ecx
jz .exit jz .exit
add edi, 0x1000
add edi, PAGE_SIZE
inc edx inc edx
cmp edx, 0x400 cmp edx, 1024
jnz .map jnz .map
inc ebx inc ebx
mov eax, [ipc_pdir] mov eax, [process]
mov eax, [eax+ebx*4] mov eax, [eax+PROC.pdt_0+ebx*4]
and eax, 0xFFFFF000 and eax, 0xFFFFF000
jz .exit jz .exit
stdcall map_page, esi, eax, PG_UW
stdcall map_page, esi, eax, PG_SW
xor edx, edx xor edx, edx
jmp .map jmp .map
.exit: .exit:
pop eax mov eax, [count]
ret ret
endp endp
proc map_memEx stdcall, lin_addr:dword,slot:dword,\ proc map_memEx stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access: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 cmp [buf_size], 0
jz .exit jz .exit
mov eax, [slot] mov eax, [slot]
shl eax, 8 shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table] mov eax, [SLOT_BASE+eax+APPDATA.process]
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
test eax, eax test eax, eax
jz .exit 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] mov edi, [lin_addr]
and edi, 0xFFFFF000 and edi, 0xFFFFF000
mov ecx, [buf_size] mov ecx, [buf_size]
add ecx, 4095 add ecx, 4095
shr ecx, 12 shr ecx, 12
inc ecx inc ecx ; ???????????
mov edx, [ofs] mov edx, [ofs]
shr edx, 12 shr edx, 12
and edx, 0x3FF and edx, 0x3FF
mov esi, [proc_mem_tab]
.map: .map:
stdcall safe_map_page, [slot], [req_access], [ofs] stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit jnc .exit
add dword [ebp-4], 0x1000 add [count], PAGE_SIZE
add edi, 0x1000 add [ofs], PAGE_SIZE
add [ofs], 0x1000
inc edx
dec ecx dec ecx
jz .exit
add edi, PAGE_SIZE
inc edx
cmp edx, 1024
jnz .map 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: .exit:
pop eax mov eax, [count]
ret ret
endp endp
@@ -905,7 +962,8 @@ proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
push ebx ecx push ebx ecx
mov eax, [slot] mov eax, [slot]
shl eax, 8 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 test eax, eax
jz .no_hdll jz .no_hdll
mov ecx, [eax+HDLL.fd] mov ecx, [eax+HDLL.fd]
@@ -992,29 +1050,6 @@ sys_IPC:
mov [esp+32], eax mov [esp+32], eax
ret 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 proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
locals locals
dst_slot dd ? dst_slot dd ?
@@ -1033,7 +1068,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
mov [dst_slot], eax mov [dst_slot], eax
shl eax, 8 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 test edi, edi
jz .no_ipc_area jz .no_ipc_area
@@ -1041,7 +1076,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
and ebx, 0xFFF and ebx, 0xFFF
mov [dst_offset], ebx mov [dst_offset], ebx
mov esi, [eax+SLOT_BASE+0xa4] mov esi, [eax+SLOT_BASE+APPDATA.ipc_size]
mov [buf_size], esi mov [buf_size], esi
mov ecx, [ipc_tmp] mov ecx, [ipc_tmp]
@@ -1054,7 +1089,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
pop edi esi pop edi esi
@@: @@:
mov [used_buf], ecx mov [used_buf], ecx
stdcall map_mem, ecx, [dst_slot], \ stdcall map_mem_ipc, ecx, [dst_slot], \
edi, esi, PG_SW edi, esi, PG_SW
mov edi, [dst_offset] mov edi, [dst_offset]
@@ -1125,7 +1160,7 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
.ret: .ret:
mov eax, [used_buf] mov eax, [used_buf]
cmp eax, [ipc_tmp] cmp eax, [ipc_tmp]
jz @f je @f
stdcall free_kernel_space, eax stdcall free_kernel_space, eax
@@: @@:
pop eax pop eax
@@ -1329,113 +1364,6 @@ proc load_pe_driver stdcall, file:dword, cmdline:dword
ret ret
endp 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 align 4
proc create_ring_buffer stdcall, size:dword, flags:dword proc create_ring_buffer stdcall, size:dword, flags:dword
locals locals

View File

@@ -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

View File

@@ -24,15 +24,30 @@ proc load_PE stdcall, file_name:dword
mov [image], eax 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 test eax, eax
jz .cleanup jz .cleanup
mov [base], eax 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 mov [entry], eax
test eax, eax test eax, eax
@@ -48,199 +63,200 @@ proc load_PE stdcall, file_name:dword
ret ret
endp endp
DWORD equ dword map_PE: ;ebp=base:dword, ebx=image:dword
PTR equ
align 4
map_PE: ;stdcall base:dword, image:dword
cld
push ebp
push edi push edi
push esi push esi
push ebx sub esp, .locals_size
sub esp, 60 virtual at esp
mov ebx, DWORD PTR [esp+84] .numsections dd ?
mov ebp, DWORD PTR [esp+80] .import_names dd ?
mov edx, ebx .import_targets dd ?
mov esi, ebx .peheader dd ?
add edx, DWORD PTR [ebx+60] .bad_import dd ?
mov edi, ebp .import_idx dd ?
mov DWORD PTR [esp+32], edx .import_descr dd ?
mov ecx, DWORD PTR [edx+84] .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 shr ecx, 2
rep movsd rep movsd
movzx eax, WORD PTR [edx+6] cmp [.numsections], 0
mov DWORD PTR [esp+36], 0 jz .nosections
mov DWORD PTR [esp+16], eax .copy_sections:
jmp L2 mov eax, [edx+8]
L3:
mov eax, DWORD PTR [edx+264]
test eax, eax test eax, eax
je L4 je .no_section_data
mov esi, ebx mov esi, ebx
mov edi, ebp mov edi, ebp
add esi, DWORD PTR [edx+268] add esi, [edx+12]
mov ecx, eax mov ecx, eax
add edi, DWORD PTR [edx+260] add edi, [edx+4]
add ecx, 3 add ecx, 3
shr ecx, 2 shr ecx, 2
rep movsd rep movsd
L4: .no_section_data:
mov ecx, DWORD PTR [edx+256] mov ecx, [edx]
cmp ecx, eax cmp ecx, eax
jbe L6 jbe .no_section_fill
sub ecx, eax sub ecx, eax
add eax, DWORD PTR [edx+260] add eax, [edx+4]
lea edi, [eax+ebp] lea edi, [eax+ebp]
xor eax, eax xor eax, eax
rep stosb rep stosb
L6: .no_section_fill:
inc DWORD PTR [esp+36] add edx, [.section_header_size]
add edx, 40 dec [.numsections]
L2: jnz .copy_sections
mov esi, DWORD PTR [esp+16] .nosections:
cmp DWORD PTR [esp+36], esi cmp [.relocs_size], 0
jne L3 je .no_relocations
mov edi, DWORD PTR [esp+32]
cmp DWORD PTR [edi+164], 0
je L9
pushd [edi+164]
mov esi, ebp mov esi, ebp
mov ecx, ebp mov ecx, ebp
sub esi, DWORD PTR [edi+52] sub esi, [.ImageBase]
add ecx, DWORD PTR [edi+160] add ecx, [.relocs_rva]
mov eax, esi .relocs_block:
shr eax, 16 mov edi, [ecx]
mov DWORD PTR [esp+16], eax add edi, ebp
L12: mov ebx, [ecx+4]
mov eax, [ecx+4] add ecx, 8
sub [esp], eax sub [.relocs_size], ebx
lea ebx, [eax-8] sub ebx, 8
xor edi, edi
shr ebx, 1 shr ebx, 1
jmp L13 jz .relocs_next_block
L14: .one_reloc:
movzx eax, WORD PTR [ecx+8+edi*2] movzx eax, word [ecx]
add ecx, 2
mov edx, eax mov edx, eax
shr eax, 12 shr eax, 12
and edx, 4095 and edx, 4095
add edx, DWORD PTR [ecx] cmp eax, 3
cmp ax, 2 jne @f
je L17 add [edx+edi], esi
cmp ax, 3 @@:
je L18 dec ebx
dec ax jnz .one_reloc
jne L15 .relocs_next_block:
mov eax, DWORD PTR [esp+16] cmp [.relocs_size], 0
add WORD PTR [edx+ebp], ax jg .relocs_block
L17: .no_relocations:
add WORD PTR [edx+ebp], si cmp [.import_descr], 0
L18: je .no_imports
add DWORD PTR [edx+ebp], esi add [.import_descr], ebp
L15: mov [.bad_import], 0
inc edi .import_block:
L13: mov ecx, [.import_descr]
cmp edi, ebx cmp dword [ecx+4], 0
jne L14 jne @f
add ecx, DWORD PTR [ecx+4] cmp dword [ecx+12], 0
L11: je .done_imports
cmp dword [esp], 0 @@:
jg L12 mov edx, dword [ecx]
pop eax mov ecx, dword [ecx+16]
L9:
mov edx, DWORD PTR [esp+32]
cmp DWORD PTR [edx+132], 0
je L20
mov eax, ebp
add eax, DWORD PTR [edx+128]
mov DWORD PTR [esp+40], 0
add eax, 20
mov DWORD PTR [esp+56], eax
L22:
mov ecx, DWORD PTR [esp+56]
cmp DWORD PTR [ecx-16], 0
jne L23
cmp DWORD PTR [ecx-8], 0
je L25
L23:
mov edi, DWORD PTR [__exports+32]
mov esi, DWORD PTR [__exports+28]
mov eax, DWORD PTR [esp+56]
mov DWORD PTR [esp+20], edi
add edi, OS_BASE
add esi, OS_BASE
mov DWORD PTR [esp+44], esi
mov ecx, DWORD PTR [eax-4]
mov DWORD PTR [esp+48], edi
mov edx, DWORD PTR [eax-20]
test edx, edx test edx, edx
jnz @f jnz @f
mov edx, ecx mov edx, ecx
@@: @@:
mov DWORD PTR [esp+52], 0 mov [.import_idx], 0
add ecx, ebp add ecx, ebp
add edx, ebp add edx, ebp
mov DWORD PTR [esp+24], edx mov [.import_names], edx
mov DWORD PTR [esp+28], ecx mov [.import_targets], ecx
L26: .import_func:
mov esi, DWORD PTR [esp+52] mov esi, [.import_idx]
mov edi, DWORD PTR [esp+24] mov edi, [.import_names]
mov eax, DWORD PTR [edi+esi*4] mov eax, [edi+esi*4]
test eax, eax test eax, eax
je L27 je .next_import_block
test eax, eax js .next_import_block
js L27
lea edi, [ebp+eax] lea edi, [ebp+eax]
mov eax, DWORD PTR [esp+28] mov eax, [.import_targets]
mov DWORD PTR [eax+esi*4], 0 mov dword [eax+esi*4], 0
lea esi, [edi+2] lea esi, [edi+2]
push eax movzx ebx, word [edi]
push 32 push 32
movzx eax, WORD PTR [edi] mov ecx, [__exports+32]
mov edx, DWORD PTR [esp+56] mov eax, [ecx+OS_BASE+ebx*4]
mov eax, DWORD PTR [edx+eax*4]
add eax, OS_BASE add eax, OS_BASE
push eax push eax
push esi push esi
call strncmp call strncmp
pop ebx test eax, eax
jz .import_func_found
xor ebx, ebx xor ebx, ebx
test eax, eax .import_func_candidate:
jne L32
jmp L30
L33:
push ecx
push 32 push 32
mov ecx, DWORD PTR [esp+28] mov ecx, [__exports+32]
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4] mov eax, [ecx+OS_BASE+ebx*4]
add eax, OS_BASE add eax, OS_BASE
push eax push eax
push esi push esi
call strncmp call strncmp
pop edx
test eax, eax test eax, eax
jne L34 je .import_func_found
mov esi, DWORD PTR [esp+44]
mov edx, DWORD PTR [esp+52]
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+ebx*4]
add eax, OS_BASE
mov DWORD PTR [ecx+edx*4], eax
jmp L36
L34:
inc ebx inc ebx
L32: cmp ebx, [__exports+24]
cmp ebx, DWORD PTR [__exports+24] jb .import_func_candidate
jb L33
L36:
cmp ebx, DWORD PTR [__exports+24]
jne L37
mov esi, msg_unresolved mov esi, msg_unresolved
call sys_msg_board_str call sys_msg_board_str
@@ -249,34 +265,30 @@ L36:
mov esi, msg_CR mov esi, msg_CR
call sys_msg_board_str call sys_msg_board_str
mov DWORD PTR [esp+40], 1 mov [.bad_import], 1
jmp L37 jmp .next_import_func
L30: .import_func_found:
movzx eax, WORD PTR [edi] mov esi, [__exports+28]
mov esi, DWORD PTR [esp+44] mov edx, [.import_idx]
mov edi, DWORD PTR [esp+52] mov ecx, [.import_targets]
mov edx, DWORD PTR [esp+28] mov eax, [esi+OS_BASE+ebx*4]
mov eax, DWORD PTR [esi+eax*4]
add eax, OS_BASE add eax, OS_BASE
mov DWORD PTR [edx+edi*4], eax mov [ecx+edx*4], eax
L37: .next_import_func:
inc DWORD PTR [esp+52] inc [.import_idx]
jmp L26 jmp .import_func
L27: .next_import_block:
add DWORD PTR [esp+56], 20 add [.import_descr], 20
jmp L22 jmp .import_block
L25: .done_imports:
xor eax, eax xor eax, eax
cmp DWORD PTR [esp+40], 0 cmp [.bad_import], 0
jne L40 jne @f
L20: .no_imports:
mov ecx, DWORD PTR [esp+32]
mov eax, ebp mov eax, ebp
add eax, DWORD PTR [ecx+40] add eax, [.AddressOfEntryPoint]
L40: @@:
add esp, 60 add esp, .locals_size
pop ebx
pop esi pop esi
pop edi pop edi
pop ebp ret
ret 8

View File

@@ -29,8 +29,7 @@ irq0:
.nocounter: .nocounter:
xor ecx, ecx ; send End Of Interrupt signal xor ecx, ecx ; send End Of Interrupt signal
call irq_eoi call irq_eoi
; btr dword[DONT_SWITCH], 0
; jc .return
mov bl, SCHEDULE_ANY_PRIORITY mov bl, SCHEDULE_ANY_PRIORITY
call find_next_task call find_next_task
jz .return ; if there is only one running process jz .return ; if there is only one running process
@@ -44,26 +43,10 @@ change_task:
pushfd pushfd
cli cli
pushad 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 mov bl, SCHEDULE_ANY_PRIORITY
call find_next_task call find_next_task
jz .return ; the same task -> skip switch jz .return ; the same task -> skip switch
@@:
; mov byte[DONT_SWITCH], 1
call do_change_task call do_change_task
.return: .return:
popad 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_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] Mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
; set new thread memory-map ; set new thread memory-map
mov ecx, APPDATA.dir_table mov eax, [ebx+APPDATA.process]
mov eax, [ebx+ecx] ;offset>0x7F cmp eax, [current_process]
cmp eax, [esi+ecx] ;offset>0x7F
je @f je @f
mov [current_process], eax
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax mov cr3, eax
@@: @@:
; set tss.esp0 ; set tss.esp0
@@ -159,7 +143,7 @@ do_change_task:
jz @f jz @f
xor eax, eax xor eax, eax
mov dr6, eax mov dr6, eax
lea esi, [ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table];offset>0x7F lea esi, [ebx+APPDATA.dbg_regs]
cld cld
macro lodsReg [reg] { macro lodsReg [reg] {
lodsd lodsd

View File

@@ -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 ; Éste archivo debe ser editado con codificación CP866
msg_sel_ker cp850 "núcleo", 0 msg_sel_ker cp850 "núcleo", 0

View File

@@ -413,23 +413,26 @@ endg
align 4 align 4
terminate: ; terminate application 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 push esi ;save .slot
shl esi, 8 shl esi, 8
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0 mov edx, [SLOT_BASE+esi+APPDATA.process]
jne @F test edx, edx
jnz @F
pop esi pop esi
shl esi, 5 shl esi, 5
mov [CURRENT_TASK+esi+TASKDATA.state], 9 mov [CURRENT_TASK+esi+TASKDATA.state], 9
ret ret
@@: @@:
push edx ;save .process
lea edx, [SLOT_BASE+esi] lea edx, [SLOT_BASE+esi]
call scheduler_remove_thread call scheduler_remove_thread
;mov esi,process_terminating
;call sys_msg_board_str
call lock_application_table call lock_application_table
; if the process is in V86 mode... ; if the process is in V86 mode...
@@ -442,14 +445,14 @@ terminate: ; terminate application
; ...it has page directory for V86 mode ; ...it has page directory for V86 mode
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0] mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
mov ecx, [esi+4] 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 ; ...and I/O permission map for V86 mode
mov ecx, [esi+12] mov ecx, [esi+12]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [esi+8] mov ecx, [esi+8]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
.nov86: .nov86:
;destroy per-thread kernel objects
mov esi, [.slot] mov esi, [.slot]
shl esi, 8 shl esi, 8
add esi, SLOT_BASE+APP_OBJ_OFFSET add esi, SLOT_BASE+APP_OBJ_OFFSET
@@ -467,11 +470,6 @@ terminate: ; terminate application
pop esi pop esi
jmp @B 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] mov esi, [.slot]
cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2 cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2
jne @F jne @F
@@ -630,6 +628,9 @@ terminate: ; terminate application
je @F je @F
call free_page call free_page
@@: @@:
lea ebx, [edi+APPDATA.list]
list_del ebx ;destroys edx, ecx
mov eax, 0x20202020 mov eax, 0x20202020
stosd stosd
stosd stosd
@@ -745,7 +746,17 @@ terminate: ; terminate application
add ecx, 0x100 add ecx, 0x100
jmp .xd0 jmp .xd0
.xd1: .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 sti ; .. and life goes on
mov eax, [draw_limits.left] mov eax, [draw_limits.left]
@@ -760,18 +771,10 @@ terminate: ; terminate application
call unlock_application_table call unlock_application_table
;mov esi,process_terminated ;mov esi,process_terminated
;call sys_msg_board_str ;call sys_msg_board_str
add esp, 4 add esp, 8
ret ret
restore .slot restore .slot
restore .process
;build_scheduler:
; mov esi, boot_sched_1
; call boot_log
; call build_process_gdt_tss_pointer
; mov esi,boot_sched_2
; call boot_log
; ret
; Three following procedures are used to guarantee that ; Three following procedures are used to guarantee that
; some part of kernel code will not be terminated from outside ; some part of kernel code will not be terminated from outside

View File

@@ -70,7 +70,7 @@ proc fs_execute
filename rd 256 ;1024/4 filename rd 256 ;1024/4
flags dd ? flags dd ?
save_cr3 dd ? save_proc dd ?
slot dd ? slot dd ?
slot_base dd ? slot_base dd ?
file_base dd ? file_base dd ?
@@ -215,7 +215,7 @@ proc fs_execute
call lock_application_table call lock_application_table
call get_new_process_place call alloc_thread_slot
test eax, eax test eax, eax
mov esi, -0x20 ; too many processes mov esi, -0x20 ; too many processes
jz .err jz .err
@@ -248,18 +248,23 @@ proc fs_execute
loop .copy_process_name_loop loop .copy_process_name_loop
.copy_process_name_done: .copy_process_name_done:
mov ebx, cr3 mov ebx, [current_process]
mov [save_cr3], ebx 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 mov esi, -30; no memory
test eax, eax test eax, eax
jz .failed jz .failed
mov ebx, [hdr_mem]
mov [eax+PROC.mem_used], ebx
mov ebx, [slot_base] mov ebx, [slot_base]
mov [ebx+APPDATA.dir_table], eax mov [ebx+APPDATA.process], eax
mov eax, [hdr_mem]
mov [ebx+APPDATA.mem_size], eax lea edx, [ebx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail edx, ecx
xor edx, edx xor edx, edx
cmp word [6], '02' cmp word [6], '02'
@@ -292,7 +297,7 @@ end if
lea ecx, [filename] lea ecx, [filename]
stdcall set_app_params , [slot], eax, ebx, ecx, [flags] stdcall set_app_params , [slot], eax, ebx, ecx, [flags]
mov eax, [save_cr3] mov eax, [save_proc]
call set_cr3 call set_cr3
mov eax, [process_number];set result mov eax, [process_number];set result
@@ -301,7 +306,7 @@ end if
jmp .final jmp .final
.failed: .failed:
mov eax, [save_cr3] mov eax, [save_proc]
call set_cr3 call set_cr3
.err: .err:
.err_hdr: .err_hdr:
@@ -385,53 +390,55 @@ test_app_header:
ret ret
align 4 align 4
proc get_new_process_place alloc_thread_slot:
;input: ;input:
; none ; none
;result: ;result:
; eax=[new_process_place]<>0 - ok ; eax=[new_thread_slot]<>0 - ok
; 0 - failed. ; 0 - failed.
;This function find least empty slot. ;This function find least empty slot.
;It doesn't increase [TASK_COUNT]! ;It doesn't increase [TASK_COUNT]!
mov eax, CURRENT_TASK
mov ebx, [TASK_COUNT]
inc ebx mov edx, thr_slot_map
shl ebx, 5 pushfd
add ebx, eax ;ebx - address of process information for (last+1) slot cli
.newprocessplace: .l1:
;eax = address of process information for current slot bsf eax, [edx]
cmp eax, ebx jnz .found
jz .endnewprocessplace ;empty slot after high boundary add edx, 4
add eax, 0x20 cmp edx, thr_slot_map+32
cmp word [eax+0xa], 9;check process state, 9 means that process slot is empty jb .l1
jnz .newprocessplace
.endnewprocessplace: popfd
mov ebx, eax
sub eax, CURRENT_TASK
shr eax, 5 ;calculate slot index
cmp eax, 256
jge .failed ;it should be <256
mov word [ebx+0xa], 9;set process state to 9 (for slot after hight boundary)
ret
.failed:
xor eax, eax xor eax, eax
ret ret
endp .found:
btr [edx], eax
sub edx, thr_slot_map
lea eax, [eax+edx*8]
popfd
ret
align 4 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 locals
app_pages dd ? app_pages dd ?
img_pages dd ? img_pages dd ?
dir_addr dd ? process dd ?
app_tabs dd ? app_tabs dd ?
endl endl
push ebx
push esi
push edi
mov ecx, pg_data.mutex mov ecx, pg_data.mutex
call mutex_lock call mutex_lock
xor eax, eax xor eax, eax
mov [dir_addr], eax mov [process], eax
mov eax, [app_size] mov eax, [app_size]
add eax, 4095 add eax, 4095
@@ -454,39 +461,59 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
shr ecx, 12 shr ecx, 12
mov [img_pages], ecx mov [img_pages], ecx
if GREEDY_KERNEL
lea eax, [ecx+ebx+2];only image size
else
lea eax, [eax+ebx+2];all requested memory lea eax, [eax+ebx+2];all requested memory
end if
cmp eax, [pg_data.pages_free] cmp eax, [pg_data.pages_free]
ja .fail ja .fail
call alloc_page stdcall kernel_alloc, 0x2000
test eax, eax test eax, eax
jz .fail jz .fail
mov [dir_addr], eax mov [process], eax
stdcall map_page, [tmp_task_pdir], eax, dword PG_SW
lea edi, [eax+PROC.heap_lock]
mov ecx, (PROC.ht_next-PROC.heap_lock)/4
list_init eax
add eax, PROC.thr_list
list_init eax
mov edi, [tmp_task_pdir]
mov ecx, (OS_BASE shr 20)/4
xor eax, eax xor eax, eax
cld cld
rep stosd 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 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 rep movsd
mov eax, [dir_addr] mov eax, [edi-8192+PROC.pdt_0_phys]
or eax, PG_SW or eax, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax mov [edi-4096+(page_tabs shr 20)], eax
and eax, -4096 lea eax, [edi-8192]
call set_cr3 call set_cr3
mov edx, [app_tabs] mov ecx, [app_tabs]
mov edi, new_app_base test ecx, ecx
jz .done
xor edi, edi
@@: @@:
call alloc_page call alloc_page
test eax, eax test eax, eax
@@ -494,81 +521,81 @@ end if
stdcall map_page_table, edi, eax stdcall map_page_table, edi, eax
add edi, 0x00400000 add edi, 0x00400000
dec edx loop @B
jnz @B
mov edi, new_app_base mov edi, page_tabs
shr edi, 10
add edi, page_tabs
mov ecx, [app_tabs] mov ecx, [app_tabs]
shl ecx, 10 shl ecx, 10
xor eax, eax xor eax, eax
rep stosd rep stosd
xor edx, edx
mov ecx, [img_pages] mov ecx, [img_pages]
jcxz .bss
sub [app_pages], ecx
mov ebx, PG_UW mov ebx, PG_UW
mov edx, new_app_base
mov esi, [img_base] mov esi, [img_base]
mov edi, new_app_base
shr esi, 10 shr esi, 10
shr edi, 10
add esi, page_tabs add esi, page_tabs
add edi, page_tabs mov edi, page_tabs
.remap: .remap:
lodsd lodsd
and eax, 0xFFFFF000 and eax, 0xFFFFF000
or eax, ebx; force user level r/w access or eax, ebx; force user level r/w access
stosd stosd
add edx, 0x1000 add edx, 0x1000
dec [app_pages] loop .remap
dec ecx .bss:
jnz .remap mov ebx, [app_pages]
test ebx, ebx
mov ecx, [app_pages]
test ecx, ecx
jz .done jz .done
if GREEDY_KERNEL .map_bss:
mov eax, 0x02
rep stosd
else
.alloc:
call alloc_page call alloc_page
test eax, eax test eax, eax
jz .fail jz .fail
stdcall map_page, edx, eax, dword PG_UW stdcall map_page, edx, eax, dword PG_UW
add edx, 0x1000 add edx, 0x1000
dec [app_pages] dec ebx
jnz .alloc jnz .map_bss
end if
.done: .done:
stdcall map_page, [tmp_task_pdir], dword 0, dword PG_UNMAP
mov ecx, pg_data.mutex mov ecx, pg_data.mutex
call mutex_unlock call mutex_unlock
mov eax, [dir_addr] mov eax, [process]
pop edi
pop esi
pop ebx
ret ret
.fail: .fail:
mov ecx, pg_data.mutex mov ecx, pg_data.mutex
call mutex_unlock call mutex_unlock
cmp [dir_addr], 0 cmp [process], 0
je @f je @f
stdcall destroy_app_space, [dir_addr], 0 ;; stdcall destroy_app_space, [dir_addr], 0
@@: @@:
xor eax, eax xor eax, eax
pop edi
pop esi
pop ebx
ret ret
endp endp
align 4 align 4
set_cr3: set_cr3:
pushfd
cli
mov ebx, [current_slot] 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 mov cr3, eax
popfd
ret ret
align 4 align 4
@@ -582,6 +609,8 @@ proc destroy_page_table stdcall, pg_tab:dword
mov eax, [esi] mov eax, [esi]
test eax, 1 test eax, 1
jz .next jz .next
test eax, 2
jz .next
test eax, 1 shl 9 test eax, 1 shl 9
jnz .next ;skip shared pages jnz .next ;skip shared pages
call free_page call free_page
@@ -594,46 +623,25 @@ proc destroy_page_table stdcall, pg_tab:dword
endp endp
align 4 align 4
proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword destroy_process: ;fastcall ecx= ptr to process
xor edx, edx lea eax, [ecx+PROC.thr_list]
push edx cmp eax, [eax+LHEAD.next]
mov eax, 0x1 jne .exit
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
;edx = number of threads align 4
;our process is zombi so it isn't counted .internal:
pop ecx push ecx
cmp edx, 1
jg .ret
;if there isn't threads then clear memory.
mov esi, [dlls_list]
call destroy_all_hdlls;ecx=APPDATA
mov ecx, pg_data.mutex mov esi, [ecx+PROC.dlls_list_ptr]
call mutex_lock call destroy_all_hdlls
mov eax, [pg_dir] ; mov ecx, pg_data.mutex
and eax, not 0xFFF ; call mutex_lock
stdcall map_page, [tmp_task_pdir], eax, PG_SW
mov esi, [tmp_task_pdir] mov esi, [esp]
mov edi, (OS_BASE shr 20)/4 add esi, PROC.pdt_0
mov edi, (0x80000000 shr 20)/4
.destroy: .destroy:
mov eax, [esi] mov eax, [esi]
test eax, 1 test eax, 1
@@ -648,16 +656,13 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
dec edi dec edi
jnz .destroy jnz .destroy
mov eax, [pg_dir] call kernel_free ;ecx still in stack
call free_page
.exit:
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
stdcall map_page, [tmp_task_pdir], 0, PG_UNMAP ; mov ecx, pg_data.mutex
mov ecx, pg_data.mutex ; call mutex_unlock
call mutex_unlock
.ret: .exit:
ret ret
endp
align 4 align 4
get_pid: get_pid:
@@ -708,6 +713,10 @@ check_region:
;result: ;result:
; eax = 1 region lays in app memory ; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory ; eax = 0 region don't lays in app memory
mov eax, 1
ret
if 0
mov eax, [CURRENT_TASK] mov eax, [CURRENT_TASK]
; jmp check_process_region ; jmp check_process_region
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
@@ -732,57 +741,13 @@ check_region:
mov eax, 1 mov eax, 1
ret 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: .ok:
mov eax, 1 mov eax, 1
ret ret
;
;.failed1:
; pop edx
; pop ecx
; pop ebx
.failed: .failed:
xor eax, eax xor eax, eax
ret ret
end if
align 4 align 4
proc read_process_memory proc read_process_memory
@@ -954,7 +919,7 @@ proc new_sys_threads
call lock_application_table call lock_application_table
call get_new_process_place call alloc_thread_slot
test eax, eax test eax, eax
jz .failed jz .failed
@@ -976,20 +941,12 @@ proc new_sys_threads
mov ecx, 11 mov ecx, 11
rep movsb ;copy process name rep movsb ;copy process name
mov eax, [ebx+APPDATA.heap_base] mov eax, [ebx+APPDATA.process]
mov [edx+APPDATA.heap_base], eax mov [edx+APPDATA.process], eax
mov ecx, [ebx+APPDATA.heap_top] lea ebx, [edx+APPDATA.list]
mov [edx+APPDATA.heap_top], ecx lea ecx, [eax+PROC.thr_list]
list_add_tail ebx, ecx ;add thread to process child's list
mov eax, [ebx+APPDATA.mem_size]
mov [edx+APPDATA.mem_size], eax
mov ecx, [ebx+APPDATA.dir_table]
mov [edx+APPDATA.dir_table], ecx;copy page directory
mov eax, [ebx+APPDATA.dlls_list_ptr]
mov [edx+APPDATA.dlls_list_ptr], eax
mov eax, [ebx+APPDATA.tls_base] mov eax, [ebx+APPDATA.tls_base]
test eax, eax test eax, eax
@@ -1118,8 +1075,8 @@ proc set_app_params stdcall,slot:dword, params:dword,\
add eax, 256 add eax, 256
jc @f jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] ; cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f ; ja @f
mov eax, [cmd_line] mov eax, [cmd_line]
@@ -1158,8 +1115,8 @@ proc set_app_params stdcall,slot:dword, params:dword,\
mov eax, edx mov eax, edx
add eax, 1024 add eax, 1024
jc @f jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] ; cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f ; ja @f
stdcall strncpy, edx, [app_path], 1024 stdcall strncpy, edx, [app_path], 1024
@@: @@:
mov ebx, [slot] mov ebx, [slot]
@@ -1188,9 +1145,9 @@ proc set_app_params stdcall,slot:dword, params:dword,\
xor eax, eax xor eax, eax
mov [ecx+0], dword eax mov [ecx+0], dword eax
mov [ecx+4], dword eax mov [ecx+4], dword eax
mov eax, [_display.width] mov eax, [Screen_Max_X]
mov [ecx+8], eax mov [ecx+8], eax
mov eax, [_display.height] mov eax, [Screen_Max_Y]
mov [ecx+12], eax mov [ecx+12], eax
mov ebx, [pl0_stack] mov ebx, [pl0_stack]

View File

@@ -14,9 +14,7 @@ DEBUG_SHOW_IO = 0
struct V86_machine struct V86_machine
; page directory ; page directory
pagedir dd ? process dd ?
; translation table: V86 address -> flat linear address
pages dd ?
; mutex to protect all data from writing by multiple threads at one time ; mutex to protect all data from writing by multiple threads at one time
mutex dd ? mutex dd ?
; i/o permission map ; i/o permission map
@@ -38,91 +36,87 @@ v86_create:
and dword [eax+V86_machine.mutex], 0 and dword [eax+V86_machine.mutex], 0
; allocate tables ; allocate tables
mov ebx, eax mov ebx, eax
; We allocate 4 pages.
; First is main page directory for V86 mode. stdcall create_process, 4096, eax, 4096 ;FIXME
; Second page: test eax, eax
; first half (0x800 bytes) is page table for addresses 0 - 0x100000, jz .fail2
; second half is for V86-to-linear translation.
; Third and fourth are for I/O permission map. mov [eax+PROC.mem_used], 4096
push 8000h ; blocks less than 8 pages are discontinuous mov [ebx+V86_machine.process], eax
push 2000h
call kernel_alloc call kernel_alloc
test eax, eax test eax, eax
jz .fail2 jz .fail2
mov [ebx+V86_machine.pagedir], eax
push edi eax mov [ebx+V86_machine.iopm], eax
mov edi, eax
add eax, 1800h
mov [ebx+V86_machine.pages], eax
; initialize tables ; initialize tables
mov ecx, 2000h/4 push edi
xor eax, eax
rep stosd
mov [ebx+V86_machine.iopm], edi
dec eax
mov ecx, 2000h/4
rep stosd
pop eax
; page directory: first entry is page table...
mov edi, eax mov edi, eax
add eax, 1000h mov eax, -1
push eax mov ecx, 2000h/4
call get_pg_addr rep stosd
or al, PG_UW
stosd mov eax, [ebx+V86_machine.process]
; ...and also copy system page tables mov eax, [eax+PROC.pdt_0_phys]
; thx to Serge, system is located at high addresses
add edi, (OS_BASE shr 20) - 4 pushfd
push esi cli
mov esi, (OS_BASE shr 20) + sys_pgdir mov cr3, eax
mov ecx, 0x80000000 shr 22
rep movsd
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 ; now V86 specific: initialize known addresses in first Mb
pop eax
; first page - BIOS data (shared between all machines!) ; first page - BIOS data (shared between all machines!)
; physical address = 0 ; physical address = 0
; linear address = OS_BASE ; 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!) ; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
; physical address = 0x9C000 ; physical address = 0x9C000
; linear address = 0x8009C000 ; linear address = 0x8009C000
; (I have seen one computer with EBDA segment = 0x9D80, ; (I have seen one computer with EBDA segment = 0x9D80,
; all other computers use less memory) ; all other computers use less memory)
mov ecx, 4
mov edx, 0x9C000 mov eax, PG_UW
push eax mov [page_tabs], eax
lea edi, [eax+0x9C*4] 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 stosd
add edx, 0x1000 add eax, edx
loop @b loop @b
pop eax
pop edi
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!) ; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
; physical address = 0xC0000 ; 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 stosd
shl edx, 12 add eax, edx
push edx loop @b
or edx, 111b
mov [eax+ecx*4], edx mov eax, sys_proc
pop edx push ebx
add edx, OS_BASE call set_cr3
mov [eax+ecx*4+0x800], edx pop ebx
inc cl popfd
jnz @b
pop edi
mov eax, ebx mov eax, ebx
ret ret
.fail2: .fail2:
@@ -132,15 +126,16 @@ v86_create:
xor eax, eax xor eax, eax
ret ret
;not used
; Destroy V86 machine ; Destroy V86 machine
; in: eax = handle ; in: eax = handle
; out: nothing ; out: nothing
; destroys: eax, ebx, ecx, edx (due to free) ; destroys: eax, ebx, ecx, edx (due to free)
v86_destroy: ;v86_destroy:
push eax ; push eax
stdcall kernel_free, [eax+V86_machine.pagedir] ; stdcall kernel_free, [eax+V86_machine.pagedir]
pop eax ; pop eax
jmp free ; jmp free
; Translate V86-address to linear address ; Translate V86-address to linear address
; in: eax=V86 address ; in: eax=V86 address
@@ -150,28 +145,30 @@ v86_destroy:
v86_get_lin_addr: v86_get_lin_addr:
push ecx edx push ecx edx
mov ecx, eax mov ecx, eax
mov edx, [esi+V86_machine.pages]
shr ecx, 12 shr ecx, 12
mov edx, [page_tabs+ecx*4]
and eax, 0xFFF and eax, 0xFFF
add eax, [edx+ecx*4] ; atomic operation, no mutex needed and edx, 0xFFFFF000
or eax, edx
pop edx ecx pop edx ecx
ret ret
;not used
; Sets linear address for V86-page ; Sets linear address for V86-page
; in: eax=linear address (must be page-aligned) ; in: eax=linear address (must be page-aligned)
; ecx=V86 page (NOT address!) ; ecx=V86 page (NOT address!)
; esi=handle ; esi=handle
; out: nothing ; out: nothing
; destroys: nothing ; destroys: nothing
v86_set_page: ;v86_set_page:
push eax ebx ; push eax ebx
mov ebx, [esi+V86_machine.pagedir] ; mov ebx, [esi+V86_machine.pagedir]
mov [ebx+ecx*4+0x1800], eax ; mov [ebx+ecx*4+0x1800], eax
call get_pg_addr ; call get_pg_addr
or al, 111b ; or al, 111b
mov [ebx+ecx*4+0x1000], eax ; mov [ebx+ecx*4+0x1000], eax
pop ebx eax ; pop ebx eax
ret ; ret
; Allocate memory in V86 machine ; Allocate memory in V86 machine
; in: eax=size (in bytes) ; in: eax=size (in bytes)
@@ -214,21 +211,7 @@ init_sys_v86:
mov [sys_v86_machine], eax mov [sys_v86_machine], eax
test eax, eax test eax, eax
jz .ret 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 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 if ~DEBUG_SHOW_IO
; allow access to all ports ; allow access to all ports
mov ecx, [esi+V86_machine.iopm] mov ecx, [esi+V86_machine.iopm]
@@ -272,36 +255,38 @@ ends
; eax = 3 - IRQ is already hooked by another VM ; eax = 3 - IRQ is already hooked by another VM
; destroys: nothing ; destroys: nothing
v86_start: v86_start:
pushad pushad
cli cli
mov ecx, [CURRENT_TASK] mov ecx, [current_slot]
shl ecx, 8
add ecx, SLOT_BASE
mov eax, [esi+V86_machine.iopm]
call get_pg_addr
inc eax
push dword [ecx+APPDATA.io_map] push dword [ecx+APPDATA.io_map]
push dword [ecx+APPDATA.io_map+4] push dword [ecx+APPDATA.io_map+4]
mov dword [ecx+APPDATA.io_map], eax push [ecx+APPDATA.process]
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.saved_esp0] push [ecx+APPDATA.saved_esp0]
mov [ecx+APPDATA.saved_esp0], esp mov [ecx+APPDATA.saved_esp0], esp
mov [tss._esp0], esp mov [tss._esp0], esp
mov eax, [esi+V86_machine.pagedir] mov eax, [esi+V86_machine.iopm]
call get_pg_addr call get_pg_addr
mov [ecx+APPDATA.dir_table], eax inc eax
mov cr3, 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 ; We do not enable interrupts, because V86 IRQ redirector assumes that
; machine is running ; machine is running
@@ -782,19 +767,21 @@ end if
mov esp, esi mov esp, esi
cli cli
mov ecx, [CURRENT_TASK] mov ecx, [current_slot]
shl ecx, 8
pop eax pop eax
mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax
mov [ecx+APPDATA.saved_esp0], eax
mov [tss._esp0], eax mov [tss._esp0], eax
pop eax pop eax
mov [SLOT_BASE+ecx+APPDATA.dir_table], eax mov [ecx+APPDATA.process], eax
mov [current_process], eax
pop ebx 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 mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx
pop 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 dword [page_tabs + (tss._io_map_0 shr 10)], ebx
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax mov cr3, eax
sti sti
@@ -843,11 +830,10 @@ v86_irq:
pop eax pop eax
v86_irq2: v86_irq2:
mov esi, [v86_irqhooks+edi*8] ; get VM handle mov esi, [v86_irqhooks+edi*8] ; get VM handle
mov eax, [esi+V86_machine.pagedir] mov eax, [esi+V86_machine.process]
call get_pg_addr
mov ecx, [CURRENT_TASK] mov ecx, [CURRENT_TASK]
shl ecx, 8 shl ecx, 8
cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax cmp [SLOT_BASE+ecx+APPDATA.process], eax
jnz .notcurrent jnz .notcurrent
lea eax, [edi+8] lea eax, [edi+8]
cmp al, 10h cmp al, 10h
@@ -860,7 +846,7 @@ v86_irq2:
mov ebx, SLOT_BASE + 0x100 mov ebx, SLOT_BASE + 0x100
mov ecx, [TASK_COUNT] mov ecx, [TASK_COUNT]
.scan: .scan:
cmp [ebx+APPDATA.dir_table], eax cmp [ebx+APPDATA.process], eax
jnz .cont jnz .cont
push ecx push ecx
mov ecx, [ebx+APPDATA.saved_esp0] mov ecx, [ebx+APPDATA.saved_esp0]
@@ -895,6 +881,7 @@ v86_irq2:
popad popad
iretd iretd
.found: .found:
mov eax, [eax+PROC.pdt_0_phys]
mov cr3, eax mov cr3, eax
mov esi, [ebx+APPDATA.saved_esp0] mov esi, [ebx+APPDATA.saved_esp0]
sub word [esi-sizeof.v86_regs+v86_regs.esp], 6 sub word [esi-sizeof.v86_regs+v86_regs.esp], 6

View File

@@ -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 ;; ;; 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 start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
msg_unresolved db 'unresolved ',0 msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0 ;msg_module db 'in module ',0
if ~ lang eq sp ;if ~ lang eq sp
msg_version db 'incompatible driver version',13,10,0 ;msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0 ;msg_www db 'please visit www.kolibrios.org',13,10,0
end if ;end if
msg_CR db 13,10,0 msg_CR db 13,10,0
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
szHwMouse db 'ATI2D',0 szHwMouse db 'ATI2D',0
szPS2MDriver db 'PS2MOUSE',0 szPS2MDriver db '/rd/1/drivers/PS2MOUSE.SYS',0
;szCOM_MDriver db 'COM_MOUSE',0 ;szCOM_MDriver db 'COM_MOUSE',0
szVidintel db 'vidintel',0 szVidintel db '/rd/1/drivers/vidintel.sys',0
szUSB db 'USB',0 szUSB db 'USB',0
szAtiHW db '/rd/1/drivers/ati2d.drv',0 szAtiHW db '/rd/1/drivers/ati2d.drv',0
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0 szEXPORTS db 'EXPORTS',0
sz_EXPORTS db '_EXPORTS',0 sz_EXPORTS db '_EXPORTS',0
@@ -168,8 +164,10 @@ firstapp db 'LAUNCHER',0
notifyapp db '@notify',0 notifyapp db '@notify',0
if lang eq ru if lang eq ru
ud_user_message cp866 'Ошибка: неподдерживаемая инструкция процессора',0 ud_user_message cp866 'Ошибка: неподдерживаемая инструкция процессора',0
mtrr_user_message cp866 '"Обнаружена проблема с конфигурацией MTRR.\nПроизводительность может быть пониженной" -dW',0
else if ~ lang eq sp else if ~ lang eq sp
ud_user_message db 'Error: unsupported processor instruction',0 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 end if
vmode db '/sys/drivers/VMODE.MDR',0 vmode db '/sys/drivers/VMODE.MDR',0
@@ -179,7 +177,7 @@ kernel_file_load:
dd 0 ; subfunction dd 0 ; subfunction
dq 0 ; offset in file dq 0 ; offset in file
dd 0x30000 ; number of bytes to read 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 db '/RD/1/KERNEL.MNT',0
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',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_used_list rd 64*2
mem_hash_cnt rd 64 mem_hash_cnt rd 64
thr_slot_map rd 8
cpu_freq rq 1 cpu_freq rq 1
heap_mutex MUTEX heap_mutex MUTEX
@@ -378,12 +378,14 @@ _display display_t
_WinMapAddress rd 1 _WinMapAddress rd 1
_WinMapSize rd 1 _WinMapSize rd 1
LFBAddress rd 1 LFBAddress dd ?
Screen_Max_X dd ?
Screen_Max_Y dd ?
SCR_MODE rw 2 SCR_MODE rw 2
PUTPIXEL rd 1 PUTPIXEL dd ?
GETPIXEL rd 1 GETPIXEL dd ?
if VESA_1_2_VIDEO if VESA_1_2_VIDEO
BANK_SWITCH rd 1 reserved for vesa 1.2 BANK_SWITCH rd 1 reserved for vesa 1.2
@@ -399,7 +401,7 @@ d_width_calc_area rd 1140
mouseunder rd 16*24 mouseunder rd 16*24
MOUSE_PICTURE rd 1 MOUSE_PICTURE dd ?
MOUSE_SCROLL_H rw 1 MOUSE_SCROLL_H rw 1
MOUSE_X: rw 1 MOUSE_X: rw 1
@@ -436,14 +438,15 @@ proc_mem_map rd 1
proc_mem_pdir rd 1 proc_mem_pdir rd 1
proc_mem_tab rd 1 proc_mem_tab rd 1
tmp_task_pdir rd 1
tmp_task_ptab rd 1 tmp_task_ptab rd 1
default_io_map rd 1 default_io_map rd 1
LFBSize rd 1 LFBSize rd 1
current_slot rd 1 current_process rd 1
current_slot rd 1 ; i.e. cureent thread
; status ; status
hd1_status rd 1 ; 0 - free : other - pid hd1_status rd 1 ; 0 - free : other - pid
@@ -460,8 +463,6 @@ cdid rd 1
hdbase rd 1 ; for boot 0x1f0 hdbase rd 1 ; for boot 0x1f0
hdid rd 1 hdid rd 1
hdpos rd 1 ; for boot 0x1 hdpos rd 1 ; for boot 0x1
label known_part dword
fat32part rd 1 ; for boot 0x1
cdpos rd 1 cdpos rd 1
;CPUID information ;CPUID information
@@ -494,63 +495,12 @@ BgrDataHeight rd 1
skin_data 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 debug_step_pointer rd 1
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
pci_access_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 hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache
cd_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) org (OS_BASE+0x0100000)
RAMDISK: rb 2880*512 ; Currently size of memory allocated for the ramdisk is fixed.
rb 2856*4 ; not used ; This should be revisited when/if memory map would become more dynamic.
RAMDISK_CAPACITY = 2880 ; in sectors
RAMDISK: rb RAMDISK_CAPACITY*512
_CLEAN_ZONE: _CLEAN_ZONE:
BgrAuxTable rb 32768
align 65536
SB16Buffer rb 65536
align 4096 align 4096
_IDE_DMA rb 16*512 _IDE_DMA rb 16*512
BgrAuxTable rb 32768
BUTTON_INFO rb 64*1024 BUTTON_INFO rb 64*1024
RESERVED_PORTS: rb 64*1024 RESERVED_PORTS: rb 64*1024
FLOPPY_BUFF: rb 18*512 ;one track
sys_pgmap: rb 1024*1024/8 sys_pgmap: rb 1024*1024/8

View File

@@ -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_initirq latin1 'Algväärtustan IRQ',0
boot_picinit latin1 'Algväärtustan PIC',0 boot_picinit latin1 'Algväärtustan PIC',0
boot_v86machine latin1 'Algväärtustan süsteemi V86 masinat',0 boot_v86machine latin1 'Algväärtustan süsteemi V86 masinat',0

View File

@@ -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_initirq: cp850 'Inicializar IRQ',0
boot_picinit: cp850 'Inicializar PIC',0 boot_picinit: cp850 'Inicializar PIC',0
boot_v86machine: cp850 'Inicializar sistema V86',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 boot_tasking: cp850 'Todo configurado - presiona ESC para iniciar',0
end if end if
msg_version: cp850 'versión incompatible del controlador',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 ;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 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

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
; Detect all BIOS hard drives. ; Detect all BIOS hard drives.
; diamond, 2008 ; diamond, 2008
; Do not include USB mass storages. CleverMouse, 2013 ; Do not include USB mass storages. CleverMouse, 2013

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
; Query physical memory map from BIOS. ; Query physical memory map from BIOS.
; diamond, 2009 ; diamond, 2009

View File

@@ -17,93 +17,192 @@ $Revision$
;**************************************************** ;****************************************************
;* ПОИСК HDD и CD * ;* ПОИСК HDD и CD *
;**************************************************** ;****************************************************
cmp [IDEContrProgrammingInterface], 0 cmp [ecx+IDE_DATA.ProgrammingInterface], 0
je EndFindHDD je EndFindHDD
FindHDD: 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 [ChannelNumber], 1
mov [DiskNumber], 0 mov [DiskNumber], 0
call FindHDD_3 call FindHDD_2
; mov ax,[Sector512+176]
; mov [DRIVE_DATA+6],ax
; mov ax,[Sector512+126]
; mov [DRIVE_DATA+8],ax
; mov ax,[Sector512+128]
; mov [DRIVE_DATA+8],ax
mov [DiskNumber], 1 mov [DiskNumber], 1
call FindHDD_3 call FindHDD_2
; mov al,[Sector512+176]
; mov [DRIVE_DATA+7],al
inc [ChannelNumber] inc [ChannelNumber]
mov [DiskNumber], 0 mov [DiskNumber], 0
call FindHDD_3 call FindHDD_2
; mov al,[Sector512+176]
; mov [DRIVE_DATA+8],al
mov [DiskNumber], 1 mov [DiskNumber], 1
call FindHDD_1 call FindHDD_1
; mov al,[Sector512+176]
; mov [DRIVE_DATA+9],al
pop ecx
jmp EndFindHDD jmp EndFindHDD
;-----------------------------------------------------------------------------
FindHDD_2:
call FindHDD_1
shl byte [ebx+DRIVE_DATA], 2
ret
;-----------------------------------------------------------------------------
FindHDD_1: FindHDD_1:
DEBUGF 1, "K : Channel %d ",[ChannelNumber]:2 DEBUGF 1, "K : Channel %d ",[ChannelNumber]:2
DEBUGF 1, "Disk %d\n",[DiskNumber]:1 DEBUGF 1, "Disk %d\n",[DiskNumber]:1
push ebx ecx
call ReadHDD_ID call ReadHDD_ID
pop ecx ebx
cmp [DevErrorCode], 7
je .end
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne FindHDD_2 jne .FindCD
cmp [Sector512+6], word 16 cmp [Sector512+6], word 16
ja FindHDD_2 ja .FindCD
cmp [Sector512+12], word 255 cmp [Sector512+12], word 255
ja FindHDD_2 ja .FindCD
inc byte [DRIVE_DATA+1]
jmp Print_Device_Name inc byte [ebx+DRIVE_DATA]
FindHDD_2: jmp .Print_Device_Name
;--------------------------------------
.FindCD:
push ebx ecx
call DeviceReset call DeviceReset
pop ecx ebx
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne FindHDD_2_2 jne .end
push ebx ecx
call ReadCD_ID call ReadCD_ID
pop ecx ebx
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne FindHDD_2_2 jne .end
inc byte [DRIVE_DATA+1]
inc byte [DRIVE_DATA+1] add [ebx+DRIVE_DATA], byte 2
Print_Device_Name: ;--------------------------------------
.Print_Device_Name:
pushad pushad
pushfd 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 esi, Sector512+27*2
mov edi, dev_name mov edi, dev_name
mov ecx, 20 mov ecx, 20
cld cld
;--------------------------------------
@@: @@:
lodsw lodsw
xchg ah, al xchg ah, al
stosw stosw
loop @b loop @b
popfd
popad
DEBUGF 1, "K : Dev: %s \n", dev_name DEBUGF 1, "K : Dev: %s \n", dev_name
xor eax, eax xor eax, eax
mov ax, [Sector512+64*2] 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] 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] mov ax, [Sector512+88*2]
DEBUGF 1, "K : Ultra DMA mode %x\n", eax DEBUGF 1, "K : Ultra DMA possible modes %x\n", al
FindHDD_2_2:
ret
FindHDD_3: mov [ebx+IDE_DEVICE.UDMA_possible_modes], al
call FindHDD_1
shl byte [DRIVE_DATA+1], 2
ret
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 ; Адрес считываемого сектора в режиме LBA
uglobal uglobal
SectorAddress DD ? SectorAddress dd ?
dev_name: dev_name:
rb 41 rb 41
endg endg
;-----------------------------------------------------------------------------
;************************************************* ;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * ;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА *
;* Входные параметры передаются через глобальные * ;* Входные параметры передаются через глобальные *
@@ -119,32 +218,32 @@ ReadHDD_ID:
; Послать команду идентификации устройства ; Послать команду идентификации устройства
mov [ATAFeatures], 0 mov [ATAFeatures], 0
mov [ATAHead], 0 mov [ATAHead], 0
mov [ATACommand], 0ECh mov [ATACommand], 0xEC
call SendCommandToHDD call SendCommandToHDD
cmp [DevErrorCode], 0;проверить код ошибки cmp [DevErrorCode], 0 ;проверить код ошибки
jne @@End ;закончить, сохранив код ошибки jne @@End ;закончить, сохранив код ошибки
mov DX, [ATABasePortAddr]
add DX, 7 ;адрес регистра состояни mov dx, [ATABasePortAddr]
add dx, 7 ;адрес регистра состояни
mov ecx, 0xffff mov ecx, 0xffff
@@WaitCompleet: @@WaitCompleet:
; Проверить время выполнения команды ; Проверить время выполнения команды
dec ecx dec ecx
; cmp ecx,0
jz @@Error1 ;ошибка тайм-аута jz @@Error1 ;ошибка тайм-аута
; Проверить готовность ; Проверить готовность
in AL, DX in al, dx
test AL, 80h ;состояние сигнала BSY test al, 80h ;состояние сигнала BSY
jnz @@WaitCompleet jnz @@WaitCompleet
test AL, 1 ;состояние сигнала ERR
test al, 1 ;состояние сигнала ERR
jnz @@Error6 jnz @@Error6
test AL, 08h ;состояние сигнала DRQ
test al, 08h ;состояние сигнала DRQ
jz @@WaitCompleet jz @@WaitCompleet
; Принять блок данных от контроллера ; Принять блок данных от контроллера
; mov AX,DS mov edi, Sector512
; mov ES,AX mov dx, [ATABasePortAddr];регистр данных
mov EDI, Sector512 ;offset Sector512 mov cx, 256 ;число считываемых слов
mov DX, [ATABasePortAddr];регистр данных
mov CX, 256 ;число считываемых слов
rep insw ;принять блок данных rep insw ;принять блок данных
ret ret
; Записать код ошибки ; Записать код ошибки
@@ -155,34 +254,32 @@ ReadHDD_ID:
mov [DevErrorCode], 6 mov [DevErrorCode], 6
@@End: @@End:
ret ret
;-----------------------------------------------------------------------------
iglobal
; Стандартные базовые адреса каналов 1 и 2
StandardATABases DW 1F0h, 170h
endg
uglobal uglobal
; Стандартные базовые адреса каналов 1 и 2
StandardATABases dw ?, ? ; 1F0h, 170h
; Номер канала ; Номер канала
ChannelNumber DW ? ChannelNumber dw ?
; Номер диска ; Номер диска
DiskNumber DB ? DiskNumber db ?
; Базовый адрес группы портов контроллера ATA ; Базовый адрес группы портов контроллера ATA
ATABasePortAddr DW ? ATABasePortAddr dw ?
; Параметры ATA-команды ; Параметры ATA-команды
ATAFeatures DB ? ;особенности ATAFeatures db ? ;особенности
ATASectorCount DB ? ;количество обрабатываемых секторов ATASectorCount db ? ;количество обрабатываемых секторов
ATASectorNumber DB ? ;номер начального сектора ATASectorNumber db ? ;номер начального сектора
ATACylinder DW ? ;номер начального цилиндра ATACylinder dw ? ;номер начального цилиндра
ATAHead DB ? ;номер начальной головки ATAHead db ? ;номер начальной головки
ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA) ATAAddressMode db ? ;режим адресации (0 - CHS, 1 - LBA)
ATACommand DB ? ;код команды, подлежащей выполнению ATACommand db ? ;код команды, подлежащей выполнению
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый ; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
; интервал ожидания, 2 - неверный код режима адресации, ; интервал ожидания, 2 - неверный код режима адресации,
; 3 - неверный номер канала, 4 - неверный номер диска, ; 3 - неверный номер канала, 4 - неверный номер диска,
; 5 - неверный номер головки, 6 - ошибка при выполнении ; 5 - неверный номер головки, 6 - ошибка при выполнении
; команды) ; команды, 7 - таймаут при выборе канала)
DevErrorCode dd ? DevErrorCode dd ?
endg endg
;-----------------------------------------------------------------------------
;**************************************************** ;****************************************************
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * ;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
;* Входные параметры передаются через глобальные * ;* Входные параметры передаются через глобальные *
@@ -207,89 +304,85 @@ SendCommandToHDD:
cmp [ATAAddressMode], 1 cmp [ATAAddressMode], 1
ja @@Err2 ja @@Err2
; Проверить корректность номера канала ; Проверить корректность номера канала
mov BX, [ChannelNumber] mov bx, [ChannelNumber]
cmp BX, 1 cmp bx, 1
jb @@Err3 jb @@Err3
cmp BX, 2
cmp bx, 2
ja @@Err3 ja @@Err3
; Установить базовый адрес ; Установить базовый адрес
dec BX dec bx
shl BX, 1 shl bx, 1
movzx ebx, bx movzx ebx, bx
mov AX, [ebx+StandardATABases] mov ax, [ebx+StandardATABases]
mov [ATABasePortAddr], AX mov [ATABasePortAddr], ax
; Ожидание готовности HDD к приему команды ; Ожидание готовности HDD к приему команды
; Выбрать нужный диск ; Выбрать нужный диск
mov DX, [ATABasePortAddr] mov dx, [ATABasePortAddr]
add DX, 6 ;адрес регистра головок add dx, 6 ;адрес регистра головок
mov AL, [DiskNumber] mov al, [DiskNumber]
cmp AL, 1 ;проверить номера диска cmp al, 1 ;проверить номера диска
ja @@Err4 ja @@Err4
shl AL, 4
or AL, 10100000b shl al, 4
out DX, AL or al, 10100000b
out dx, al
; Ожидать, пока диск не будет готов ; Ожидать, пока диск не будет готов
inc DX inc dx
mov ecx, 0xfff mov ecx, 0xfff
; mov eax,[timer_ticks]
; mov [TickCounter_1],eax
@@WaitHDReady: @@WaitHDReady:
; Проверить время ожидани ; Проверить время ожидани
dec ecx dec ecx
; cmp ecx,0
jz @@Err1 jz @@Err1
; mov eax,[timer_ticks]
; sub eax,[TickCounter_1]
; cmp eax,300 ;ожидать 300 тиков
; ja @@Err1 ;ошибка тайм-аута
; Прочитать регистр состояни ; Прочитать регистр состояни
in AL, DX in al, dx
; Проверить состояние сигнала BSY ; Проверить состояние сигнала BSY
test AL, 80h test al, 80h
jnz @@WaitHDReady jnz @@WaitHDReady
; Проверить состояние сигнала DRQ ; Проверить состояние сигнала DRQ
test AL, 08h test al, 08h
jnz @@WaitHDReady jnz @@WaitHDReady
; Загрузить команду в регистры контроллера ; Загрузить команду в регистры контроллера
cli cli
mov DX, [ATABasePortAddr] mov dx, [ATABasePortAddr]
inc DX ;регистр "особенностей" inc dx ;регистр "особенностей"
mov AL, [ATAFeatures] mov al, [ATAFeatures]
out DX, AL out dx, AL
inc DX ;счетчик секторов inc dx ;счетчик секторов
mov AL, [ATASectorCount] mov al, [ATASectorCount]
out DX, AL out dx, AL
inc DX ;регистр номера сектора inc dx ;регистр номера сектора
mov AL, [ATASectorNumber] mov al, [ATASectorNumber]
out DX, AL out dx, AL
inc DX ;номер цилиндра (младший байт) inc dx ;номер цилиндра (младший байт)
mov AX, [ATACylinder] mov ax, [ATACylinder]
out DX, AL out dx, AL
inc DX ;номер цилиндра (старший байт) inc dx ;номер цилиндра (старший байт)
mov AL, AH mov al, AH
out DX, AL out dx, AL
inc DX ;номер головки/номер диска inc dx ;номер головки/номер диска
mov AL, [DiskNumber] mov al, [DiskNumber]
shl AL, 4 shl al, 4
cmp [ATAHead], 0Fh;проверить номер головки cmp [ATAHead], 0xF ;проверить номер головки
ja @@Err5 ja @@Err5
or AL, [ATAHead]
or AL, 10100000b or al, [ATAHead]
mov AH, [ATAAddressMode] or al, 10100000b
shl AH, 6 mov ah, [ATAAddressMode]
or AL, AH shl ah, 6
out DX, AL or al, ah
out dx, al
; Послать команду ; Послать команду
mov AL, [ATACommand] mov al, [ATACommand]
inc DX ;регистр команд inc dx ;регистр команд
out DX, AL out dx, al
sti sti
; Сбросить признак ошибки ; Сбросить признак ошибки
mov [DevErrorCode], 0 mov [DevErrorCode], 0
ret ret
; Записать код ошибки ; Записать код ошибки
@@Err1: @@Err1:
mov [DevErrorCode], 1 mov [DevErrorCode], 7
ret ret
@@Err2: @@Err2:
mov [DevErrorCode], 2 mov [DevErrorCode], 2
@@ -304,7 +397,7 @@ SendCommandToHDD:
mov [DevErrorCode], 5 mov [DevErrorCode], 5
; Завершение работы программы ; Завершение работы программы
ret ret
;-----------------------------------------------------------------------------
;************************************************* ;*************************************************
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI * ;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI *
;* Входные параметры передаются через глобальные * ;* Входные параметры передаются через глобальные *
@@ -323,33 +416,32 @@ ReadCD_ID:
mov [ATASectorNumber], 0 mov [ATASectorNumber], 0
mov [ATACylinder], 0 mov [ATACylinder], 0
mov [ATAHead], 0 mov [ATAHead], 0
mov [ATACommand], 0A1h mov [ATACommand], 0xA1
call SendCommandToHDD call SendCommandToHDD
cmp [DevErrorCode], 0;проверить код ошибки cmp [DevErrorCode], 0;проверить код ошибки
jne @@End_1 ;закончить, сохранив код ошибки jne @@End_1 ;закончить, сохранив код ошибки
; Ожидать готовность данных HDD ; Ожидать готовность данных HDD
mov DX, [ATABasePortAddr] mov dx, [ATABasePortAddr]
add DX, 7 ;порт 1х7h add dx, 7 ;порт 1х7h
mov ecx, 0xffff mov ecx, 0xffff
@@WaitCompleet_1: @@WaitCompleet_1:
; Проверить врем ; Проверить врем
dec ecx dec ecx
; cmp ecx,0
jz @@Error1_1 ;ошибка тайм-аута jz @@Error1_1 ;ошибка тайм-аута
; Проверить готовность ; Проверить готовность
in AL, DX in al, dx
test AL, 80h ;состояние сигнала BSY test al, 80h ;состояние сигнала BSY
jnz @@WaitCompleet_1 jnz @@WaitCompleet_1
test AL, 1 ;состояние сигнала ERR
test al, 1 ;состояние сигнала ERR
jnz @@Error6_1 jnz @@Error6_1
test AL, 08h ;состояние сигнала DRQ
test al, 08h ;состояние сигнала DRQ
jz @@WaitCompleet_1 jz @@WaitCompleet_1
; Принять блок данных от контроллера ; Принять блок данных от контроллера
; mov AX,DS mov edi, Sector512 ;offset Sector512
; mov ES,AX mov dx, [ATABasePortAddr];порт 1x0h
mov EDI, Sector512 ;offset Sector512 mov cx, 256;число считываемых слов
mov DX, [ATABasePortAddr];порт 1x0h
mov CX, 256;число считываемых слов
rep insw rep insw
ret ret
; Записать код ошибки ; Записать код ошибки
@@ -360,7 +452,7 @@ ReadCD_ID:
mov [DevErrorCode], 6 mov [DevErrorCode], 6
@@End_1: @@End_1:
ret ret
;-----------------------------------------------------------------------------
;************************************************* ;*************************************************
;* СБРОС УСТРОЙСТВА * ;* СБРОС УСТРОЙСТВА *
;* Входные параметры передаются через глобальные * ;* Входные параметры передаются через глобальные *
@@ -370,39 +462,40 @@ ReadCD_ID:
;************************************************* ;*************************************************
DeviceReset: DeviceReset:
; Проверить корректность номера канала ; Проверить корректность номера канала
mov BX, [ChannelNumber] mov bx, [ChannelNumber]
cmp BX, 1 cmp bx, 1
jb @@Err3_2 jb @@Err3_2
cmp BX, 2
cmp bx, 2
ja @@Err3_2 ja @@Err3_2
; Установить базовый адрес ; Установить базовый адрес
dec BX dec bx
shl BX, 1 shl bx, 1
movzx ebx, bx movzx ebx, bx
mov DX, [ebx+StandardATABases] mov dx, [ebx+StandardATABases]
mov [ATABasePortAddr], DX mov [ATABasePortAddr], dx
; Выбрать нужный диск ; Выбрать нужный диск
add DX, 6 ;адрес регистра головок add dx, 6 ;адрес регистра головок
mov AL, [DiskNumber] mov al, [DiskNumber]
cmp AL, 1 ;проверить номера диска cmp al, 1 ;проверить номера диска
ja @@Err4_2 ja @@Err4_2
shl AL, 4
or AL, 10100000b shl al, 4
out DX, AL or al, 10100000b
out dx, al
; Послать команду "Сброс" ; Послать команду "Сброс"
mov AL, 08h mov al, 0x8
inc DX ;регистр команд inc dx ;регистр команд
out DX, AL out dx, al
mov ecx, 0x80000 mov ecx, 0x80000
@@WaitHDReady_1: @@WaitHDReady_1:
; Проверить время ожидани ; Проверить время ожидани
dec ecx dec ecx
; cmp ecx,0
je @@Err1_2 ;ошибка тайм-аута je @@Err1_2 ;ошибка тайм-аута
; Прочитать регистр состояни ; Прочитать регистр состояни
in AL, DX in al, dx
; Проверить состояние сигнала BSY ; Проверить состояние сигнала BSY
test AL, 80h test al, 80h
jnz @@WaitHDReady_1 jnz @@WaitHDReady_1
; Сбросить признак ошибки ; Сбросить признак ошибки
mov [DevErrorCode], 0 mov [DevErrorCode], 0
@@ -418,6 +511,5 @@ DeviceReset:
mov [DevErrorCode], 4 mov [DevErrorCode], 4
; Записать код ошибки ; Записать код ошибки
ret ret
;-----------------------------------------------------------------------------
EndFindHDD: EndFindHDD:

View File

@@ -7,6 +7,7 @@
$Revision$ $Revision$
;-----------------------------------------------------------------------------
pusha pusha
mov eax, [pg_data.pages_free] 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 ; check a upper size of the cache, no more than 1 Mb on the physical device
cmp eax, 1024*1024 cmp eax, 1024*1024
jbe @f jbe @f
mov eax, 1024*1024 mov eax, 1024*1024
jmp .continue jmp .continue
;--------------------------------------
@@: @@:
; check a lower size of the cache, not less than 128 Kb on the physical device ; check a lower size of the cache, not less than 128 Kb on the physical device
cmp eax, 128*1024 cmp eax, 128*1024
jae @f jae .continue
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
test byte [DRIVE_DATA+1], 2 mov eax, 128*1024
je .ide2 ;--------------------------------------
mov esi, cache_ide3 .continue:
call get_cache_ide push ecx
.ide2: mov ecx, 12
test byte [DRIVE_DATA+1], 8 mov esi, cache_ide0+IDE_CACHE.size
je .ide1 cld
mov esi, cache_ide2 @@:
call get_cache_ide mov [esi], eax
.ide1: add esi, sizeof.IDE_CACHE
test byte [DRIVE_DATA+1], 0x20 loop @b
je .ide0
mov esi, cache_ide1 pop ecx
call get_cache_ide
.ide0: xor eax, eax
mov [hdd_appl_data], 1 ;al
mov [cd_appl_data], 1
;--------------------------------------
test byte [DRIVE_DATA+1], 0x80 test byte [DRIVE_DATA+1], 0x80
je @f je @f
mov esi, cache_ide0 mov esi, cache_ide0
call get_cache_ide 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: get_cache_ide:
and [esi+cache_ide0_search_start-cache_ide0], 0 and [esi+IDE_CACHE.search_start], 0
and [esi+cache_ide0_appl_search_start-cache_ide0], 0 and [esi+IDE_CACHE.appl_search_start], 0
push ecx push ecx
stdcall kernel_alloc, [esi+cache_ide0_size-cache_ide0] ; DEBUGF 1, "K : IDE_CACHE.size %x\n", [esi+IDE_CACHE.size]
mov [esi+cache_ide0_pointer-cache_ide0], eax stdcall kernel_alloc, [esi+IDE_CACHE.size]
mov [esi+IDE_CACHE.pointer], eax
pop ecx pop ecx
mov edx, eax mov edx, eax
mov eax, [esi+cache_ide0_size-cache_ide0] mov eax, [esi+IDE_CACHE.size]
shr eax, 3 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 mov ebx, eax
imul eax, 7 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 add ebx, edx
mov [esi+cache_ide0_data_pointer-cache_ide0], ebx mov [esi+IDE_CACHE.data_pointer], ebx
.cd: .cd:
push ecx push ecx
mov eax, [esi+cache_ide0_system_data_size-cache_ide0] mov eax, [esi+IDE_CACHE.system_data_size]
call calculate_for_cd call calculate_for_cd
add eax, [esi+cache_ide0_pointer-cache_ide0] add eax, [esi+IDE_CACHE.pointer]
mov [esi+cache_ide0_system_data-cache_ide0], eax mov [esi+IDE_CACHE.system_data], eax
mov [esi+cache_ide0_system_sad_size-cache_ide0], ecx mov [esi+IDE_CACHE.system_sad_size], ecx
push edi push edi
mov edi, [esi+cache_ide0_pointer-cache_ide0] mov edi, [esi+IDE_CACHE.pointer]
call clear_ide_cache call clear_ide_cache
pop edi pop edi
mov eax, [esi+cache_ide0_appl_data_size-cache_ide0] mov eax, [esi+IDE_CACHE.appl_data_size]
call calculate_for_cd call calculate_for_cd
add eax, [esi+cache_ide0_data_pointer-cache_ide0] add eax, [esi+IDE_CACHE.data_pointer]
mov [esi+cache_ide0_appl_data-cache_ide0], eax mov [esi+IDE_CACHE.appl_data], eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0], ecx mov [esi+IDE_CACHE.appl_sad_size], ecx
push edi push edi
mov edi, [esi+cache_ide0_data_pointer-cache_ide0] mov edi, [esi+IDE_CACHE.data_pointer]
call clear_ide_cache call clear_ide_cache
pop edi pop edi
pop ecx pop ecx
ret ret
;-----------------------------------------------------------------------------
calculate_for_cd: calculate_for_cd:
push eax push eax
mov ebx, eax mov ebx, eax
@@ -116,7 +195,7 @@ calculate_for_cd:
sub eax, ebx sub eax, ebx
dec ecx dec ecx
ret ret
;-----------------------------------------------------------------------------
clear_ide_cache: clear_ide_cache:
push eax push eax
shl ecx, 1 shl ecx, 1
@@ -125,6 +204,6 @@ clear_ide_cache:
rep stosd rep stosd
pop eax pop eax
ret ret
;-----------------------------------------------------------------------------
end_get_cache: end_get_cache:
popa popa

View File

@@ -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
;-----------------------------------------------------------------------------

View File

@@ -8,63 +8,203 @@
$Revision$ $Revision$
search_partitions: search_partitions:
push ecx
; 1. Fill missing parameters in HD_DATA structures. ; 1. Fill missing parameters in HD_DATA structures.
mov eax, [hd_address_table] xor eax, eax
mov [hd0_data.hdbase], eax ;0x1f0 mov edx, IDE_controller_1
mov ax, [edx + IDE_DATA.BAR0_val]
mov [hd0_data.hdbase], eax
mov [hd1_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 [hd2_data.hdbase], eax
mov [hd3_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. ; 2. Notify the system about /hd* disks.
; For every existing disk, call ide_disk_add with correct parameters. ; For every existing disk, call ide_disk_add with correct parameters.
; Generate name "hdN" on the stack; this is 4 bytes including terminating zero. ; 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, ; 2a. /hd0: exists if mask 0x40 in [DRIVE_DATA+1] is set,
; data: hd0_data, ; data: hd0_data,
; number of partitions: [DRIVE_DATA+2] ; number of partitions: [DRIVE_DATA+2]
test [DRIVE_DATA+1], byte 0x40 test [DRIVE_DATA+1], byte 0x40
jz @f jz @f
push 'hd0' push 'hd0'
mov eax, esp ; name mov eax, esp ; name
mov edx, hd0_data mov edx, hd0_data
call ide_disk_add call ide_disk_add
mov [DRIVE_DATA+2], al mov [DRIVE_DATA+2], al
pop ecx ; restore the stack pop ecx ; restore the stack
;-----------------------------------------------------------------------------
@@: @@:
; 2b. /hd1: exists if mask 0x10 in [DRIVE_DATA+1] is set, ; 2b. /hd1: exists if mask 0x10 in [DRIVE_DATA+1] is set,
; data: hd1_data, ; data: hd1_data,
; number of partitions: [DRIVE_DATA+3] ; number of partitions: [DRIVE_DATA+3]
test [DRIVE_DATA+1], byte 0x10 test [DRIVE_DATA+1], byte 0x10
jz @f jz @f
push 'hd1' push 'hd1'
mov eax, esp mov eax, esp
mov edx, hd1_data mov edx, hd1_data
call ide_disk_add call ide_disk_add
mov [DRIVE_DATA+3], al mov [DRIVE_DATA+3], al
pop ecx pop ecx
;-----------------------------------------------------------------------------
@@: @@:
; 2c. /hd2: exists if mask 4 in [DRIVE_DATA+1] is set, ; 2c. /hd2: exists if mask 4 in [DRIVE_DATA+1] is set,
; data: hd2_data, ; data: hd2_data,
; number of partitions: [DRIVE_DATA+4] ; number of partitions: [DRIVE_DATA+4]
test [DRIVE_DATA+1], byte 4 test [DRIVE_DATA+1], byte 4
jz @f jz @f
push 'hd2' push 'hd2'
mov eax, esp mov eax, esp
mov edx, hd2_data mov edx, hd2_data
call ide_disk_add call ide_disk_add
mov [DRIVE_DATA+4], al mov [DRIVE_DATA+4], al
pop ecx pop ecx
;-----------------------------------------------------------------------------
@@: @@:
; 2d. /hd3: exists if mask 1 in [DRIVE_DATA+1] is set, ; 2d. /hd3: exists if mask 1 in [DRIVE_DATA+1] is set,
; data: hd3_data, ; data: hd3_data,
; number of partitions: [DRIVE_DATA+5] ; number of partitions: [DRIVE_DATA+5]
test [DRIVE_DATA+1], byte 1 test [DRIVE_DATA+1], byte 1
jz @f jz @f
push 'hd3' push 'hd3'
mov eax, esp mov eax, esp
mov edx, hd3_data mov edx, hd3_data
call ide_disk_add call ide_disk_add
mov [DRIVE_DATA+5], al mov [DRIVE_DATA+5], al
pop ecx 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. ; 3. Notify the system about /bd* disks.
; 3a. Check whether there are BIOS disks. If no, skip step 3. ; 3a. Check whether there are BIOS disks. If no, skip step 3.
@@ -115,10 +255,10 @@ endg
pop ecx ecx ; restore stack after name pop ecx ecx ; restore stack after name
.nobd: .nobd:
jmp end_search_partitions jmp end_search_partitions
;-----------------------------------------------------------------------------
; Helper procedure for search_partitions, adds one IDE disk. ; Helper procedure for search_partitions, adds one IDE disk.
; For compatibility, number of partitions for IDE disks is kept in a separate variable, ; For compatibility, number of partitions for IDE disks is kept in a separate
; so the procedure returns number of partitions. ; variable, so the procedure returns number of partitions.
; eax -> name, edx -> disk data ; eax -> name, edx -> disk data
proc ide_disk_add proc ide_disk_add
stdcall disk_add, ide_callbacks, eax, edx, 0 stdcall disk_add, ide_callbacks, eax, edx, 0
@@ -134,6 +274,6 @@ proc ide_disk_add
@@: @@:
ret ret
endp endp
;-----------------------------------------------------------------------------
end_search_partitions: end_search_partitions:
pop ecx

View File

@@ -86,9 +86,9 @@
* рисуется внешняя рамка цвета, указанного в edi, * рисуется внешняя рамка цвета, указанного в edi,
шириной 1 пиксель шириной 1 пиксель
* рисуется заголовок - прямоугольник с левым верхним углом (1,1) * рисуется заголовок - прямоугольник с левым верхним углом (1,1)
и правым нижним (xsize-1,min(25,ysize)) цвета, указанного в esi и правым нижним (xsize-1,min(20,ysize-1)) цвета, указанного в esi
(с учетом градиента) (с учетом градиента)
* если ysize>=26, то закрашивается рабочая область окна - * если ysize>21, то закрашивается рабочая область окна -
прямоугольник с левым верхним углом (1,21) и правым нижним прямоугольник с левым верхним углом (1,21) и правым нижним
(xsize-1,ysize-1) (размерами (xsize-1)*(ysize-21)) - цветом, (xsize-1,ysize-1) (размерами (xsize-1)*(ysize-21)) - цветом,
указанным в edx (с учетом градиента) указанным в edx (с учетом градиента)
@@ -151,7 +151,9 @@
Возвращаемое значение: Возвращаемое значение:
* если буфер пуст, возвращается eax=1 * если буфер пуст, возвращается eax=1
* если буфер непуст, то возвращается al=0, ah=код нажатой клавиши, * если буфер непуст, то возвращается al=0, ah=код нажатой клавиши,
старшее слово регистра eax обнулено биты 16-23 содержат сканкод нажатой клавиши в режиме ASCII,
в режме сканкодов биты обнулены.
биты 23-31 обнулены
* если есть "горячая клавиша", то возвращается * если есть "горячая клавиша", то возвращается
al=2, ah=сканкод нажатой клавиши (0 для управляющих клавиш), al=2, ah=сканкод нажатой клавиши (0 для управляющих клавиш),
старшее слово регистра eax содержит состояние управляющих клавиш старшее слово регистра eax содержит состояние управляющих клавиш
@@ -816,9 +818,9 @@
вызове, оно может измениться в последующих версиях ядра. вызове, оно может измениться в последующих версиях ядра.
====================================================================== ======================================================================
======== Функция 18, подфункция 10 - свернуть окно приложения. ======= ========= Функция 18, подфункция 10 - свернуть активное окно. ========
====================================================================== ======================================================================
Сворачивает собственное окно. Сворачивает активное окно.
Параметры: Параметры:
* eax = 18 - номер функции * eax = 18 - номер функции
* ebx = 10 - номер подфункции * ebx = 10 - номер подфункции
@@ -843,8 +845,7 @@
* eax = 18 - номер функции * eax = 18 - номер функции
* ebx = 11 - номер подфункции * ebx = 11 - номер подфункции
* ecx = тип таблицы: * ecx = тип таблицы:
* 1 = короткая версия, 10 байт * 1 = короткая версия, 16 байт
* 2 = полная версия, 65536 байт
* edx = указатель на буфер (в приложении) для таблицы * edx = указатель на буфер (в приложении) для таблицы
Возвращаемое значение: Возвращаемое значение:
* функция не возвращает значения * функция не возвращает значения
@@ -861,6 +862,8 @@
Например, для стандартной конфигурации из одного 1.44-дисковода Например, для стандартной конфигурации из одного 1.44-дисковода
здесь будет 40h, а для случая 1.2Mb на A: и 1.44Mb на B: здесь будет 40h, а для случая 1.2Mb на A: и 1.44Mb на B:
значение оказывается 24h. значение оказывается 24h.
Первый контроллер IDE:
* +1: byte: информация о жёстких дисках и CD-приводах, AABBCCDD, * +1: byte: информация о жёстких дисках и CD-приводах, AABBCCDD,
где AA соответствует контроллеру IDE0, ..., DD - IDE3: где AA соответствует контроллеру IDE0, ..., DD - IDE3:
* 0 = устройство отсутствует * 0 = устройство отсутствует
@@ -869,31 +872,36 @@
Например, в случае HD на IDE0 и CD на IDE2 здесь будет 48h. Например, в случае HD на IDE0 и CD на IDE2 здесь будет 48h.
* +2: 4 db: число найденных разделов на жёстких дисках с * +2: 4 db: число найденных разделов на жёстких дисках с
соответственно IDE0,...,IDE3. соответственно 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 соответствующий байт При отсутствии жёсткого диска на IDEx соответствующий байт
нулевой, при наличии показывает число распознанных разделов, нулевой, при наличии показывает число распознанных разделов,
которых может и не быть (если носитель не отформатирован или которых может и не быть (если носитель не отформатирован или
если файловая система не поддерживается). В текущей версии ядра если файловая система не поддерживается). В текущей версии ядра
для жёстких дисков поддерживаются только FAT16, FAT32 и NTFS. для жёстких дисков поддерживаются только FAT12/16/32, NTFS,
* +6: 4 db: зарезервировано ext2/3/4 и XFS.
Формат таблицы: полная версия:
* +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
* формат дальнейших данных зависит от файловой системы,
может меняться с изменениями в ядре и поэтому не описывается
Замечания: Замечания:
* Короткая таблица может быть использована для получения информации * Таблица может быть использована для получения информации
об имеющихся устройствах. об имеющихся устройствах.
====================================================================== ======================================================================
@@ -1208,20 +1216,6 @@ dd 1675
соответствующую текущей стране иконку. соответствующую текущей стране иконку.
* Приложение @panel переключает раскладки по запросу пользователя. * Приложение @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 - установить язык системы. ======== ========= Функция 21, подфункция 5 - установить язык системы. ========
====================================================================== ======================================================================
@@ -1239,52 +1233,6 @@ dd 1675
переменную не использует. переменную не использует.
* Получить язык системы можно вызовом подфункции 5 функции 26. * Получить язык системы можно вызовом подфункции 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 ===================== ====================== Функция 21, подфункция 11 =====================
=========== Разрешить/запретить низкоуровневый доступ к HD. ========== =========== Разрешить/запретить низкоуровневый доступ к HD. ==========
@@ -1315,122 +1263,6 @@ dd 1675
* Текущая реализация использует только младший бит ecx. * Текущая реализация использует только младший бит ecx.
* Получить текущее состояние можно вызовом подфункции 12 функции 26. * Получить текущее состояние можно вызовом подфункции 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 - установить системную дату/время. =========== ============ Функция 22 - установить системную дату/время. ===========
====================================================================== ======================================================================
@@ -1493,59 +1325,6 @@ dd 1675
с eax=0, если сложение ebx с текущим значением счётчика времени с eax=0, если сложение ebx с текущим значением счётчика времени
вызовет 32-битное переполнение. вызовет 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 - извлечь лоток привода диска. ====== ======= Функция 24, подфункция 4 - извлечь лоток привода диска. ======
====================================================================== ======================================================================
@@ -1553,7 +1332,9 @@ dd 1675
* eax = 24 - номер функции * eax = 24 - номер функции
* ebx = 4 - номер подфункции * ebx = 4 - номер подфункции
* ecx = номер CD/DVD-диска * 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 - номер функции * eax = 24 - номер функции
* ebx = 5 - номер подфункции * ebx = 5 - номер подфункции
* ecx = номер CD/DVD-диска * 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 переключает раскладки по запросу пользователя. * Приложение @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 - получить язык системы. ========= ========== Функция 26, подфункция 5 - получить язык системы. =========
====================================================================== ======================================================================
@@ -1674,42 +1445,6 @@ dd 1675
соответствующую иконку (используя описываемую функцию). соответствующую иконку (используя описываемую функцию).
* Установить язык системы можно вызовом подфункции 5 функции 21. * Установить язык системы можно вызовом подфункции 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 - получить значение счётчика времени. === === Функция 26, подфункция 9 - получить значение счётчика времени. ===
====================================================================== ======================================================================
@@ -2543,221 +2278,6 @@ dword-значение цвета 0x00RRGGBB
* Если BIOS не поддерживает это расширение, поведение функции * Если BIOS не поддерживает это расширение, поведение функции
эмулируется (через аналоги подфункций функции 62 режима ядра). эмулируется (через аналоги подфункций функции 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). ========== =========== Функция 60 - Inter Process Communication (IPC). ==========
====================================================================== ======================================================================
@@ -4544,12 +4064,6 @@ Architecture Software Developer's Manual, Volume 3, Appendix B);
Возвращаемое значение: Возвращаемое значение:
* eax = socketnum1, -1 для ошибки * eax = socketnum1, -1 для ошибки
* ebx = socketnum2, код ошибки в случае ошибки * ebx = socketnum2, код ошибки в случае ошибки
Замечания:
Optstruct: dd level
dd optionname
dd optlength
db options...
====================================================================== ======================================================================
========== Функция -1 - завершить выполнение потока/процесса ========= ========== Функция -1 - завершить выполнение потока/процесса =========

View File

@@ -82,9 +82,9 @@ Remarks:
* The window of type I looks as follows: * The window of type I looks as follows:
* draw external frame of color indicated in edi, 1 pixel in width * draw external frame of color indicated in edi, 1 pixel in width
* draw header - rectangle with the left upper corner (1,1) and * 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) (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 rectangle with the left upper corner (1,21) and right lower
(xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color (xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color
indicated in edx (taking a gradient into account) indicated in edx (taking a gradient into account)
@@ -148,7 +148,10 @@ Parameters:
Returned value: Returned value:
* if the buffer is empty, function returns eax=1 * if the buffer is empty, function returns eax=1
* if the buffer is not empty, function returns al=0, * 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, * if there is "hotkey", function returns al=2,
ah=scancode of the pressed key (0 for control keys), ah=scancode of the pressed key (0 for control keys),
high word of eax contains a status of control keys at the moment 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. 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: Parameters:
* eax = 18 - function number * eax = 18 - function number
* ebx = 10 - subfunction number * ebx = 10 - subfunction number
@@ -828,8 +831,8 @@ Remarks:
keeps position and sizes. keeps position and sizes.
* Restoring of an application window occurs at its activation by * Restoring of an application window occurs at its activation by
subfunction 3. subfunction 3.
* Usually there is no necessity to minimize/restire a window * Usually there is no necessity to minimize/restore a window
obviously: minimization of a window is carried out by the system explicitly: minimization of a window is carried out by the system
at pressing the minimization button (for skinned windows at pressing the minimization button (for skinned windows
it is defined automatically by function 0, it is defined automatically by function 0,
for other windows it can be defined manually by function 8), for other windows it can be defined manually by function 8),
@@ -842,8 +845,7 @@ Parameters:
* eax = 18 - function number * eax = 18 - function number
* ebx = 11 - subfunction number * ebx = 11 - subfunction number
* ecx = type of the table: * ecx = type of the table:
* 1 = short version, 10 bytes * 1 = short version, 16 bytes
* 2 = full version, 65536 bytes
* edx = pointer to the buffer (in the application) for the table * edx = pointer to the buffer (in the application) for the table
Returned value: Returned value:
* function does not return value * function does not return value
@@ -860,41 +862,48 @@ Format of the table: short version:
For example, for the standard configuration from one 1.44-drive 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: 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, * +1: byte: information about hard disks and CD-drives, AABBCCDD,
where AA corresponds to the controller IDE0, ..., DD - IDE3: where AA corresponds to the controller IDE0, ..., DD - IDE3:
* 0 = device is absent * 0 = device not found
* 1 = hard drive * 1 = hard drive
* 2 = CD-drive * 2 = CD-drive
For example, in the case HD on IDE0 and CD on IDE2 For example, in the case HD on IDE0 and CD on IDE2
this field contains 48h. this field contains 48h.
* +2: 4 db: number of the retrieved partitions on hard disks * +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, If the hard disk on IDEx is absent, appropriate byte is zero,
otherwise it shows number of the recognized partitions, which otherwise it shows number of the recognized partitions, which
can be not presented (if the drive is not formatted or if can be not presented (if the drive is not formatted or if
the file system is not supported). Current version of the kernel the file system is not supported). Current version of the kernel
supports only FAT16, FAT32 and NTFS for hard disks. supports only FAT12/16/32, NTFS, ext2/3/4 and XFS for hard disks.
* +6: 4 db: reserved
Format of the table: full version:
* +0: 10 db: same as for the short version
* +10: 100 db: data for the first partition
* +110: 100 db: data for the second partition
* ...
* +10+100*(n-1): 100 db: data for the last partition
The partitions are located as follows: at first sequentially all
recoginzed partitions on HD on IDE0 (if present),
then on HD on IDE1 (if present) and so on up to IDE3.
Format of the information about partition
(at moment only FAT is supported):
* +0: dword: first physical sector of the partition
* +4: dword: last physical sector of the partition
(belongs to the partition)
* +8: byte: file system type:
16=FAT16, 32=FAT32, 1=NTFS
* other data are dependent on file system, are modified with
kernel modifications and therefore are not described
Remarks: Remarks:
* The short table can be used for obtaining the information about * The table can be used for obtaining the information about
available devices. available devices.
====================================================================== ======================================================================
@@ -1208,19 +1217,6 @@ Remarks:
the corresponding icon. the corresponding icon.
* The application @panel switches layouts on user request. * 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. ========= ========== Function 21, subfunction 5 - set system language. =========
====================================================================== ======================================================================
@@ -1238,49 +1234,6 @@ Remarks:
use this variable. use this variable.
* To get system language use subfunction 5 of function 26. * 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. 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. * The current implementation uses only low bit of ecx.
* To get current status use subfunction 12 of function 26. * 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. ================ ================= Function 22 - set system date/time. ================
====================================================================== ======================================================================
@@ -1484,58 +1323,6 @@ Remarks:
if the addition of ebx with the current value of time counter if the addition of ebx with the current value of time counter
makes 32-bit overflow. 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. ======= ======= Function 24, subfunction 4 - eject tray of disk drive. =======
====================================================================== ======================================================================
@@ -1543,7 +1330,9 @@ Parameters:
* eax = 24 - function number * eax = 24 - function number
* ebx = 4 - subfunction number * ebx = 4 - subfunction number
* ecx = position of CD/DVD-drive * 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: Returned value:
* function does not return value * function does not return value
Remarks: Remarks:
@@ -1561,7 +1350,9 @@ Parameters:
* eax = 24 - function number * eax = 24 - function number
* ebx = 5 - subfunction number * ebx = 5 - subfunction number
* ecx = position of CD/DVD-drive * 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: Returned value:
* function does not return value * function does not return value
Remarks: Remarks:
@@ -1635,18 +1426,6 @@ Remarks:
the corresponding icon (using this function). the corresponding icon (using this function).
* The application @panel switches layouts on user request. * 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. ========= ========== Function 26, subfunction 5 - get system language. =========
====================================================================== ======================================================================
@@ -1661,41 +1440,6 @@ Remarks:
appropriate icon (using this function). appropriate icon (using this function).
* To set system language use subfunction 5 of function 21. * 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. == === Function 26, subfunction 9 - get the value of the time counter. ==
====================================================================== ======================================================================
@@ -2315,8 +2059,7 @@ Remarks:
Parameters: Parameters:
* eax = 48 - function number * eax = 48 - function number
* ebx = 8 - subfunction number * ebx = 8 - subfunction number
* ecx = pointer to a block for function 58, in * ecx = pointer to filename of the skin
which the fields of intermediate buffer and file name are filled
Returned value: Returned value:
* eax = 0 - success * eax = 0 - success
* otherwise eax = file system error code; if file does not * 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 * If BIOS does not support this extension, its behavior is emulated
(through kernel-mode analogues of subfunctions of function 62). (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). ========== ========== Function 60 - Inter Process Communication (IPC). ==========
====================================================================== ======================================================================
@@ -4502,12 +4032,6 @@ Parameters:
Returned value: Returned value:
* eax = socketnum1, -1 on error * eax = socketnum1, -1 on error
* ebx = socketnum2, errorcode on error * ebx = socketnum2, errorcode on error
Remarks:
Optstruct: dd level
dd optionname
dd optlength
db options...
====================================================================== ======================================================================
=============== Function -1 - terminate thread/process =============== =============== Function -1 - terminate thread/process ===============

View File

@@ -186,6 +186,7 @@ USB_STATUS_BUFOVERRUN = 12 ; overflow of internal controller buffer
USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer
USB_STATUS_CLOSED = 16 ; pipe closed, either explicitly with USBClosePipe USB_STATUS_CLOSED = 16 ; pipe closed, either explicitly with USBClosePipe
; or due to device disconnect ; 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 If several transfers are queued for the same pipe, their callback functions
are called in the same order as they were queued. 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 with USB_STATUS_CLOSED. The call to DeviceDisconnected() occurs after
all callbacks. 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); void* __stdcall USBGetParam(void* pipe0, int param);
Returns miscellaneous parameters of the device. Returns miscellaneous parameters of the device.
pipe0 is the pointer to the config pipe. pipe0 is the pointer to the config pipe.

View File

@@ -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: ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
; 0x2500 -> 0xC4, 0x2502 -> 0xB3, 0x250C -> 0xDA, 0x2510 -> 0xBF, ;; Distributed under terms of the GNU General Public License ;;
; 0x2514 -> 0xC0, 0x2518 -> 0xD9, 0x252C -> 0xC2, 0x2534 -> 0xC1, 0x2551 -> 0xBA ;; ;;
macro fetch_utf8_char string, offs, char, graph ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5082 $
; fetch the UTF-8 character in addrspace:offs to char
macro fetch_utf8_char addrspace, offs, char
{ local first_byte, b { local first_byte, b
virtual at 0
db string
if offs >= $
char = -1
else
; fetch first byte ; fetch first byte
load first_byte byte from offs load first_byte byte from addrspace:offs
if first_byte < 0x80 if first_byte < 0x80
char = first_byte char = first_byte
offs = offs + 1 offs = offs + 1
else if first_byte < 0xC0 else if first_byte < 0xC0
.err Invalid UTF-8 string err Invalid UTF-8 string
else if first_byte < 0xE0 else if first_byte < 0xE0
char = first_byte and 0x1F 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) char = (char shl 6) + (b and 0x3F)
offs = offs + 2 offs = offs + 2
else if first_byte < 0xF0 else if first_byte < 0xF0
char = first_byte and 0xF 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) 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) char = (char shl 6) + (b and 0x3F)
offs = offs + 3 offs = offs + 3
else if first_byte < 0xF8 else if first_byte < 0xF8
char = first_byte and 0x7 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) 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) 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) char = (char shl 6) + (b and 0x3F)
offs = offs + 4 offs = offs + 4
else else
.err Invalid UTF-8 string err Invalid UTF-8 string
end if
end if
end virtual
if char = 0x2500
graph = 0xC4
else if char = 0x2502
graph = 0xB3
else if char = 0x250C
graph = 0xDA
else if char = 0x2510
graph = 0xBF
else if char = 0x2514
graph = 0xC0
else if char = 0x2518
graph = 0xD9
else if char = 0x252C
graph = 0xC2
else if char = 0x2534
graph = 0xC1
else if char = 0x2551
graph = 0xBA
else
graph = 0
end if 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
db 0xC4
else if char = 0x2502
db 0xB3
else if char = 0x250C
db 0xDA
else if char = 0x2510
db 0xBF
else if char = 0x2514
db 0xC0
else if char = 0x2518
db 0xD9
else if char = 0x252C
db 0xC2
else if char = 0x2534
db 0xC1
else if char = 0x2551
db 0xBA
else if char < 0x80
db char
else
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. ; Russian: use CP866.
; 0x00-0x7F - trivial map
; 0x410-0x43F -> 0x80-0xAF ; 0x410-0x43F -> 0x80-0xAF
; 0x440-0x44F -> 0xE0-0xEF ; 0x440-0x44F -> 0xE0-0xEF
; 0x401 -> 0xF0, 0x451 -> 0xF1 ; 0x401 -> 0xF0, 0x451 -> 0xF1
macro cp866 [arg] declare_encoding cp866
{ local offs, char, graph {
offs = 0 if char = 0x401
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x80
db char
else if char = 0x401
db 0xF0 db 0xF0
else if char = 0x451 else if char = 0x451
db 0xF1 db 0xF1
else if (char < 0x410) | (char > 0x44F) else if (char < 0x410) | (char > 0x44F)
.err Failed to convert to CP866 err Failed to convert to CP866
else if char < 0x440 else if char < 0x440
db char - 0x410 + 0x80 db char - 0x410 + 0x80
else else
db char - 0x440 + 0xE0 db char - 0x440 + 0xE0
end if end if
end while
}
struc cp866 [arg]
{
common
cp866 arg
} }
; Latin-1 encoding ; Latin-1 encoding
; 0x00-0xFF - trivial map ; 0x00-0xFF - trivial map
macro latin1 [arg] declare_encoding latin1
{ local offs, char, graph {
offs = 0 if char < 0x100
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x100
db char db char
else else
.err Failed to convert to Latin-1 err Failed to convert to Latin-1
end if end if
end while
}
struc latin1 [arg]
{
common
latin1 arg
} }
; CP850 encoding ; CP850 encoding
macro cp850 [arg] declare_encoding cp850
{ local offs, char, graph {
offs = 0 if char = 0xBF
while 1
fetch_utf8_char arg, offs, char, graph
if char = -1
break
end if
if graph
db graph
else if char < 0x80
db char
else if char = 0xBF
db 0xA8 db 0xA8
else if char = 0xE1 else if char = 0xE1
db 0xA0 db 0xA0
@@ -157,11 +142,4 @@ macro cp850 [arg]
else else
err Failed to convert to CP850 err Failed to convert to CP850
end if end if
end while
}
struc cp850 [arg]
{
common
cp850 arg
} }

View File

@@ -2,11 +2,14 @@
;; ;; ;; ;;
;; Contains ext2 block handling code. ;; ;; Contains ext2 block handling code. ;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4891 $
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
; Write ext2 block from memory to disk. ; Write ext2 block from memory to disk.
; Input: eax = i_block (block number in ext2 terms); ; Input: eax = i_block (block number in ext2 terms);

View File

@@ -2,11 +2,14 @@
;; ;; ;; ;;
;; Contains ext2 initialization, plus syscall handling code. ;; ;; Contains ext2 initialization, plus syscall handling code. ;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5089 $
include 'ext2.inc' include 'ext2.inc'
include 'blocks.inc' include 'blocks.inc'
include 'inode.inc' include 'inode.inc'
@@ -56,6 +59,8 @@ endp
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
proc ext2_create_partition proc ext2_create_partition
push ebx push ebx
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .fail
mov eax, 2 ; Superblock starts at 1024-bytes. mov eax, 2 ; Superblock starts at 1024-bytes.
add ebx, 512 ; Get pointer to fs-specific buffer. add ebx, 512 ; Get pointer to fs-specific buffer.

View File

@@ -2,11 +2,14 @@
;; ;; ;; ;;
;; Contains ext2 structures, and macros. ;; ;; Contains ext2 structures, and macros. ;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4891 $
; Future jobs for driver, in order of preference: ; Future jobs for driver, in order of preference:
; * clean up existing extents support. ; * clean up existing extents support.
; * add b-tree directories support. ; * add b-tree directories support.

View File

@@ -2,11 +2,14 @@
;; ;; ;; ;;
;; Contains ext2 inode handling code. ;; ;; Contains ext2 inode handling code. ;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4891 $
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
; Receives block number from extent-based inode. ; Receives block number from extent-based inode.
; Input: ecx = number of block in inode ; Input: ecx = number of block in inode

View File

@@ -2,11 +2,14 @@
;; ;; ;; ;;
;; Contains common resource allocation + freeing code. ;; ;; Contains common resource allocation + freeing code. ;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;;
;; Distributed under the terms of the new BSD license. ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4891 $
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
; Frees a resource (block/inode). ; Frees a resource (block/inode).
; Input: eax = resource ID. ; Input: eax = resource ID.

View File

@@ -154,6 +154,9 @@ fat_create_partition.return0:
xor eax, eax xor eax, eax
ret ret
fat_create_partition: fat_create_partition:
; sector size must be 512
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .return0
; bootsector must have been successfully read ; bootsector must have been successfully read
cmp dword [esp+4], 0 cmp dword [esp+4], 0
jnz .return0 jnz .return0

View File

@@ -43,6 +43,30 @@ rootdirs:
db 3,'cd3' db 3,'cd3'
dd fs_OnCd3 dd fs_OnCd3
dd fs_NextCd 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 db 0
@@ -57,6 +81,22 @@ virtual_root_query:
db 'cd2',0 db 'cd2',0
dd fs_HasCd3 dd fs_HasCd3
db 'cd3',0 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 dd 0
endg endg
@@ -149,8 +189,8 @@ file_system_lfn:
cmp dword [ebx], 1 cmp dword [ebx], 1
jnz .access_denied jnz .access_denied
xor eax, eax xor eax, eax
mov ebp, [ebx+12] ;количество блоков для считывания mov ebp, [ebx+12] ;the number of blocks to read
mov edx, [ebx+16] ;куда записывать рузельтат mov edx, [ebx+16] ;where to write the result
; add edx, std_application_base_address ; add edx, std_application_base_address
push dword [ebx+4] ; first block push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags mov ebx, [ebx+8] ; flags
@@ -404,8 +444,7 @@ file_system_lfn:
fs_NotImplemented: fs_NotImplemented:
mov eax, 2 mov eax, 2
ret ret
;-----------------------------------------------------------------------------
;*******************************************************
fs_OnCd0: fs_OnCd0:
call reserve_cd call reserve_cd
mov [ChannelNumber], 1 mov [ChannelNumber], 1
@@ -413,6 +452,7 @@ fs_OnCd0:
push 6 push 6
push 1 push 1
jmp fs_OnCd jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd1: fs_OnCd1:
call reserve_cd call reserve_cd
mov [ChannelNumber], 1 mov [ChannelNumber], 1
@@ -420,6 +460,7 @@ fs_OnCd1:
push 4 push 4
push 2 push 2
jmp fs_OnCd jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd2: fs_OnCd2:
call reserve_cd call reserve_cd
mov [ChannelNumber], 2 mov [ChannelNumber], 2
@@ -427,22 +468,96 @@ fs_OnCd2:
push 2 push 2
push 3 push 3
jmp fs_OnCd jmp fs_OnCd
;-----------------------------------------------------------------------------
fs_OnCd3: fs_OnCd3:
call reserve_cd call reserve_cd
mov [ChannelNumber], 2 mov [ChannelNumber], 2
mov [DiskNumber], 1 mov [DiskNumber], 1
push 0 push 0
push 4 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: fs_OnCd:
call reserve_cd_channel
pop eax pop eax
mov [cdpos], eax mov [cdpos], eax
call reserve_cd_channel
pop eax pop eax
cmp ecx, 0x100 cmp ecx, 0x100
jae .nf jae .nf
push ecx ebx push ecx ebx
mov cl, al 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 shr bl, cl
test bl, 2 test bl, 2
pop ebx ecx pop ebx ecx
@@ -472,7 +587,7 @@ fs_OnCd:
and [cd_status], 0 and [cd_status], 0
mov dword [image_of_eax], 2 ; not implemented mov dword [image_of_eax], 2 ; not implemented
ret ret
;-----------------------------------------------------------------------------
fs_CdServices: fs_CdServices:
dd fs_CdRead dd fs_CdRead
dd fs_CdReadFolder dd fs_CdReadFolder
@@ -485,32 +600,74 @@ fs_CdServices:
dd fs_NotImplemented dd fs_NotImplemented
dd fs_NotImplemented dd fs_NotImplemented
fs_NumCdServices = ($ - fs_CdServices)/4 fs_NumCdServices = ($ - fs_CdServices)/4
;-----------------------------------------------------------------------------
;*******************************************************
fs_HasCd0: fs_HasCd0:
test byte [DRIVE_DATA+1], 10000000b test byte [DRIVE_DATA+1], 10000000b
setnz al setnz al
ret ret
;--------------------------------------
fs_HasCd1: fs_HasCd1:
test byte [DRIVE_DATA+1], 00100000b test byte [DRIVE_DATA+1], 00100000b
setnz al setnz al
ret ret
;--------------------------------------
fs_HasCd2: fs_HasCd2:
test byte [DRIVE_DATA+1], 00001000b test byte [DRIVE_DATA+1], 00001000b
setnz al setnz al
ret ret
;--------------------------------------
fs_HasCd3: fs_HasCd3:
test byte [DRIVE_DATA+1], 00000010b test byte [DRIVE_DATA+1], 00000010b
setnz al setnz al
ret 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: ; fs_NextXXX functions:
; in: eax = partition number, from which start to scan ; in: eax = partition number, from which start to scan
; out: CF=1 => no more partitions ; out: CF=1 => no more partitions
; CF=0 => eax=next partition number ; CF=0 => eax=next partition number
;
;******************************************************* ;-----------------------------------------------------------------------------
fs_NextCd: fs_NextCd:
; we always have /cdX/1 ; we always have /cdX/1
test eax, eax test eax, eax
@@ -520,8 +677,6 @@ fs_NextCd:
clc clc
@@: @@:
ret ret
;*******************************************************
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
process_replace_file_name: process_replace_file_name:
; in ; in

View File

@@ -7,18 +7,15 @@
$Revision$ $Revision$
;-----------------------------------------------------------------------------
uglobal uglobal
cd_current_pointer_of_input dd 0 cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0 cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0 cd_mem_location dd 0
cd_counter_block dd 0 cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
endg endg
;-----------------------------------------------------------------------------
reserve_cd: reserve_cd:
cli cli
cmp [cd_status], 0 cmp [cd_status], 0
je reserve_ok2 je reserve_ok2
@@ -26,9 +23,8 @@ reserve_cd:
sti sti
call change_task call change_task
jmp reserve_cd jmp reserve_cd
;-----------------------------------------------------------------------------
reserve_ok2: reserve_ok2:
push eax push eax
mov eax, [CURRENT_TASK] mov eax, [CURRENT_TASK]
shl eax, 5 shl eax, 5
@@ -37,48 +33,105 @@ reserve_cd:
pop eax pop eax
sti sti
ret ret
;-----------------------------------------------------------------------------
reserve_cd_channel: reserve_cd_channel:
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
pushad pushad
mov ecx, ide_channel1_mutex mov eax, [cdpos]
call mutex_lock dec eax
mov [IDE_Channel_1], 1 shr eax, 2
popad
ret
.IDE_Channel_2:
pushad
mov ecx, ide_channel2_mutex
call mutex_lock
mov [IDE_Channel_2], 1
popad
ret
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: free_cd_channel:
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
pushad pushad
mov ecx, ide_channel1_mutex mov eax, [cdpos]
call mutex_unlock dec eax
popad shr eax, 2
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
pushad
mov ecx, ide_channel2_mutex
call mutex_unlock
popad
ret
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 uglobal
cd_status dd 0 cd_status dd 0
endg endg
;-----------------------------------------------------------------------------
;----------------------------------------------------------------
; ;
; fs_CdRead - LFN variant for reading CD disk ; fs_CdRead - LFN variant for reading CD disk
; ;
@@ -91,91 +144,114 @@ endg
; ret ebx = bytes read or 0xffffffff file not found ; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg ; eax = 0 ok read or other = errormsg
; ;
;-------------------------------------------------------------- ;-----------------------------------------------------------------------------
fs_CdRead: fs_CdRead:
push edi push edi
cmp byte [esi], 0 cmp byte [esi], 0
jnz @f jnz @f
;--------------------------------------
.noaccess: .noaccess:
pop edi pop edi
;--------------------------------------
.noaccess_2: .noaccess_2:
or ebx, -1 or ebx, -1
mov eax, ERROR_ACCESS_DENIED mov eax, ERROR_ACCESS_DENIED
ret ret
;--------------------------------------
.noaccess_3: .noaccess_3:
pop eax edx ecx edi pop eax edx ecx edi
jmp .noaccess_2 jmp .noaccess_2
;--------------------------------------
@@: @@:
call cd_find_lfn call cd_find_lfn
jnc .found jnc .found
pop edi pop edi
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .noaccess_2 jne .noaccess_2
or ebx, -1 or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND mov eax, ERROR_FILE_NOT_FOUND
ret ret
;--------------------------------------
.found: .found:
mov edi, [cd_current_pointer_of_input] mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b; do not allow read directories test byte [edi+25], 10b; do not allow read directories
jnz .noaccess jnz .noaccess
test ebx, ebx test ebx, ebx
jz .l1 jz .l1
cmp dword [ebx+4], 0 cmp dword [ebx+4], 0
jz @f jz @f
xor ebx, ebx xor ebx, ebx
;--------------------------------------
.reteof: .reteof:
mov eax, 6; end of file mov eax, 6; end of file
pop edi pop edi
ret ret
;--------------------------------------
@@: @@:
mov ebx, [ebx] mov ebx, [ebx]
;--------------------------------------
.l1: .l1:
push ecx edx push ecx edx
push 0 push 0
mov eax, [edi+10] ; реальный размер файловой секции mov eax, [edi+10] ; real size of the file section
sub eax, ebx sub eax, ebx
jb .eof jb .eof
cmp eax, ecx cmp eax, ecx
jae @f jae @f
mov ecx, eax mov ecx, eax
mov byte [esp], 6 mov byte [esp], 6
;--------------------------------------
@@: @@:
mov eax, [edi+2] mov eax, [edi+2]
mov [CDSectorAddress], eax mov [CDSectorAddress], eax
;--------------------------------------
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data ; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector: .new_sector:
test ecx, ecx test ecx, ecx
jz .done jz .done
sub ebx, 2048 sub ebx, 2048
jae .next jae .next
add ebx, 2048 add ebx, 2048
jnz .incomplete_sector jnz .incomplete_sector
cmp ecx, 2048 cmp ecx, 2048
jb .incomplete_sector jb .incomplete_sector
; we may read and memmove complete sector ; we may read and memmove complete sector
mov [CDDataBuf_pointer], edx mov [CDDataBuf_pointer], edx
call ReadCDWRetr; читаем сектор файла call ReadCDWRetr ; read sector of file
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .noaccess_3 jne .noaccess_3
add edx, 2048 add edx, 2048
sub ecx, 2048 sub ecx, 2048
;--------------------------------------
.next: .next:
inc dword [CDSectorAddress] inc dword [CDSectorAddress]
jmp .new_sector jmp .new_sector
;--------------------------------------
.incomplete_sector: .incomplete_sector:
; we must read and memmove incomplete sector ; we must read and memmove incomplete sector
mov [CDDataBuf_pointer], CDDataBuf mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr; читаем сектор файла call ReadCDWRetr ; read sector of file
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .noaccess_3 jne .noaccess_3
push ecx push ecx
add ecx, ebx add ecx, ebx
cmp ecx, 2048 cmp ecx, 2048
jbe @f jbe @f
mov ecx, 2048 mov ecx, 2048
;--------------------------------------
@@: @@:
sub ecx, ebx sub ecx, ebx
push edi esi ecx push edi esi ecx
@@ -189,19 +265,19 @@ fs_CdRead:
pop ecx pop ecx
xor ebx, ebx xor ebx, ebx
jmp .next jmp .next
;--------------------------------------
.done: .done:
mov ebx, edx mov ebx, edx
pop eax edx ecx edi pop eax edx ecx edi
sub ebx, edx sub ebx, edx
ret ret
;--------------------------------------
.eof: .eof:
mov ebx, edx mov ebx, edx
pop eax edx ecx pop eax edx ecx
sub ebx, edx sub ebx, edx
jmp .reteof jmp .reteof
;-----------------------------------------------------------------------------
;----------------------------------------------------------------
; ;
; fs_CdReadFolder - LFN variant for reading CD disk folder ; fs_CdReadFolder - LFN variant for reading CD disk folder
; ;
@@ -215,30 +291,37 @@ fs_CdRead:
; ret ebx = blocks read or 0xffffffff folder not found ; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg ; eax = 0 ok read or other = errormsg
; ;
;-------------------------------------------------------------- ;-----------------------------------------------------------------------------
fs_CdReadFolder: fs_CdReadFolder:
push edi push edi
call cd_find_lfn call cd_find_lfn
jnc .found jnc .found
pop edi pop edi
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .noaccess_1 jne .noaccess_1
or ebx, -1 or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND mov eax, ERROR_FILE_NOT_FOUND
ret ret
;--------------------------------------
.found: .found:
mov edi, [cd_current_pointer_of_input] mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir jnz .found_dir
pop edi pop edi
;--------------------------------------
.noaccess_1: .noaccess_1:
or ebx, -1 or ebx, -1
mov eax, ERROR_ACCESS_DENIED mov eax, ERROR_ACCESS_DENIED
ret ret
;--------------------------------------
.found_dir: .found_dir:
mov eax, [edi+2] ; eax=cluster mov eax, [edi+2] ; eax=cluster
mov [CDSectorAddress], eax mov [CDSectorAddress], eax
mov eax, [edi+10] ; размер директрории mov eax, [edi+10] ; directory size
;--------------------------------------
.doit: .doit:
; init header ; init header
push eax ecx push eax ecx
@@ -250,21 +333,23 @@ fs_CdReadFolder:
mov byte [edx], 1 ; version mov byte [edx], 1 ; version
mov [cd_mem_location], edx mov [cd_mem_location], edx
add [cd_mem_location], 32 add [cd_mem_location], 32
; начинаем переброску БДВК в УСВК
;.mainloop: ;.mainloop:
mov [cd_counter_block], dword 0 mov [cd_counter_block], dword 0
dec dword [CDSectorAddress] dec dword [CDSectorAddress]
push ecx push ecx
;--------------------------------------
.read_to_buffer: .read_to_buffer:
inc dword [CDSectorAddress] inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; читаем сектор директории call ReadCDWRetr ; read sector of directory
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .noaccess_1 jne .noaccess_1
call .get_names_from_buffer call .get_names_from_buffer
sub eax, 2048 sub eax, 2048
; директория закончилась? ; directory is over?
ja .read_to_buffer ja .read_to_buffer
mov edi, [cd_counter_block] mov edi, [cd_counter_block]
mov [edx+8], edi mov [edx+8], edi
mov edi, [ebx] mov edi, [ebx]
@@ -272,24 +357,30 @@ fs_CdReadFolder:
xor eax, eax xor eax, eax
dec ecx dec ecx
js @f js @f
mov al, ERROR_END_OF_FILE mov al, ERROR_END_OF_FILE
;--------------------------------------
@@: @@:
pop ecx edi pop ecx edi
mov ebx, [edx+4] mov ebx, [edx+4]
ret ret
;--------------------------------------
.get_names_from_buffer: .get_names_from_buffer:
mov [cd_current_pointer_of_input_2], CDDataBuf mov [cd_current_pointer_of_input_2], CDDataBuf
push eax esi edi edx push eax esi edi edx
;--------------------------------------
.get_names_from_buffer_1: .get_names_from_buffer_1:
call cd_get_name call cd_get_name
jc .end_buffer jc .end_buffer
inc dword [cd_counter_block] inc dword [cd_counter_block]
mov eax, [cd_counter_block] mov eax, [cd_counter_block]
cmp [ebx], eax cmp [ebx], eax
jae .get_names_from_buffer_1 jae .get_names_from_buffer_1
test ecx, ecx test ecx, ecx
jz .get_names_from_buffer_1 jz .get_names_from_buffer_1
mov edi, [cd_counter_block] mov edi, [cd_counter_block]
mov [edx+4], edi mov [edx+4], edi
dec ecx dec ecx
@@ -298,189 +389,209 @@ fs_CdReadFolder:
add edi, 40 add edi, 40
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode jnz .unicode
; jmp .unicode ;--------------------------------------
.ansi: .ansi:
cmp [cd_counter_block], 2 cmp [cd_counter_block], 2
jbe .ansi_parent_directory jbe .ansi_parent_directory
cld cld
lodsw lodsw
xchg ah, al xchg ah, al
call uni2ansi_char call uni2ansi_char
cld cld
stosb stosb
; проверка конца файла ; check end of file
mov ax, [esi] mov ax, [esi]
cmp ax, word 3B00h; сепаратор конца файла ';' cmp ax, word 3B00h ; separator end of file ';'
je .cd_get_parameters_of_file_1 je .cd_get_parameters_of_file_1
; проверка для файлов не заканчивающихся сепаратором ; check for files not ending with separator
movzx eax, byte [ebp-33] movzx eax, byte [ebp-33]
add eax, ebp add eax, ebp
sub eax, 34 sub eax, 34
cmp esi, eax cmp esi, eax
je .cd_get_parameters_of_file_1 je .cd_get_parameters_of_file_1
; проверка конца папки ; check the end of the directory
movzx eax, byte [ebp-1] movzx eax, byte [ebp-1]
add eax, ebp add eax, ebp
cmp esi, eax cmp esi, eax
jb .ansi jb .ansi
;--------------------------------------
.cd_get_parameters_of_file_1: .cd_get_parameters_of_file_1:
mov [edi], byte 0 mov [edi], byte 0
call cd_get_parameters_of_file call cd_get_parameters_of_file
add [cd_mem_location], 304 add [cd_mem_location], 304
jmp .get_names_from_buffer_1 jmp .get_names_from_buffer_1
;--------------------------------------
.ansi_parent_directory: .ansi_parent_directory:
cmp [cd_counter_block], 2 cmp [cd_counter_block], 2
je @f je @f
mov [edi], byte '.' mov [edi], byte '.'
inc edi inc edi
jmp .cd_get_parameters_of_file_1 jmp .cd_get_parameters_of_file_1
;--------------------------------------
@@: @@:
mov [edi], word '..' mov [edi], word '..'
add edi, 2 add edi, 2
jmp .cd_get_parameters_of_file_1 jmp .cd_get_parameters_of_file_1
;--------------------------------------
.unicode: .unicode:
cmp [cd_counter_block], 2 cmp [cd_counter_block], 2
jbe .unicode_parent_directory jbe .unicode_parent_directory
cld cld
movsw movsw
; проверка конца файла ; check end of file
mov ax, [esi] mov ax, [esi]
cmp ax, word 3B00h; сепаратор конца файла ';' cmp ax, word 3B00h; separator end of file ';'
je .cd_get_parameters_of_file_2 je .cd_get_parameters_of_file_2
; проверка для файлов не заканчивающихся сепаратором ; check for files not ending with separator
movzx eax, byte [ebp-33] movzx eax, byte [ebp-33]
add eax, ebp add eax, ebp
sub eax, 34 sub eax, 34
cmp esi, eax cmp esi, eax
je .cd_get_parameters_of_file_2 je .cd_get_parameters_of_file_2
; проверка конца папки ; check the end of the directory
movzx eax, byte [ebp-1] movzx eax, byte [ebp-1]
add eax, ebp add eax, ebp
cmp esi, eax cmp esi, eax
jb .unicode jb .unicode
;--------------------------------------
.cd_get_parameters_of_file_2: .cd_get_parameters_of_file_2:
mov [edi], word 0 mov [edi], word 0
call cd_get_parameters_of_file call cd_get_parameters_of_file
add [cd_mem_location], 560 add [cd_mem_location], 560
jmp .get_names_from_buffer_1 jmp .get_names_from_buffer_1
;--------------------------------------
.unicode_parent_directory: .unicode_parent_directory:
cmp [cd_counter_block], 2 cmp [cd_counter_block], 2
je @f je @f
mov [edi], word 2E00h; '.' mov [edi], word 2E00h; '.'
add edi, 2 add edi, 2
jmp .cd_get_parameters_of_file_2 jmp .cd_get_parameters_of_file_2
;--------------------------------------
@@: @@:
mov [edi], dword 2E002E00h; '..' mov [edi], dword 2E002E00h; '..'
add edi, 4 add edi, 4
jmp .cd_get_parameters_of_file_2 jmp .cd_get_parameters_of_file_2
;--------------------------------------
.end_buffer: .end_buffer:
pop edx edi esi eax pop edx edi esi eax
ret ret
;-----------------------------------------------------------------------------
cd_get_parameters_of_file: cd_get_parameters_of_file:
mov edi, [cd_mem_location] mov edi, [cd_mem_location]
cd_get_parameters_of_file_1: cd_get_parameters_of_file_1:
; получаем атрибуты файла ; get file attributes
xor eax, eax xor eax, eax
; файл не архивировался ; file is not archived
inc eax inc eax
shl eax, 1 shl eax, 1
; это каталог? ; is a directory?
test [ebp-8], byte 2 test [ebp-8], byte 2
jz .file jz .file
inc eax inc eax
;--------------------------------------
.file: .file:
; метка тома не как в FAT, в этом виде отсутсвует ; not as a volume label in the FAT, in this form not available
; файл не является системным ; file is not a system
shl eax, 3 shl eax, 3
; файл является скрытым? (атрибут существование) ; file is hidden? (attribute of existence)
test [ebp-8], byte 1 test [ebp-8], byte 1
jz .hidden jz .hidden
inc eax inc eax
;--------------------------------------
.hidden: .hidden:
shl eax, 1 shl eax, 1
; файл всегда только для чтения, так как это CD ; file is always read-only, as this CD
inc eax inc eax
mov [edi], eax mov [edi], eax
; получаем время для файла ; get the time to file
;час ; hour
movzx eax, byte [ebp-12] movzx eax, byte [ebp-12]
shl eax, 8 shl eax, 8
;минута ; minute
mov al, [ebp-11] mov al, [ebp-11]
shl eax, 8 shl eax, 8
;секунда ; second
mov al, [ebp-10] mov al, [ebp-10]
;время создания файла ; file creation time
mov [edi+8], eax mov [edi+8], eax
;время последнего доступа ; last access time
mov [edi+16], eax mov [edi+16], eax
;время последней записи ; last write time
mov [edi+24], eax mov [edi+24], eax
; получаем дату для файла ; get date for file
;год ; year
movzx eax, byte [ebp-15] movzx eax, byte [ebp-15]
add eax, 1900 add eax, 1900
shl eax, 8 shl eax, 8
;месяц ; month
mov al, [ebp-14] mov al, [ebp-14]
shl eax, 8 shl eax, 8
;день ; day
mov al, [ebp-13] mov al, [ebp-13]
;дата создания файла ; file creation date
mov [edi+12], eax mov [edi+12], eax
;время последнего доступа ; last access date
mov [edi+20], eax mov [edi+20], eax
;время последней записи ; last write date
mov [edi+28], eax mov [edi+28], eax
; получаем тип данных имени ; get the data type of name
xor eax, eax xor eax, eax
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode_1 jnz .unicode_1
mov [edi+4], eax mov [edi+4], eax
jmp @f jmp @f
;--------------------------------------
.unicode_1: .unicode_1:
inc eax inc eax
mov [edi+4], eax mov [edi+4], eax
;--------------------------------------
@@: @@:
; получаем размер файла в байтах ; get the file size in bytes
xor eax, eax xor eax, eax
mov [edi+32+4], eax mov [edi+32+4], eax
mov eax, [ebp-23] mov eax, [ebp-23]
mov [edi+32], eax mov [edi+32], eax
ret ret
;-----------------------------------------------------------------------------
;----------------------------------------------------------------
; ;
; fs_CdGetFileInfo - LFN variant for CD ; fs_CdGetFileInfo - LFN variant for CD
; get file/directory attributes structure ; get file/directory attributes structure
; ;
;---------------------------------------------------------------- ;-----------------------------------------------------------------------------
fs_CdGetFileInfo: fs_CdGetFileInfo:
cmp byte [esi], 0 cmp byte [esi], 0
jnz @f jnz @f
mov eax, 2 mov eax, 2
ret ret
;--------------------------------------
@@: @@:
push edi push edi
call cd_find_lfn call cd_find_lfn
pushfd pushfd
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jz @f jz @f
popfd popfd
pop edi pop edi
mov eax, 11 mov eax, 11
ret ret
;--------------------------------------
@@: @@:
popfd popfd
jnc @f jnc @f
pop edi pop edi
mov eax, ERROR_FILE_NOT_FOUND mov eax, ERROR_FILE_NOT_FOUND
ret ret
;--------------------------------------
@@: @@:
mov edi, edx mov edi, edx
@@ -493,32 +604,31 @@ fs_CdGetFileInfo:
pop edi pop edi
xor eax, eax xor eax, eax
ret ret
;-----------------------------------------------------------------------------
;----------------------------------------------------------------
cd_find_lfn: cd_find_lfn:
mov [cd_appl_data], 0 mov [cd_appl_data], 0
; in: esi+ebp -> name ; in: esi+ebp -> name
; out: CF=1 - file not found ; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry ; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi push eax esi
; 16 сектор начало набора дескрипторов томов ; Sector 16 - start set of volume descriptors
call WaitUnitReady call WaitUnitReady
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .access_denied jne .access_denied
call prevent_medium_removal call prevent_medium_removal
; тестовое чтение ; testing of reading
mov [CDSectorAddress], dword 16 mov [CDSectorAddress], dword 16
mov [CDDataBuf_pointer], CDDataBuf mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr;_1 call ReadCDWRetr;_1
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .access_denied jne .access_denied
; вычисление последней сессии ; calculation of the last session
call WaitUnitReady call WaitUnitReady
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .access_denied jne .access_denied
call Read_TOC call Read_TOC
mov ah, [CDDataBuf+4+4] mov ah, [CDDataBuf+4+4]
mov al, [CDDataBuf+4+5] mov al, [CDDataBuf+4+5]
@@ -529,7 +639,7 @@ cd_find_lfn:
mov [CDSectorAddress], eax mov [CDSectorAddress], eax
; mov [CDSectorAddress],dword 15 ; mov [CDSectorAddress],dword 15
mov [CDDataBuf_pointer], CDDataBuf mov [CDDataBuf_pointer], CDDataBuf
;--------------------------------------
.start: .start:
inc dword [CDSectorAddress] inc dword [CDSectorAddress]
call ReadCDWRetr;_1 call ReadCDWRetr;_1
@@ -537,111 +647,128 @@ cd_find_lfn:
jne .access_denied jne .access_denied
.start_check: .start_check:
; проверка на вшивость ; checking for "lice"
cmp [CDDataBuf+1], dword 'CD00' cmp [CDDataBuf+1], dword 'CD00'
jne .access_denied jne .access_denied
cmp [CDDataBuf+5], byte '1' cmp [CDDataBuf+5], byte '1'
jne .access_denied jne .access_denied
; сектор является терминатором набор дескрипторов томов? ; sector is the terminator of set of descriptors volumes?
cmp [CDDataBuf], byte 0xff cmp [CDDataBuf], byte 0xff
je .access_denied je .access_denied
; сектор является дополнительным и улучшенным дескриптором тома? ; sector is an additional and improved descriptor of volume?
cmp [CDDataBuf], byte 0x2 cmp [CDDataBuf], byte 0x2
jne .start jne .start
; сектор является дополнительным дескриптором тома? ; sector is an additional descriptor of volume?
cmp [CDDataBuf+6], byte 0x1 cmp [CDDataBuf+6], byte 0x1
jne .start jne .start
; параметры root директрории ; parameters of root directory
mov eax, [CDDataBuf+0x9c+2]; начало root директрории mov eax, [CDDataBuf+0x9c+2]; start of root directory
mov [CDSectorAddress], eax mov [CDSectorAddress], eax
mov eax, [CDDataBuf+0x9c+10]; размер root директрории mov eax, [CDDataBuf+0x9c+10]; size of root directory
cmp byte [esi], 0 cmp byte [esi], 0
jnz @f jnz @f
mov [cd_current_pointer_of_input], CDDataBuf+0x9c mov [cd_current_pointer_of_input], CDDataBuf+0x9c
jmp .done jmp .done
;--------------------------------------
@@: @@:
; начинаем поиск ; start the search
.mainloop: .mainloop:
dec dword [CDSectorAddress] dec dword [CDSectorAddress]
;--------------------------------------
.read_to_buffer: .read_to_buffer:
inc dword [CDSectorAddress] inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; читаем сектор директории call ReadCDWRetr ; read sector of directory
cmp [DevErrorCode], 0 cmp [DevErrorCode], 0
jne .access_denied jne .access_denied
push ebp push ebp
call cd_find_name_in_buffer call cd_find_name_in_buffer
pop ebp pop ebp
jnc .found jnc .found
sub eax, 2048 sub eax, 2048
; директория закончилась? ; directory is over?
cmp eax, 0 cmp eax, 0
ja .read_to_buffer ja .read_to_buffer
; нет искомого элемента цепочки ; desired element of chain is not found
.access_denied: .access_denied:
pop esi eax pop esi eax
mov [cd_appl_data], 1 mov [cd_appl_data], 1
stc stc
ret ret
; искомый элемент цепочки найден ;--------------------------------------
.found: ; desired element of chain found
; конец пути файла .found:
; the end of the file path
cmp byte [esi-1], 0 cmp byte [esi-1], 0
jz .done jz .done
.nested: .nested:
mov eax, [cd_current_pointer_of_input] mov eax, [cd_current_pointer_of_input]
push dword [eax+2] push dword [eax+2]
pop dword [CDSectorAddress] ; начало директории pop dword [CDSectorAddress] ; beginning of the directory
mov eax, [eax+2+8]; размер директории mov eax, [eax+2+8] ; size of directory
jmp .mainloop jmp .mainloop
; указатель файла найден ;--------------------------------------
.done: ; file pointer found
.done:
test ebp, ebp test ebp, ebp
jz @f jz @f
mov esi, ebp mov esi, ebp
xor ebp, ebp xor ebp, ebp
jmp .nested jmp .nested
;--------------------------------------
@@: @@:
pop esi eax pop esi eax
mov [cd_appl_data], 1 mov [cd_appl_data], 1
clc clc
ret ret
;-----------------------------------------------------------------------------
cd_find_name_in_buffer: cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2], CDDataBuf mov [cd_current_pointer_of_input_2], CDDataBuf
;--------------------------------------
.start: .start:
call cd_get_name call cd_get_name
jc .not_found jc .not_found
call cd_compare_name call cd_compare_name
jc .start jc .start
;--------------------------------------
.found: .found:
clc clc
ret ret
;--------------------------------------
.not_found: .not_found:
stc stc
ret ret
;-----------------------------------------------------------------------------
cd_get_name: cd_get_name:
push eax push eax
mov ebp, [cd_current_pointer_of_input_2] mov ebp, [cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input], ebp mov [cd_current_pointer_of_input], ebp
mov eax, [ebp] mov eax, [ebp]
test eax, eax ; входы закончились? test eax, eax ; entry's is over?
jz .next_sector jz .next_sector
cmp ebp, CDDataBuf+2048 ; буфер закончился?
cmp ebp, CDDataBuf+2048 ; buffer is over?
jae .next_sector jae .next_sector
movzx eax, byte [ebp] movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2], eax; следующий вход каталога add [cd_current_pointer_of_input_2], eax ; next entry of directory
add ebp, 33; указатель установлен на начало имени add ebp, 33; pointer is set to the beginning of the name
pop eax pop eax
clc clc
ret ret
;--------------------------------------
.next_sector: .next_sector:
pop eax pop eax
stc stc
ret ret
;-----------------------------------------------------------------------------
cd_compare_name: cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding) ; compares ASCIIZ-names, case-insensitive (cp866 encoding)
; in: esi->name, ebp->name ; in: esi->name, ebp->name
@@ -650,6 +777,7 @@ cd_compare_name:
; destroys eax ; destroys eax
push esi eax edi push esi eax edi
mov edi, ebp mov edi, ebp
;--------------------------------------
.loop: .loop:
cld cld
lodsb lodsb
@@ -666,94 +794,118 @@ cd_compare_name:
sub edi, 2 sub edi, 2
scasw scasw
jne .name_not_coincide jne .name_not_coincide
;--------------------------------------
.coincides: .coincides:
cmp [esi], byte '/'; разделитель пути, конец имени текущего элемента cmp [esi], byte '/' ; path separator is end of current element
je .done je .done
cmp [esi], byte 0; разделитель пути, конец имени текущего элемента
cmp [esi], byte 0 ; path separator end of name
je .done je .done
jmp .loop jmp .loop
;--------------------------------------
.name_not_coincide: .name_not_coincide:
pop edi eax esi pop edi eax esi
stc stc
ret ret
;--------------------------------------
.done: .done:
; проверка конца файла ; check end of file
cmp [edi], word 3B00h; сепаратор конца файла ';' cmp [edi], word 3B00h; separator end of file ';'
je .done_1 je .done_1
; проверка для файлов не заканчивающихся сепаратором ; check for files not ending with separator
movzx eax, byte [ebp-33] movzx eax, byte [ebp-33]
add eax, ebp add eax, ebp
sub eax, 34 sub eax, 34
cmp edi, eax cmp edi, eax
je .done_1 je .done_1
; проверка конца папки ; check the end of directory
movzx eax, byte [ebp-1] movzx eax, byte [ebp-1]
add eax, ebp add eax, ebp
cmp edi, eax cmp edi, eax
jne .name_not_coincide jne .name_not_coincide
;--------------------------------------
.done_1: .done_1:
pop edi eax pop edi eax
add esp, 4 add esp, 4
inc esi inc esi
clc clc
ret ret
;-----------------------------------------------------------------------------
char_todown: char_todown:
; convert character to uppercase, using cp866 encoding ; convert character to uppercase, using cp866 encoding
; in: al=symbol ; in: al=symbol
; out: al=converted symbol ; out: al=converted symbol
cmp al, 'A' cmp al, 'A'
jb .ret jb .ret
cmp al, 'Z' cmp al, 'Z'
jbe .az jbe .az
cmp al, 0x80 ; 'А' cmp al, 0x80 ; 'А'
jb .ret jb .ret
cmp al, 0x90 ; 'Р' cmp al, 0x90 ; 'Р'
jb .rus1 jb .rus1
cmp al, 0x9F ; 'Я' cmp al, 0x9F ; 'Я'
ja .ret ja .ret
; 0x90-0x9F -> 0xE0-0xEF ; 0x90-0x9F -> 0xE0-0xEF
add al, 0xE0-0x90 add al, 0xE0-0x90
;--------------------------------------
.ret: .ret:
ret ret
;--------------------------------------
.rus1: .rus1:
; 0x80-0x8F -> 0xA0-0xAF ; 0x80-0x8F -> 0xA0-0xAF
.az: .az:
add al, 0x20 add al, 0x20
ret ret
;-----------------------------------------------------------------------------
uni2ansi_char: uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding ; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character ; in: ax=UNICODE character
; out: al=converted ANSI character ; out: al=converted ANSI character
cmp ax, 0x80 cmp ax, 0x80
jb .ascii jb .ascii
cmp ax, 0x401 cmp ax, 0x401
jz .yo1 jz .yo1
cmp ax, 0x451 cmp ax, 0x451
jz .yo2 jz .yo2
cmp ax, 0x410 cmp ax, 0x410
jb .unk jb .unk
cmp ax, 0x440 cmp ax, 0x440
jb .rus1 jb .rus1
cmp ax, 0x450 cmp ax, 0x450
jb .rus2 jb .rus2
;--------------------------------------
.unk: .unk:
mov al, '_' mov al, '_'
jmp .doit jmp .doit
;--------------------------------------
.yo1: .yo1:
mov al, 0xF0 ; 'Ё' in cp866 mov al, 0xF0 ; 'Ё' in cp866
jmp .doit jmp .doit
;--------------------------------------
.yo2: .yo2:
mov al, 0xF1 ; 'ё' in cp866 mov al, 0xF1 ; 'ё' in cp866
jmp .doit jmp .doit
;--------------------------------------
.rus1: .rus1:
; 0x410-0x43F -> 0x80-0xAF ; 0x410-0x43F -> 0x80-0xAF
add al, 0x70 add al, 0x70
jmp .doit jmp .doit
;--------------------------------------
.rus2: .rus2:
; 0x440-0x44F -> 0xE0-0xEF ; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0 add al, 0xA0
;--------------------------------------
.ascii: .ascii:
.doit: .doit:
ret ret
;-----------------------------------------------------------------------------

View File

@@ -152,6 +152,8 @@ ntfs_test_bootsec:
ret ret
proc ntfs_create_partition proc ntfs_create_partition
cmp dword [esi+DISK.MediaInfo.SectorSize], 512
jnz .nope
mov edx, dword [ebp+PARTITION.Length] mov edx, dword [ebp+PARTITION.Length]
cmp dword [esp+4], 0 cmp dword [esp+4], 0
jz .boot_read_ok jz .boot_read_ok

View File

@@ -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' include 'xfs.inc'
; ;
@@ -15,6 +25,8 @@ include 'xfs.inc'
; returns 0 (not XFS or invalid) / pointer to partition structure ; returns 0 (not XFS or invalid) / pointer to partition structure
xfs_create_partition: xfs_create_partition:
push ebx ecx edx esi edi 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 cmp dword[ebx + xfs_sb.sb_magicnum], XFS_SB_MAGIC ; signature
jne .error jne .error

View File

@@ -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 ; from stat.h
; distinguish file types ; distinguish file types
S_IFMT = 0170000o ; These bits determine file type. S_IFMT = 0170000o ; These bits determine file type.

View File

@@ -454,7 +454,11 @@ align 4
cmp al, 120 cmp al, 120
jae .result ;overflow jae .result ;overflow
inc byte[KEY_COUNT] 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 align 4
.result: .result:

View File

@@ -11,7 +11,7 @@ $Revision$
include "skindata.inc" include "skindata.inc"
;skin_data = 0x00778000 ;skin_data = 0x00778000
;------------------------------------------------------------------------------ ;-----------------------------------------------------------------
align 4 align 4
read_skin_file: read_skin_file:
stdcall load_file, ebx stdcall load_file, ebx
@@ -121,7 +121,7 @@ parse_skin_data:
lea esi, [ebx+SKIN_PARAMS.dtp.data] lea esi, [ebx+SKIN_PARAMS.dtp.data]
mov edi, common_colours mov edi, common_colours
mov ecx, [ebx+SKIN_PARAMS.dtp.size] mov ecx, [ebx+SKIN_PARAMS.dtp.size]
and ecx, 127 and ecx, 255
rep movsb rep movsb
mov eax, dword[ebx+SKIN_PARAMS.margin.right] mov eax, dword[ebx+SKIN_PARAMS.margin.right]
mov dword[_skinmargins+0], eax mov dword[_skinmargins+0], eax

View File

@@ -9,7 +9,7 @@ $Revision$
; ;
; WINDOW SKIN DATA ; WINDOW SKIN DATA.
; ;
iglobal iglobal

View File

@@ -26,7 +26,7 @@ macro FuncTable name, table_name, [label]
} }
uglobal uglobal
common_colours rd 32 common_colours rd 48
draw_limits RECT draw_limits RECT
endg endg
@@ -34,7 +34,7 @@ align 4
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
syscall_draw_window: ;///// system function 0 ///////////////////////////////// syscall_draw_window: ;///// system function 0 /////////////////////////////////
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
;? <description> ;? <description>.
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
mov eax, edx mov eax, edx
shr eax, 24 shr eax, 24
@@ -173,7 +173,10 @@ align 4
syscall_display_settings.02: syscall_display_settings.02:
dec ebx dec ebx
mov esi, ecx mov esi, ecx
and edx, 127 cmp edx, 192
jnae @f
mov edx, 192 ; max size
@@:
mov edi, common_colours mov edi, common_colours
mov ecx, edx mov ecx, edx
rep movsb rep movsb
@@ -183,7 +186,10 @@ syscall_display_settings.02:
align 4 align 4
syscall_display_settings.03: syscall_display_settings.03:
mov edi, ecx mov edi, ecx
and edx, 127 cmp edx, 192
jnae @f
mov edx, 192 ; max size
@@:
mov esi, common_colours mov esi, common_colours
mov ecx, edx mov ecx, edx
rep movsb rep movsb
@@ -209,7 +215,7 @@ align 4
syscall_display_settings.06: syscall_display_settings.06:
xor esi, esi xor esi, esi
mov edi, [_display.width] mov edi, [Screen_Max_X]
mov eax, ecx mov eax, ecx
movsx ebx, ax movsx ebx, ax
sar eax, 16 sar eax, 16
@@ -233,7 +239,7 @@ align 4
;-------------------------------------- ;--------------------------------------
align 4 align 4
.check_horizontal: .check_horizontal:
mov edi, [_display.height] mov edi, [Screen_Max_Y]
mov eax, edx mov eax, edx
movsx ebx, ax movsx ebx, ax
sar eax, 16 sar eax, 16
@@ -294,8 +300,8 @@ align 4
syscall_display_settings._.calculate_whole_screen: syscall_display_settings._.calculate_whole_screen:
xor eax, eax xor eax, eax
xor ebx, ebx xor ebx, ebx
mov ecx, [_display.width] mov ecx, [Screen_Max_X]
mov edx, [_display.height] mov edx, [Screen_Max_Y]
jmp calculatescreen jmp calculatescreen
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
align 4 align 4
@@ -303,11 +309,9 @@ syscall_display_settings._.redraw_whole_screen:
xor eax, eax xor eax, eax
mov [draw_limits.left], eax mov [draw_limits.left], eax
mov [draw_limits.top], eax mov [draw_limits.top], eax
mov eax, [_display.width] mov eax, [Screen_Max_X]
dec eax
mov [draw_limits.right], eax mov [draw_limits.right], eax
mov eax, [_display.height] mov eax, [Screen_Max_Y]
dec eax
mov [draw_limits.bottom], eax mov [draw_limits.bottom], eax
mov eax, window_data mov eax, window_data
jmp redrawscreen jmp redrawscreen
@@ -586,9 +590,9 @@ align 4
mov eax, [edi + WDATA.box.left] mov eax, [edi + WDATA.box.left]
add eax, [edi + WDATA.box.width] add eax, [edi + WDATA.box.width]
mov ebx, [_display.width] mov ebx, [Screen_Max_X]
cmp eax, ebx cmp eax, ebx
jl .fix_vertical jle .fix_vertical
mov eax, [edi + WDATA.box.width] mov eax, [edi + WDATA.box.width]
sub eax, ebx sub eax, ebx
jle @f jle @f
@@ -603,9 +607,9 @@ align 4
.fix_vertical: .fix_vertical:
mov eax, [edi + WDATA.box.top] mov eax, [edi + WDATA.box.top]
add eax, [edi + WDATA.box.height] add eax, [edi + WDATA.box.height]
mov ebx, [_display.height] mov ebx, [Screen_Max_Y]
cmp eax, ebx cmp eax, ebx
jl .fix_client_box jle .fix_client_box
mov eax, [edi + WDATA.box.height] mov eax, [edi + WDATA.box.height]
sub eax, ebx sub eax, ebx
jle @f jle @f
@@ -819,12 +823,8 @@ drawwindow_I: ;////////////////////////////////////////////////////////////////
jnz .exit jnz .exit
; does client area have a positive size on screen? ; does client area have a positive size on screen?
mov edx, [esi + WDATA.box.top] cmp [esi + WDATA.box.height], 21
add edx, 21 + 5 jle .exit
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
; okay, let's draw it ; okay, let's draw it
mov eax, 1 mov eax, 1
@@ -1718,9 +1718,9 @@ window._.check_window_position: ;//////////////////////////////////////////////
mov ecx, [edi + WDATA.box.width] mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height] mov edx, [edi + WDATA.box.height]
mov esi, [_display.width] mov esi, [Screen_Max_X]
cmp ecx, esi cmp ecx, esi
jae .fix_width_high ja .fix_width_high
;-------------------------------------- ;--------------------------------------
align 4 align 4
.check_left: .check_left:
@@ -1732,9 +1732,9 @@ align 4
;-------------------------------------- ;--------------------------------------
align 4 align 4
.check_height: .check_height:
mov esi, [_display.height] mov esi, [Screen_Max_Y]
cmp edx, esi cmp edx, esi
jae .fix_height_high ja .fix_height_high
;-------------------------------------- ;--------------------------------------
align 4 align 4
.check_top: .check_top:
@@ -1992,7 +1992,7 @@ align 4
sub ebp, [ff_xsz] sub ebp, [ff_xsz]
add ebp, [ff_x] add ebp, [ff_x]
add ebp, [_display.width] ; screen.x add ebp, [Screen_Max_X] ; screen.x
inc ebp inc ebp
inc ebx inc ebx
cmp ebx, [ff_ysz] cmp ebx, [ff_ysz]

View File

@@ -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 ;; ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -25,8 +25,6 @@ VKEY_CONTROL = 0000000000001100b
VKEY_ALT = 0000000000110000b VKEY_ALT = 0000000000110000b
uglobal uglobal
align 4
kb_state dd 0
ext_code db 0 ext_code db 0
keyboard_mode db 0 keyboard_mode db 0
@@ -35,7 +33,6 @@ uglobal
altmouseb db 0 altmouseb db 0
ctrl_alt_del db 0 ctrl_alt_del db 0
kb_lights db 0
old_kb_lights db 0 old_kb_lights db 0
align 4 align 4
@@ -45,6 +42,13 @@ align 4
endg endg
iglobal iglobal
kb_lights db 2
align 4
kb_state dd VKEY_NUMLOCK
endg
iglobal
align 4
hotkey_tests dd hotkey_test0 hotkey_tests dd hotkey_test0
dd hotkey_test1 dd hotkey_test1
dd hotkey_test2 dd hotkey_test2
@@ -457,19 +461,40 @@ send_scancode:
test bl, bl test bl, bl
jz .exit.irq1 jz .exit.irq1
cmp cl, 0xE0 ; extended keycode
jne @f
cmp ch, 53
jne .dowrite
mov bl, '/'
jmp .dowrite
@@:
cmp ch, 55
jne @f
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 test [kb_state], VKEY_NUMLOCK
jz .dowrite jz .dowrite
cmp cl, 0xE0
jz .dowrite
cmp ch, 55
jnz @f
mov bl, 0x2A ;*
jmp .dowrite
;--------------------------------------
@@:
cmp ch, 71 cmp ch, 71
jb .dowrite jb .dowrite
@@ -488,7 +513,19 @@ send_scancode:
jae .exit.irq1 jae .exit.irq1
inc eax inc eax
mov [KEY_COUNT], al 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: .exit.irq1:
ret ret
;--------------------------------------------------------------------- ;---------------------------------------------------------------------
@@ -518,9 +555,9 @@ set_lights:
ps2_set_lights: ps2_set_lights:
stdcall disable_irq, 1 stdcall disable_irq, 1
mov al, 0xED mov al, 0xED
call kb_write call kb_write_wait_ack
mov al, [esp+8] mov al, [esp+8]
call kb_write call kb_write_wait_ack
stdcall enable_irq, 1 stdcall enable_irq, 1
ret 8 ret 8

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -24,16 +24,12 @@ $Revision$
uglobal uglobal
;-------------------------------------- ;--------------------------------------
align 4 align 4
mousecount dd 0x0 mousecount dd ?
mousedata dd 0x0 mousedata dd ?
Y_UNDER_sub_CUR_hot_y_add_curh: Y_UNDER_sub_CUR_hot_y_add_curh dw ?
dw 0 Y_UNDER_subtraction_CUR_hot_y dw ?
Y_UNDER_subtraction_CUR_hot_y: X_UNDER_sub_CUR_hot_x_add_curh dw ?
dw 0 X_UNDER_subtraction_CUR_hot_x dw ?
X_UNDER_sub_CUR_hot_x_add_curh:
dw 0
X_UNDER_subtraction_CUR_hot_x:
dw 0
endg endg
iglobal iglobal
@@ -44,9 +40,12 @@ mouse_speed_factor:
dd 3 dd 3
mouse_timer_ticks dd 0 mouse_timer_ticks dd 0
endg endg
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
draw_mouse_under: draw_mouse_under:
; return old picture ; return old picture
cmp [_display.restore_cursor], 0 cmp [_display.restore_cursor], 0
je @F je @F
@@ -57,15 +56,13 @@ draw_mouse_under:
stdcall [_display.restore_cursor], eax, ebx stdcall [_display.restore_cursor], eax, ebx
popad popad
ret ret
;--------------------------------------
align 4 @@:
@@:
pushad pushad
xor ecx, ecx xor ecx, ecx
xor edx, edx xor edx, edx
;--------------------------------------
align 4 mres:
mres:
movzx eax, word [X_UNDER] movzx eax, word [X_UNDER]
movzx ebx, word [Y_UNDER] movzx ebx, word [Y_UNDER]
add eax, ecx add eax, ecx
@@ -97,7 +94,9 @@ mres:
jnz mres jnz mres
popad popad
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
save_draw_mouse: save_draw_mouse:
cmp [_display.move_cursor], 0 cmp [_display.move_cursor], 0
@@ -111,6 +110,9 @@ save_draw_mouse:
push eax push eax
push ebx push ebx
; mov ecx, [Screen_Max_X]
; inc ecx
; mul ecx
mov eax, [d_width_calc_area + eax*4] mov eax, [d_width_calc_area + eax*4]
add eax, [_WinMapAddress] add eax, [_WinMapAddress]
@@ -170,11 +172,13 @@ drm:
push edx push edx
; helloworld ; helloworld
push ecx push ecx
add eax, ecx; save picture under mouse add eax, ecx ; save picture under mouse
add ebx, edx add ebx, edx
push ecx push ecx
or ecx, 0x04000000 ; don't load to mouseunder area 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 mov [COLOR_TEMP], ecx
pop ecx pop ecx
mov eax, edx mov eax, edx
@@ -226,7 +230,9 @@ drm:
add esp, 8 add esp, 8
popad popad
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
combine_colors: combine_colors:
; in ; in
@@ -241,7 +247,7 @@ combine_colors:
push edx push edx
push ecx push ecx
xor ecx, ecx xor ecx, ecx
; byte 2 ; byte 0
mov eax, 0xff mov eax, 0xff
sub al, [esi+0] sub al, [esi+0]
mov ebx, [esp] mov ebx, [esp]
@@ -295,7 +301,9 @@ combine_colors:
pop ebx pop ebx
pop eax pop eax
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
check_mouse_area_for_getpixel: check_mouse_area_for_getpixel:
; in: ; in:
@@ -314,18 +322,18 @@ check_mouse_area_for_getpixel:
cmp ebx, ecx cmp ebx, ecx
ja .no_mouse_area ja .no_mouse_area
; offset Y ; offset Y
sub bx, [Y_UNDER] ;[MOUSE_Y] sub bx, [Y_UNDER] ; [MOUSE_Y]
;-------------------------------------- ;--------------------------------------
; check for X ; check for X
xor ecx, ecx xor ecx, ecx
mov cx, [X_UNDER] ;[MOUSE_X] mov cx, [X_UNDER] ; [MOUSE_X]
cmp eax, ecx cmp eax, ecx
jb .no_mouse_area jb .no_mouse_area
add ecx, 15 ; mouse cursor X size add ecx, 15 ; mouse cursor X size
cmp eax, ecx cmp eax, ecx
ja .no_mouse_area ja .no_mouse_area
; offset X ; offset X
sub ax, [X_UNDER] ;[MOUSE_X] sub ax, [X_UNDER] ; [MOUSE_X]
;-------------------------------------- ;--------------------------------------
; eax = offset x ; eax = offset x
; ebx = offset y ; ebx = offset y
@@ -338,13 +346,14 @@ check_mouse_area_for_getpixel:
or ecx, 0xff000000 or ecx, 0xff000000
pop ebx eax pop ebx eax
ret ret
;--------------------------------------
align 4 .no_mouse_area:
.no_mouse_area:
xor ecx, ecx xor ecx, ecx
pop ebx eax pop ebx eax
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
check_mouse_area_for_putpixel: check_mouse_area_for_putpixel:
; in: ; in:
@@ -361,12 +370,12 @@ check_mouse_area_for_putpixel:
cmp cx, ax cmp cx, ax
ja .no_mouse_area ja .no_mouse_area
; offset Y ; offset Y
sub cx, [Y_UNDER] ;[MOUSE_Y] sub cx, [Y_UNDER] ; [MOUSE_Y]
mov ax, cx mov ax, cx
shl eax, 16 shl eax, 16
;--------------------------------------
; check for X ; check for X
mov ax, [X_UNDER] ;[MOUSE_X] mov ax, [X_UNDER] ; [MOUSE_X]
shr ecx, 16 shr ecx, 16
cmp cx, ax cmp cx, ax
jb .no_mouse_area jb .no_mouse_area
@@ -374,9 +383,9 @@ check_mouse_area_for_putpixel:
cmp cx, ax cmp cx, ax
ja .no_mouse_area ja .no_mouse_area
; offset X ; offset X
sub cx, [X_UNDER] ;[MOUSE_X] sub cx, [X_UNDER] ; [MOUSE_X]
mov ax, cx mov ax, cx
;--------------------------------------
; eax = (offset y) shl 16 + (offset x) ; eax = (offset y) shl 16 + (offset x)
pop ecx pop ecx
@@ -384,8 +393,8 @@ check_mouse_area_for_putpixel:
push eax ebx push eax ebx
mov ebx, eax mov ebx, eax
shr ebx, 16 ;y shr ebx, 16 ; y
and eax, 0xffff ;x and eax, 0xffff ; x
shl ebx, 6 shl ebx, 6
shl eax, 2 shl eax, 2
@@ -408,17 +417,15 @@ check_mouse_area_for_putpixel:
add esi, 16*24*3 add esi, 16*24*3
call combine_colors call combine_colors
pop edi esi pop edi esi
;--------------------------------------
align 4
.end:
mov eax, ecx mov eax, ecx
ret ret
;--------------------------------------
align 4 .no_mouse_area:
.no_mouse_area:
pop eax pop eax
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
__sys_draw_pointer: __sys_draw_pointer:
pushad pushad
@@ -430,14 +437,14 @@ __sys_draw_pointer:
je @f je @f
mov [redrawmouse_unconditional], 0 mov [redrawmouse_unconditional], 0
jmp redrawmouse jmp redrawmouse
;-------------------------------------- @@:
align 4
@@:
cmp eax, ecx cmp eax, ecx
jne redrawmouse jne redrawmouse
cmp ebx, edx cmp ebx, edx
je nodmp je nodmp
;-------------------------------------- ;--------------------------------------
align 4 align 4
redrawmouse: redrawmouse:
pushfd pushfd
@@ -465,62 +472,62 @@ redrawmouse:
mov [X_UNDER_subtraction_CUR_hot_x], ax mov [X_UNDER_subtraction_CUR_hot_x], ax
add eax, [cur.w] add eax, [cur.w]
mov [X_UNDER_sub_CUR_hot_x_add_curh], ax mov [X_UNDER_sub_CUR_hot_x_add_curh], ax
;-------------------------------------- @@:
align 4
@@:
popfd popfd
;-------------------------------------- nodmp:
align 4
nodmp:
popad popad
ret ret
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 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] mov eax, [BtnState]
and eax, 0x3FFFFFFF ; Top 2 bits are used to flag absolute movements
mov [BTN_DOWN], eax mov [BTN_DOWN], eax
;--------------------------------------
mov eax, [XMoving] mov eax, [XMoving]
test [BtnState], 0x80000000
jnz .absolute_x
call mouse_acceleration call mouse_acceleration
add ax, [MOUSE_X];[XCoordinate] add ax, [MOUSE_X]
cmp ax, 0 cmp ax, 0
jge @@M1 jge .check_x
mov eax, 0 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] mov eax, [YMoving]
test [BtnState], 0x40000000
jnz .absolute_y
neg eax neg eax
call mouse_acceleration call mouse_acceleration
add ax, [MOUSE_Y]
add ax, [MOUSE_Y];[YCoordinate]
cmp ax, 0 cmp ax, 0
jge @@M3 jge .check_y
mov ax, 0 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] mov eax, [VScroll]
add [MOUSE_SCROLL_V], ax add [MOUSE_SCROLL_V], ax
@@ -533,7 +540,9 @@ align 4
call wakeup_osloop call wakeup_osloop
ret ret
endp endp
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
align 4 align 4
mouse_acceleration: mouse_acceleration:
push eax push eax
@@ -545,8 +554,5 @@ mouse_acceleration:
;push edx ;push edx
imul eax, [mouse_speed_factor] imul eax, [mouse_speed_factor]
;pop edx ;pop edx
;-------------------------------------- @@:
align 4
@@:
ret ret
;-----------------------------------------------------------------------------

View File

@@ -128,12 +128,12 @@ proc init_mem
mov [pg_data.kernel_tables-OS_BASE], edx mov [pg_data.kernel_tables-OS_BASE], edx
xor eax, eax xor eax, eax
mov edi, sys_pgdir-OS_BASE mov edi, sys_proc-OS_BASE
mov ecx, 4096/4 mov ecx, 8192/4
cld cld
rep stosd 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 bt [cpu_caps-OS_BASE], CAPS_PSE
jnc .no_PSE jnc .no_PSE
@@ -177,9 +177,9 @@ proc init_mem
dec ecx dec ecx
jnz .map_kernel_tabs 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)] lea esi, [edi+(OS_BASE shr 20)]
movsd movsd
movsd movsd
@@ -345,15 +345,13 @@ align 4
proc test_cpu proc test_cpu
locals locals
cpu_type dd ? cpu_type dd ?
cpu_id dd ?
cpu_Intel dd ?
cpu_AMD dd ?
endl endl
xor eax, eax xor eax, eax
mov [cpu_type], eax mov [cpu_type], eax
mov [cpu_caps-OS_BASE], eax mov [cpu_caps-OS_BASE], eax
mov [cpu_caps+4-OS_BASE], eax mov [cpu_caps+4-OS_BASE], eax
mov [cpu_phys_addr_width-OS_BASE], 32
pushfd pushfd
pop eax pop eax
@@ -378,7 +376,6 @@ proc test_cpu
pop eax pop eax
xor eax, ecx xor eax, ecx
je .end_cpuid je .end_cpuid
mov [cpu_id], 1
xor eax, eax xor eax, eax
cpuid cpuid
@@ -386,13 +383,7 @@ proc test_cpu
mov [cpu_vendor-OS_BASE], ebx mov [cpu_vendor-OS_BASE], ebx
mov [cpu_vendor+4-OS_BASE], edx mov [cpu_vendor+4-OS_BASE], edx
mov [cpu_vendor+8-OS_BASE], ecx 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 cmp eax, 1
jl .end_cpuid jl .end_cpuid
mov eax, 1 mov eax, 1
@@ -402,42 +393,26 @@ proc test_cpu
mov [cpu_caps-OS_BASE], edx mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx 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 shr eax, 8
and eax, 0x0f and eax, 0x0f
ret ret
.end_cpuid: .end_cpuid:
mov eax, [cpu_type] mov eax, [cpu_type]
ret 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 endp
iglobal iglobal

File diff suppressed because it is too large Load Diff

View File

@@ -98,17 +98,35 @@ struct DBG_REGS
dr7 dd ? dr7 dd ?
ends 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 struct APPDATA
app_name rb 11 app_name rb 11
rb 5 rb 5
fpu_state dd ? ;+16 list LHEAD ;+16
ev_count_ dd ? ;unused ;+20 process dd ? ;+24
exc_handler dd ? ;+24 fpu_state dd ? ;+28
except_mask dd ? ;+28 exc_handler dd ? ;+32
pl0_stack dd ? ;+32 except_mask dd ? ;+36
heap_base dd ? ;+36 pl0_stack dd ? ;+40
heap_top dd ? ;+40
cursor dd ? ;+44 cursor dd ? ;+44
fd_ev dd ? ;+48 fd_ev dd ? ;+48
bk_ev dd ? ;+52 bk_ev dd ? ;+52
@@ -124,7 +142,7 @@ struct APPDATA
wait_test dd ? ;+96 +++ wait_test dd ? ;+96 +++
wait_param dd ? ;+100 +++ wait_param dd ? ;+100 +++
tls_base dd ? ;+104 tls_base dd ? ;+104
dlls_list_ptr dd ? ;+108 dd ? ;+108
event_filter dd ? ;+112 event_filter dd ? ;+112
draw_bgr_x dd ? ;+116 draw_bgr_x dd ? ;+116
draw_bgr_y dd ? ;+120 draw_bgr_y dd ? ;+120
@@ -133,7 +151,7 @@ struct APPDATA
wnd_shape dd ? ;+128 wnd_shape dd ? ;+128
wnd_shape_scale dd ? ;+132 wnd_shape_scale dd ? ;+132
dd ? ;+136 dd ? ;+136
mem_size dd ? ;+140 dd ? ;+140
saved_box BOX ;+144 saved_box BOX ;+144
ipc_start dd ? ;+160 ipc_start dd ? ;+160
ipc_size dd ? ;+164 ipc_size dd ? ;+164
@@ -142,7 +160,7 @@ struct APPDATA
terminate_protection dd ? ;+176 terminate_protection dd ? ;+176
keyboard_mode db ? ;+180 keyboard_mode db ? ;+180
rb 3 rb 3
dir_table dd ? ;+184 dd ? ;+184
dbg_event_mem dd ? ;+188 dbg_event_mem dd ? ;+188
dbg_regs DBG_REGS ;+192 dbg_regs DBG_REGS ;+192
wnd_caption dd ? ;+212 wnd_caption dd ? ;+212
@@ -152,6 +170,36 @@ struct APPDATA
ends 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 ; Core functions
include "core/sync.inc" ; macros for synhronization objects 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/syscall.inc" ; system call
include "core/fpu.inc" ; all fpu/sse support include "core/fpu.inc" ; all fpu/sse support
include "core/memory.inc" include "core/memory.inc"
include "core/mtrr.inc"
include "core/heap.inc" ; kernel and app heap include "core/heap.inc" ; kernel and app heap
include "core/malloc.inc" ; small kernel heap include "core/malloc.inc" ; small kernel heap
include "core/taskman.inc" include "core/taskman.inc"
@@ -242,7 +291,6 @@ include "blkdev/bd_drv.inc"
; CD drive controller ; CD drive controller
include "blkdev/cdrom.inc"
include "blkdev/cd_drv.inc" include "blkdev/cd_drv.inc"
; Character devices ; Character devices

View File

@@ -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 ; Éste archivo debe ser editado con codificación CP866
version cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0 version cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0

View File

@@ -89,6 +89,12 @@ macro Mov op1,op2,op3 ; op1 = op2 = op3
mov op1, op2 mov op1, op2
} }
macro list_init head
{
mov [head+LHEAD.next], head
mov [head+LHEAD.prev], head
}
macro __list_add new, prev, next macro __list_add new, prev, next
{ {
mov [next+LHEAD.prev], new mov [next+LHEAD.prev], new
@@ -111,10 +117,10 @@ macro list_add_tail new, head
macro list_del entry macro list_del entry
{ {
mov edx, [entry+list_fd] mov edx, [entry+LHEAD.next]
mov ecx, [entry+list_bk] mov ecx, [entry+LHEAD.prev]
mov [edx+list_bk], ecx mov [edx+LHEAD.prev], ecx
mov [ecx+list_fd], edx mov [ecx+LHEAD.next], edx
} }
; MOV Immediate. ; MOV Immediate.

View File

@@ -1,11 +1,10 @@
FASM=fasm FASM=fasm
FLAGS=-m 65536 FLAGS=-m 65536
languages=en|ru|ge|et|sp languages=en|ru|ge|et|sp
drivers_src=com_mouse emu10k1x fm801 infinity sis sound vt823x
.PHONY: all kernel drivers bootloader clean .PHONY: all kernel bootloader clean
all: kernel drivers bootloader all: kernel bootloader
kernel: check_lang kernel: check_lang
@echo "*** building kernel with language '$(lang)' ..." @echo "*** building kernel with language '$(lang)' ..."
@@ -15,14 +14,6 @@ kernel: check_lang
@$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt @$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt
@rm -f lang.inc @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 bootloader: check_lang
@echo "*** building bootloader with language '$(lang)' ..." @echo "*** building bootloader with language '$(lang)' ..."
@mkdir -p bin @mkdir -p bin

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; ARP.INC ;; ;; 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",\ 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 [esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
lea eax, [ebx + ETH_DEVICE.mac] ; local device mac mov ax, ETHER_PROTO_ARP
mov edx, ETH_BROADCAST ; broadcast mac
mov ecx, sizeof.ARP_header mov ecx, sizeof.ARP_header
mov di, ETHER_PROTO_ARP mov edx, ETH_BROADCAST ; broadcast mac
call ETH_output call ETH_output
jz .exit jz .exit

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; IPv4.INC ;; ;; IPv4.INC ;;
@@ -267,10 +267,9 @@ IPv4_input: ; TODO: add IPv4
cmp eax, 224 cmp eax, 224
je .ip_ok 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 [IP_LIST + edi], 0
cmp eax, 127
je .ip_ok je .ip_ok
; or it's just not meant for us.. :( ; or it's just not meant for us.. :(
@@ -577,11 +576,11 @@ IPv4_find_fragment_slot:
; edx = Source IP ; edx = Source IP
; di = TTL shl 8 + protocol ; di = TTL shl 8 + protocol
; ;
; OUT: eax = pointer to buffer start ; OUT: eax = pointer to buffer start / 0 on error
; ebx = pointer to device struct (needed for sending procedure) ; ebx = device ptr (send packet through this device)
; ecx = unchanged (packet size of embedded data) ; ecx = data length
; edx = size of complete buffer ; edx = size of complete frame
; edi = pointer to start of data (0 on error) ; edi = start of IPv4 payload
; ;
;------------------------------------------------------------------ ;------------------------------------------------------------------
align 4 align 4
@@ -595,7 +594,6 @@ IPv4_output:
push ecx di eax push ecx di eax
call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
push edx push edx
test edi, edi test edi, edi
jz .loopback jz .loopback
@@ -607,12 +605,11 @@ IPv4_output:
inc [IPv4_packets_tx + edi] ; update stats inc [IPv4_packets_tx + edi] ; update stats
mov ax, ETHER_PROTO_IPv4
mov ebx, [NET_DRV_LIST + edi] mov ebx, [NET_DRV_LIST + edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6 + 8 + 2] mov ecx, [esp + 6 + 8 + 2]
add ecx, sizeof.IPv4_header add ecx, sizeof.IPv4_header
mov di, ETHER_PROTO_IPv4 mov edx, esp
call ETH_output call ETH_output
jz .eth_error jz .eth_error
add esp, 6 ; pop the mac out of the stack add esp, 6 ; pop the mac out of the stack
@@ -642,18 +639,18 @@ IPv4_output:
.eth_error: .eth_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ethernet error\n" DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ethernet error\n"
add esp, 3*4+2+6 add esp, 3*4+2+6
xor edi, edi xor eax, eax
ret ret
.arp_error: .arp_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
add esp, 3*4+2 add esp, 3*4+2
xor edi, edi xor eax, eax
ret ret
.too_large: .too_large:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: Packet too large!\n" DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: Packet too large!\n"
xor edi, edi xor eax, eax
ret ret
.loopback: .loopback:
@@ -675,7 +672,7 @@ IPv4_output:
; ecx = data length ; ecx = data length
; esi = data ptr ; esi = data ptr
; ;
; OUT: / ; OUT: eax = -1 on error
; ;
;------------------------------------------------------------------ ;------------------------------------------------------------------
align 4 align 4
@@ -699,15 +696,13 @@ IPv4_output_raw:
push ax push ax
inc [IPv4_packets_tx + 4*edi] inc [IPv4_packets_tx + 4*edi]
mov ax, ETHER_PROTO_IPv4
mov ebx, [NET_DRV_LIST + 4*edi] mov ebx, [NET_DRV_LIST + 4*edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6 + 4] mov ecx, [esp + 6 + 4]
add ecx, sizeof.IPv4_header add ecx, sizeof.IPv4_header
mov di, ETHER_PROTO_IPv4 mov edx, esp
call ETH_output call ETH_output
jz .error jz .error
add esp, 6 ; pop the mac add esp, 6 ; pop the mac
mov dword[esp+4+4], edx mov dword[esp+4+4], edx
@@ -746,7 +741,7 @@ IPv4_output_raw:
add esp, 8+4+4 add esp, 8+4+4
.too_large: .too_large:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n" DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n"
sub edi, edi or eax, -1
ret ret
@@ -795,13 +790,9 @@ IPv4_fragment:
.new_fragment: .new_fragment:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment" DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
mov ax, ETHER_PROTO_IPv4
mov eax, [esp + 3*4]
lea ebx, [esp + 4*4] lea ebx, [esp + 4*4]
mov di , ETHER_PROTO_IPv4
call ETH_output call ETH_output
cmp edi, -1
jz .err jz .err
; copy header ; copy header

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; PPPoE.INC ;; ;; PPPoE.INC ;;
@@ -14,6 +14,9 @@
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5015 $
struct PPPoE_frame struct PPPoE_frame
VersionAndType db ? VersionAndType db ?
Code db ? Code db ?
@@ -240,17 +243,15 @@ PPPoE_session_input:
; ;
; PPPoE_output ; PPPoE_output
; ;
; IN: ; IN: ax = protocol
; ebx = device ptr ; ebx = device ptr
; ecx = packet size ; ecx = packet size
; ;
; di = protocol ; OUT: eax = buffer start / 0 on error
; ; ebx = device ptr
; OUT: edi = 0 on error, pointer to buffer otherwise ; ecx = packet size
; eax = buffer start
; ebx = to device structure
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer ; edx = size of complete buffer
; edi = start of PPP payload
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
@@ -258,13 +259,12 @@ PPPoE_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: size=%u device=%x\n", ecx, ebx DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: size=%u device=%x\n", ecx, ebx
pushw di pushw ax
pushw [PPPoE_SID] pushw [PPPoE_SID]
lea eax, [ebx + ETH_DEVICE.mac] mov ax, ETHER_PROTO_PPP_SESSION
lea edx, [PPPoE_MAC]
add ecx, PPPoE_frame.Payload + 2 add ecx, PPPoE_frame.Payload + 2
mov di, ETHER_PROTO_PPP_SESSION lea edx, [PPPoE_MAC]
call ETH_output call ETH_output
jz .eth_error jz .eth_error
@@ -287,8 +287,7 @@ PPPoE_output:
.eth_error: .eth_error:
add esp, 4 add esp, 4
xor edi, edi xor eax, eax
ret ret

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; ETHERNET.INC ;; ;; ETHERNET.INC ;;
@@ -86,11 +86,7 @@ ETH_input:
push ebx push ebx
mov esi, esp mov esi, esp
pushf
cli
add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
popf
add esp, sizeof.ETH_queue_entry add esp, sizeof.ETH_queue_entry
xor edx, edx xor edx, edx
@@ -102,10 +98,9 @@ ETH_input:
ret ret
.fail: .fail:
popf DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
add esp, sizeof.ETH_queue_entry - 8 pop ebx
call NET_packet_free call NET_packet_free
add esp, 4 add esp, 4
@@ -150,14 +145,14 @@ ETH_process_input:
cmp ax, ETHER_PROTO_ARP cmp ax, ETHER_PROTO_ARP
je ARP_input je ARP_input
cmp ax, ETHER_PROTO_IPv6 ; cmp ax, ETHER_PROTO_IPv6
je IPv6_input ; je IPv6_input
cmp ax, ETHER_PROTO_PPP_DISCOVERY ; cmp ax, ETHER_PROTO_PPP_DISCOVERY
je PPPoE_discovery_input ; je PPPoE_discovery_input
cmp ax, ETHER_PROTO_PPP_SESSION ; cmp ax, ETHER_PROTO_PPP_SESSION
je PPPoE_session_input ; je PPPoE_session_input
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
@@ -171,17 +166,16 @@ ETH_process_input:
; ;
; ETH_output ; ETH_output
; ;
; IN: eax = pointer to source mac ; IN: ax = protocol
; ebx = device ptr ; ebx = device ptr
; ecx = packet size ; ecx = payload size
; edx = pointer to destination mac ; edx = pointer to destination mac
; di = protocol
; ;
; OUT: edi = 0 on error, pointer to buffer otherwise ; OUT: eax = start of ethernet frame / 0 on error
; eax = buffer start ; ebx = device ptr
; ebx = to device structure ; ecx = payload size
; ecx = unchanged (packet size of embedded data) ; edx = ethernet frame size
; edx = size of complete buffer ; edi = start of ethernet payload
; ;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4
@@ -189,11 +183,11 @@ ETH_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx 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 ja .exit
push ecx push ecx
push di eax edx push ax edx
add ecx, sizeof.ETH_header add ecx, sizeof.ETH_header
stdcall kernel_alloc, ecx stdcall kernel_alloc, ecx
@@ -204,7 +198,7 @@ ETH_output:
pop esi pop esi
movsd movsd
movsw movsw
pop esi lea esi, [ebx + ETH_DEVICE.mac]
movsd movsd
movsw movsw
pop ax pop ax
@@ -227,13 +221,13 @@ ETH_output:
.out_of_ram: .out_of_ram:
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n" DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
add esp, 4+4+2+4 add esp, 4+2+4
sub edi, edi xor eax, eax
ret ret
.exit: .exit:
DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n" DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
sub edi, edi xor eax, eax
ret ret

View File

@@ -294,12 +294,12 @@ ICMP_input:
call mutex_unlock call mutex_unlock
popa popa
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: no socket found\n" DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
jmp .dump jmp .dump
.checksum_mismatch: .checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n" DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
.dump: .dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"

View File

@@ -28,7 +28,6 @@ struct queue
size dd ? ; number of queued packets in this queue size dd ? ; number of queued packets in this queue
w_ptr dd ? ; current writing pointer in queue w_ptr dd ? ; current writing pointer in queue
r_ptr dd ? ; current reading pointer r_ptr dd ? ; current reading pointer
mutex MUTEX
ends ends
@@ -47,18 +46,12 @@ macro add_to_queue ptr, size, entry_size, failaddr {
local .ok, .no_wrap local .ok, .no_wrap
pusha spin_lock_irqsave
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
cmp [ptr + queue.size], size ; Check if queue isnt full cmp [ptr + queue.size], size ; Check if queue isnt full
jb .ok jb .ok
pusha spin_unlock_irqrestore
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr jmp failaddr
.ok: .ok:
@@ -76,10 +69,7 @@ local .ok, .no_wrap
.no_wrap: .no_wrap:
mov [ptr + queue.w_ptr], edi mov [ptr + queue.w_ptr], edi
pusha spin_unlock_irqrestore
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
} }
@@ -89,18 +79,12 @@ macro get_from_queue ptr, size, entry_size, failaddr {
local .ok, .no_wrap local .ok, .no_wrap
pusha spin_lock_irqsave
lea ecx, [ptr + queue.mutex]
call mutex_lock
popa
cmp [ptr + queue.size], 0 ; any packets queued? cmp [ptr + queue.size], 0 ; any packets queued?
ja .ok ja .ok
pusha spin_unlock_irqrestore
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
jmp failaddr jmp failaddr
.ok: .ok:
@@ -122,10 +106,7 @@ local .ok, .no_wrap
pop esi pop esi
pusha spin_unlock_irqrestore
lea ecx, [ptr + queue.mutex]
call mutex_unlock
popa
} }
@@ -136,6 +117,4 @@ macro init_queue ptr {
mov [ptr + queue.w_ptr], edi mov [ptr + queue.w_ptr], edi
mov [ptr + queue.r_ptr], edi mov [ptr + queue.r_ptr], edi
lea ecx, [ptr + queue.mutex]
call mutex_init
} }

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;; ;; Part of the TCP/IP network stack for KolibriOS ;;
@@ -293,6 +293,7 @@ SOCKET_open:
push ecx edx esi push ecx edx esi
call SOCKET_alloc call SOCKET_alloc
pop esi edx ecx pop esi edx ecx
test eax, eax
jz .nobuffs jz .nobuffs
mov [esp+32], edi ; return socketnumber 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? test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state?
jz @f jz @f
call SOCKET_notify.unblock ; Unblock it. call SOCKET_notify ; Unblock it.
@@: @@:
cmp [eax + SOCKET.Domain], AF_INET4 cmp [eax + SOCKET.Domain], AF_INET4
@@ -1192,6 +1193,7 @@ SOCKET_pair:
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n"
call SOCKET_alloc call SOCKET_alloc
test eax, eax
jz .nomem1 jz .nomem1
mov [esp+32], edi ; application's eax mov [esp+32], edi ; application's eax
@@ -1204,6 +1206,7 @@ SOCKET_pair:
mov ebx, eax mov ebx, eax
call SOCKET_alloc call SOCKET_alloc
test eax, eax
jz .nomem2 jz .nomem2
mov [esp+20], edi ; application's ebx mov [esp+20], edi ; application's ebx
@@ -1220,10 +1223,13 @@ SOCKET_pair:
lea eax, [eax + STREAM_SOCKET.rcv] lea eax, [eax + STREAM_SOCKET.rcv]
call SOCKET_ring_create call SOCKET_ring_create
test eax, eax
jz .nomem1
lea eax, [ebx + STREAM_SOCKET.rcv] lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create call SOCKET_ring_create
pop eax test eax, eax
jz .nomem2
ret 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 align 4
SOCKET_ring_create: SOCKET_ring_create:
@@ -1476,6 +1483,8 @@ SOCKET_ring_create:
push edx push edx
stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
pop edx pop edx
test eax, eax
jz .fail
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax
@@ -1493,6 +1502,7 @@ SOCKET_ring_create:
mov eax, esi mov eax, esi
pop esi pop esi
.fail:
ret ret
;----------------------------------------------------------------- ;-----------------------------------------------------------------
@@ -1536,6 +1546,7 @@ SOCKET_ring_write:
jb @f jb @f
sub edi, SOCKET_MAXDATA ; WRAP sub edi, SOCKET_MAXDATA ; WRAP
@@: @@:
mov [eax + RING_BUFFER.write_ptr], edi mov [eax + RING_BUFFER.write_ptr], edi
pop edi pop edi
@@ -1707,8 +1718,9 @@ SOCKET_block:
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
pushf
push eax push eax
pushf
cli cli
; Set the 'socket is blocked' flag ; Set the 'socket is blocked' flag
@@ -1724,12 +1736,12 @@ SOCKET_block:
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx
mov [eax + SOCKET.TID], edx mov [eax + SOCKET.TID], edx
pop edx pop edx
popf
call change_task call change_task
pop eax pop eax
popf
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continuing\n"
ret ret
@@ -1752,70 +1764,54 @@ SOCKET_notify:
call SOCKET_check call SOCKET_check
jz .error jz .error
test [eax + SOCKET.state], SS_BLOCKED ; Find the associated thread's TASK_DATA
jnz .unblock push ebx ecx esi
mov ebx, [eax + SOCKET.TID]
; test [eax + SOCKET.options], SO_NONBLOCK test ebx, ebx
; jz .error jz .error2
push eax ecx esi
; socket exists and is of non blocking type.
; We'll try to flag an event to the thread
mov eax, [eax + SOCKET.TID]
test eax, eax
jz .done
mov ecx, 1
mov esi, TASK_DATA + TASKDATA.pid
.next_pid:
cmp [esi], eax
je .found_pid
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
; PID not found, TODO: close socket!
jmp .done
.found_pid:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax
jmp .done
.unblock:
push eax ecx esi
; Clear the 'socket is blocked' flag
and [eax + SOCKET.state], not SS_BLOCKED
; Find the thread's TASK_DATA
mov eax, [eax + SOCKET.TID]
test eax, eax
jz .error
xor ecx, ecx xor ecx, ecx
inc ecx inc ecx
mov esi, TASK_DATA mov esi, TASK_DATA
.next: .next:
cmp [esi + TASKDATA.pid], eax cmp [esi + TASKDATA.pid], ebx
je .found je .found
inc ecx inc ecx
add esi, 0x20 add esi, 0x20
cmp ecx, [TASK_COUNT] cmp ecx, [TASK_COUNT]
jbe .next jbe .next
jmp .error
.found:
; Run the thread .error2:
mov [esi + TASKDATA.state], 0 ; Running ; PID not found, TODO: close socket!
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n" DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: error finding thread 0x%x !\n", ebx
pop esi ecx ebx
.done: ret
pop esi ecx eax
.error: .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 ret
@@ -1830,7 +1826,6 @@ SOCKET_notify:
; IN: / ; IN: /
; OUT: eax = 0 on error, socket ptr otherwise ; OUT: eax = 0 on error, socket ptr otherwise
; edi = socket number ; edi = socket number
; ZF = cleared on error
; ;
;-------------------------------------------------------------------- ;--------------------------------------------------------------------
align 4 align 4
@@ -1917,7 +1912,6 @@ SOCKET_alloc:
@@: @@:
mov [net_sockets + SOCKET.NextPtr], eax mov [net_sockets + SOCKET.NextPtr], eax
or eax, eax ; used to clear zero flag
pusha pusha
mov ecx, socket_mutex mov ecx, socket_mutex
@@ -1968,8 +1962,14 @@ SOCKET_free:
jnz .no_tcp jnz .no_tcp
mov ebx, eax mov ebx, eax
cmp [ebx + STREAM_SOCKET.rcv.start_ptr], 0
je @f
stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] 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] stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
@@:
mov eax, ebx mov eax, ebx
.no_tcp: .no_tcp:
@@ -2022,6 +2022,7 @@ SOCKET_fork:
push ebx push ebx
call SOCKET_alloc call SOCKET_alloc
pop ebx pop ebx
test eax, eax
jz .fail jz .fail
push eax push eax
@@ -2101,7 +2102,8 @@ SOCKET_num_to_ptr:
call mutex_unlock call mutex_unlock
popa 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 ret
@@ -2210,6 +2212,8 @@ SOCKET_check_owner:
align 4 align 4
SOCKET_process_end: SOCKET_process_end:
ret ; FIXME
cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all? cmp [net_sockets + SOCKET.NextPtr], 0 ; Are there any active sockets at all?
je .quickret ; nope, exit immediately je .quickret ; nope, exit immediately

View File

@@ -110,7 +110,7 @@ SS_MORETOCOME = 0x4000
SS_BLOCKED = 0x8000 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 MAX_backlog = 20 ; maximum backlog for stream sockets
; Error Codes ; Error Codes
@@ -313,10 +313,15 @@ stack_handler:
test [net_10ms], 0x3f ; 640ms test [net_10ms], 0x3f ; 640ms
jnz .exit jnz .exit
TCP_timer_640ms
ARP_decrease_entry_ttls ARP_decrease_entry_ttls
IPv4_decrease_fragment_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: .exit:
ret ret

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;; ;; 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_NEEDOUTPUT = 1 shl 0
TCP_BIT_TIMESTAMP = 1 shl 1 TCP_BIT_TIMESTAMP = 1 shl 1
TCP_BIT_DROPSOCKET = 1 shl 2 TCP_BIT_DROPSOCKET = 1 shl 2
TCP_BIT_FIN_IS_ACKED = 1 shl 3
TCP_BIT_SENDALOT = 1 shl 0 TCP_BIT_SENDALOT = 1 shl 0
@@ -141,6 +142,7 @@ align 4
TCP_sequence_num dd ? TCP_sequence_num dd ?
TCP_queue rd (TCP_QUEUE_SIZE*sizeof.TCP_queue_entry + sizeof.queue)/4 TCP_queue rd (TCP_QUEUE_SIZE*sizeof.TCP_queue_entry + sizeof.queue)/4
TCP_input_event dd ? TCP_input_event dd ?
TCP_timer1_event dd ?
endg endg
uglobal uglobal
@@ -224,7 +226,15 @@ macro TCP_init {
call new_sys_threads call new_sys_threads
test eax, eax test eax, eax
jns @f 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 jz .packets_missed ; 2
dec bl dec bl
jz .packets_dumped ; 3 jz .packets_dumped ; 3
dec bl
jz .packets_queued ; 4
.error: .error:
mov eax, -1 mov eax, -1
@@ -284,3 +296,7 @@ TCP_api:
.packets_dumped: .packets_dumped:
mov eax, [TCP_segments_dumped + eax] mov eax, [TCP_segments_dumped + eax]
ret ret
.packets_queued:
mov eax, [TCP_queue + queue.size]
ret

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;; ;; Part of the TCP/IP network stack for KolibriOS ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;; ;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; Based on the code of 4.4BSD ;; ;; Based on the algorithms used in 4.4BSD ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; Version 2, June 1991 ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 3407 $ $Revision: 5155 $
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
@@ -43,11 +43,7 @@ TCP_input:
push ebx ecx esi edi ; mind the order push ebx ecx esi edi ; mind the order
mov esi, esp mov esi, esp
pushf
cli
add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail
popf
add esp, sizeof.TCP_queue_entry add esp, sizeof.TCP_queue_entry
call NET_ptr_to_num4 call NET_ptr_to_num4
@@ -62,7 +58,6 @@ TCP_input:
ret ret
.fail: .fail:
popf
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
call NET_ptr_to_num4 call NET_ptr_to_num4
@@ -536,11 +531,9 @@ endl
cmp eax, [ebx + TCP_SOCKET.SND_UNA] cmp eax, [ebx + TCP_SOCKET.SND_UNA]
jne .not_uni_xfer jne .not_uni_xfer
; - The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp). ; - The reassembly list of out-of-order segments for the connection is empty.
cmp [ebx + TCP_SOCKET.seg_next], 0
;;; TODO jne .not_uni_xfer
; jnz .not_uni_xfer
; Complete processing of received data ; Complete processing of received data
@@ -845,7 +838,7 @@ endl
pop word [ebx + TCP_SOCKET.SND_SCALE] pop word [ebx + TCP_SOCKET.SND_SCALE]
@@: @@:
;;; TODO: call TCP_reassemble call TCP_reassemble
mov eax, [edx + TCP_header.SequenceNumber] mov eax, [edx + TCP_header.SequenceNumber]
dec eax dec eax
@@ -1099,8 +1092,7 @@ endl
pop ebx edx ecx pop ebx edx ecx
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is acked\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is acked\n"
stc or [temp_bits], TCP_BIT_FIN_IS_ACKED
jmp .wakeup jmp .wakeup
.finiacked: .finiacked:
@@ -1114,19 +1106,15 @@ endl
pop edx ecx pop edx ecx
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is not acked\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is not acked\n"
clc
;---------------------------------------- ;----------------------------------------
; Wake up process waiting on send buffer ; Wake up process waiting on send buffer
.wakeup: .wakeup:
pushf ; Keep the flags (Carry flag)
mov eax, ebx mov eax, ebx
call SOCKET_notify call SOCKET_notify
; Update TCPS ; Update TCPS
mov eax, [edx + TCP_header.AckNumber] mov eax, [edx + TCP_header.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax mov [ebx + TCP_SOCKET.SND_UNA], eax
cmp eax, [ebx + TCP_SOCKET.SND_NXT] cmp eax, [ebx + TCP_SOCKET.SND_NXT]
@@ -1134,8 +1122,6 @@ endl
mov [ebx + TCP_SOCKET.SND_NXT], eax mov [ebx + TCP_SOCKET.SND_NXT], eax
@@: @@:
popf
; General ACK handling complete ; General ACK handling complete
; Now do the state-specific ones ; Now do the state-specific ones
; Carry flag is set when our FIN is acked ; Carry flag is set when our FIN is acked
@@ -1158,7 +1144,8 @@ endl
.ack_fw1: .ack_fw1:
jnc .ack_processed test [temp_bits], TCP_BIT_FIN_IS_ACKED
jz .ack_processed
test [ebx + SOCKET.state], SS_CANTRCVMORE test [ebx + SOCKET.state], SS_CANTRCVMORE
jnz @f jnz @f
@@ -1171,7 +1158,8 @@ endl
jmp .ack_processed jmp .ack_processed
.ack_c: .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 [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
mov eax, ebx mov eax, ebx
@@ -1183,7 +1171,8 @@ endl
jmp .ack_processed jmp .ack_processed
.ack_la: .ack_la:
jnc .ack_processed test [temp_bits], TCP_BIT_FIN_IS_ACKED
jz .ack_processed
push ebx push ebx
lea ecx, [ebx + SOCKET.mutex] lea ecx, [ebx + SOCKET.mutex]
@@ -1246,9 +1235,13 @@ align 4
lea eax, [ebx + STREAM_SOCKET.snd] lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create call SOCKET_ring_create
test eax, eax
jz .drop
lea eax, [ebx + STREAM_SOCKET.rcv] lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create call SOCKET_ring_create
test eax, eax
jz .drop
and [temp_bits], not TCP_BIT_DROPSOCKET and [temp_bits], not TCP_BIT_DROPSOCKET
@@ -1257,7 +1250,7 @@ align 4
call SOCKET_notify call SOCKET_notify
popa popa
jmp .trim_then_step6 jmp .trim
;------------ ;------------
; Active Open ; Active Open
@@ -1350,9 +1343,9 @@ align 4
mov eax, [ebx + TCP_SOCKET.t_rtt] mov eax, [ebx + TCP_SOCKET.t_rtt]
test eax, eax test eax, eax
je .trim_then_step6 je .trim
call TCP_xmit_timer call TCP_xmit_timer
jmp .trim_then_step6 jmp .trim
.simultaneous_open: .simultaneous_open:
@@ -1363,8 +1356,7 @@ align 4
;------------------------------------- ;-------------------------------------
; Common processing for receipt of SYN ; Common processing for receipt of SYN
.trim_then_step6: .trim:
inc [edx + TCP_header.SequenceNumber] inc [edx + TCP_header.SequenceNumber]
; Drop any received data that doesnt fit in the receive window. ; Drop any received data that doesnt fit in the receive window.
@@ -1377,17 +1369,12 @@ align 4
;;; TODO: update stats ;;; TODO: update stats
.dont_trim: .dont_trim:
mov eax, [edx + TCP_header.SequenceNumber] mov eax, [edx + TCP_header.SequenceNumber]
mov [ebx + TCP_SOCKET.RCV_UP], eax mov [ebx + TCP_SOCKET.RCV_UP], eax
dec eax dec eax
mov [ebx + TCP_SOCKET.SND_WL1], eax mov [ebx + TCP_SOCKET.SND_WL1], eax
;-------
; step 6
.ack_processed: .ack_processed:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK processed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK processed\n"
;---------------------------------------------- ;----------------------------------------------
@@ -1592,14 +1579,14 @@ align 4
jnz .need_output jnz .need_output
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW test [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jz .dumpit jz .done
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n"
.need_output: .need_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n"
call TCP_output call TCP_output
.dumpit: .done:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
call NET_packet_free call NET_packet_free
@@ -1619,7 +1606,7 @@ align 4
pop eax edx pop eax edx
test [edx + TCP_header.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jnz .dumpit jnz .done
or [eax + TCP_SOCKET.t_flags], TF_ACKNOW or [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jmp .need_output jmp .need_output
@@ -1633,7 +1620,7 @@ align 4
pop edx ebx pop edx ebx
test [edx + TCP_header.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jnz .dumpit jnz .done
;;; if its a multicast/broadcast, also drop ;;; if its a multicast/broadcast, also drop
@@ -1642,7 +1629,7 @@ align 4
test [edx + TCP_header.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jnz .respond_syn jnz .respond_syn
jmp .dumpit jmp .done
;--------- ;---------
; Respond ; Respond
@@ -1661,8 +1648,10 @@ align 4
pop ebx pop ebx
jmp .destroy_new_socket jmp .destroy_new_socket
.no_socket: ;-----------------------------------------
; The connection has no associated socket
.no_socket:
pusha pusha
mov ecx, socket_mutex mov ecx, socket_mutex
call mutex_unlock call mutex_unlock
@@ -1692,8 +1681,8 @@ align 4
call TCP_respond_segment call TCP_respond_segment
jmp .drop_no_socket jmp .drop_no_socket
;----- ;------------------------------------------------
; Drop ; Unlock socket mutex and prepare to drop segment
.drop: .drop:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Dropping segment\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Dropping segment\n"
@@ -1703,6 +1692,9 @@ align 4
call mutex_unlock call mutex_unlock
popa popa
;--------------------------------------------
; Destroy the newly created socket if needed
.destroy_new_socket: .destroy_new_socket:
test [temp_bits], TCP_BIT_DROPSOCKET test [temp_bits], TCP_BIT_DROPSOCKET
jz .drop_no_socket jz .drop_no_socket
@@ -1710,6 +1702,9 @@ align 4
mov eax, ebx mov eax, ebx
call SOCKET_free call SOCKET_free
;------------------
; Drop the segment
.drop_no_socket: .drop_no_socket:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n"

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;; ;; Part of the TCP/IP network stack for KolibriOS ;;
@@ -14,7 +14,7 @@
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 3514 $ $Revision: 5015 $
align 4 align 4
iglobal iglobal
@@ -143,7 +143,7 @@ TCP_pull_out_of_band:
; ;
;------------------------- ;-------------------------
align 4 align 4
TCP_drop: TCP_drop: ; FIXME CHECKME TODO
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_drop: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_drop: %x\n", eax
@@ -290,7 +290,6 @@ TCP_respond:
mov ecx, sizeof.TCP_header mov ecx, sizeof.TCP_header
mov di, IP_PROTO_TCP shl 8 + 128 mov di, IP_PROTO_TCP shl 8 + 128
call IPv4_output call IPv4_output
test edi, edi
jz .error jz .error
pop esi cx pop esi cx
push edx eax push edx eax

View File

@@ -14,7 +14,7 @@
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 3143 $ $Revision: 5013 $
timer_flag_retransmission = 1 shl 0 timer_flag_retransmission = 1 shl 0
timer_flag_keepalive = 1 shl 1 timer_flag_keepalive = 1 shl 1
@@ -61,13 +61,18 @@ local .exit
} }
;---------------------- align 4
; 640 ms timer proc TCP_timer_640ms ; TODO: implement timed wait timer!
;----------------------
macro TCP_timer_640ms { ; TODO: implement timed wait timer!
local .loop xor esi, esi
local .exit 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 ; Update TCP sequence number
@@ -81,7 +86,7 @@ local .exit
mov eax, [eax + SOCKET.NextPtr] mov eax, [eax + SOCKET.NextPtr]
.check_only: .check_only:
or eax, eax or eax, eax
jz .exit jz .wait
cmp [eax + SOCKET.Domain], AF_INET4 cmp [eax + SOCKET.Domain], AF_INET4
jne .loop jne .loop
@@ -157,9 +162,8 @@ local .exit
mov [eax + TCP_SOCKET.t_force], 0 mov [eax + TCP_SOCKET.t_force], 0
jmp .loop jmp .loop
.exit:
} endp

View File

@@ -14,6 +14,8 @@
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 4850 $
;------------------------- ;-------------------------
; ;
@@ -186,7 +188,7 @@ TCP_connect:
mov eax, [esp+4] mov eax, [esp+4]
mov [eax + SOCKET.errorcode], ETIMEDOUT mov [eax + SOCKET.errorcode], ETIMEDOUT
and [eax + SOCKET.state], not SS_ISCONNECTING and [eax + SOCKET.state], not SS_ISCONNECTING
call SOCKET_notify.unblock call SOCKET_notify
ret 4 ret 4
.fail: .fail:

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; UDP.INC ;; ;; UDP.INC ;;
@@ -245,6 +245,8 @@ UDP_input:
; ecx = number of bytes to send ; ecx = number of bytes to send
; esi = pointer to data ; esi = pointer to data
; ;
; OUT: eax = -1 on error
;
;----------------------------------------------------------------- ;-----------------------------------------------------------------
align 4 align 4

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 5164 $
struct BLITTER_BLOCK struct BLITTER_BLOCK
xmin dd ? xmin dd ?
ymin dd ? ymin dd ?

View File

@@ -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 ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -295,15 +295,17 @@ proc set_cursor stdcall, hcursor:dword
; jne .fail ; jne .fail
mov ebx, [current_slot] mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor] xchg eax, [ebx+APPDATA.cursor]
mov [redrawmouse_unconditional], 1 jmp .end
call __sys_draw_pointer
ret
;-------------------------------------- ;--------------------------------------
align 4 align 4
.fail: .fail:
mov eax, [def_cursor] mov eax, [def_cursor]
mov ebx, [current_slot] mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor] xchg eax, [ebx+APPDATA.cursor]
align 4
.end:
mov [redrawmouse_unconditional], 1
call __sys_draw_pointer
ret ret
endp endp
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
@@ -578,6 +580,40 @@ align 4
endp endp
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
align 4 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 proc move_cursor_24 stdcall, hcursor:dword, x:dword, y:dword
locals locals
h dd ? h dd ?
@@ -817,6 +853,129 @@ align 4
endp endp
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
align 4 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: check_mouse_area_for_getpixel_new:
; in: ; in:
; eax = x ; eax = x
@@ -852,7 +1011,10 @@ check_mouse_area_for_getpixel_new:
add eax, ebx add eax, ebx
mov ebx, eax mov ebx, eax
shl eax, 2 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 je @f
sub eax, ebx sub eax, ebx
;-------------------------------------- ;--------------------------------------
@@ -927,13 +1089,29 @@ align 4
add ecx, ebx add ecx, ebx
mov ebx, ecx mov ebx, ecx
shl ecx, 2 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 je .24
and eax, 0xFFFFFF and eax, 0xFFFFFF
mov [ecx + cur_saved_data], eax ;store new color to mov [ecx + cur_saved_data], eax ;store new color to
jmp @f jmp @f
;-------------------------------------- ;--------------------------------------
align 4 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: .24:
sub ecx, ebx sub ecx, ebx
mov [ecx + cur_saved_data], ax ;store new color to mov [ecx + cur_saved_data], ax ;store new color to
@@ -1001,9 +1179,9 @@ init_display:
mov ebx, restore_32 mov ebx, restore_32
mov ecx, move_cursor_32 mov ecx, move_cursor_32
mov edx, Vesa20_putpixel32_new mov edx, Vesa20_putpixel32_new
mov eax, [_display.bpp] mov eax, [_display.bits_per_pixel]
cmp al, 32 cmp al, 32
jne .24 jne .not_32bpp
.set: .set:
mov [_display.select_cursor], select_cursor mov [_display.select_cursor], select_cursor
@@ -1022,12 +1200,30 @@ init_display:
mov [def_cursor], eax mov [def_cursor], eax
ret ret
.24: .not_32bpp:
cmp al, 24
jne .not_24bpp
mov ebx, restore_24 mov ebx, restore_24
mov ecx, move_cursor_24 mov ecx, move_cursor_24
mov edx, Vesa20_putpixel24_new mov edx, Vesa20_putpixel24_new
cmp al, 24 jmp .set
je .set
.not_24bpp:
cmp al, 16
jne .not_16bpp
mov ebx, restore_16
mov ecx, move_cursor_16
mov edx, Vesa20_putpixel16_new
jmp .set
.not_16bpp:
; cmp al, 15
; jne .fail
; mov ebx, restore_15
; mov ecx, move_cursor_15
; mov edx, Vesa20_putpixel15_new
; jmp .set
.fail: .fail:
xor eax, eax xor eax, eax

File diff suppressed because it is too large Load Diff