kernel branch with configurable boot
git-svn-id: svn://kolibrios.org@1942 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
96673e3ce5
commit
7b2b309d03
347
kernel/branches/kolibri-cfg/COPYING.TXT
Normal file
347
kernel/branches/kolibri-cfg/COPYING.TXT
Normal file
@ -0,0 +1,347 @@
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
929
kernel/branches/kolibri-cfg/blkdev/cd_drv.inc
Normal file
929
kernel/branches/kolibri-cfg/blkdev/cd_drv.inc
Normal file
@ -0,0 +1,929 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
;**********************************************************
|
||||
; Непосредственная работа с устройством СD (ATAPI)
|
||||
;**********************************************************
|
||||
; Автор части исходного текста Кулаков Владимир Геннадьевич
|
||||
; Адаптация, доработка и разработка Mario79,<Lrz>
|
||||
|
||||
; Максимальное количество повторений операции чтения
|
||||
MaxRetr equ 10
|
||||
; Предельное время ожидания готовности к приему команды
|
||||
; (в тиках)
|
||||
BSYWaitTime equ 1000 ;2
|
||||
NoTickWaitTime equ 0xfffff
|
||||
CDBlockSize equ 2048
|
||||
;********************************************
|
||||
;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ *
|
||||
;* Многократное повторение чтения при сбоях *
|
||||
;********************************************
|
||||
ReadCDWRetr:
|
||||
;-----------------------------------------------------------
|
||||
; input : eax = block to read
|
||||
; ebx = destination
|
||||
;-----------------------------------------------------------
|
||||
pushad
|
||||
mov eax,[CDSectorAddress]
|
||||
mov ebx,[CDDataBuf_pointer]
|
||||
call cd_calculate_cache
|
||||
xor edi,edi
|
||||
add esi,8
|
||||
inc edi
|
||||
.hdreadcache:
|
||||
; cmp dword [esi+4],0 ; empty
|
||||
; je .nohdcache
|
||||
cmp [esi],eax ; correct sector
|
||||
je .yeshdcache
|
||||
.nohdcache:
|
||||
add esi,8
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz .hdreadcache
|
||||
call find_empty_slot_CD_cache ; ret in edi
|
||||
|
||||
push edi
|
||||
push eax
|
||||
call cd_calculate_cache_2
|
||||
shl edi,11
|
||||
add edi,eax
|
||||
mov [CDDataBuf_pointer],edi
|
||||
pop eax
|
||||
pop edi
|
||||
|
||||
call ReadCDWRetr_1
|
||||
cmp [DevErrorCode],0
|
||||
jne .exit
|
||||
|
||||
mov [CDDataBuf_pointer],ebx
|
||||
call cd_calculate_cache_1
|
||||
lea esi,[edi*8+esi]
|
||||
mov [esi],eax ; sector number
|
||||
; mov dword [esi+4],1 ; hd read - mark as same as in hd
|
||||
.yeshdcache:
|
||||
mov esi,edi
|
||||
shl esi,11 ;9
|
||||
push eax
|
||||
call cd_calculate_cache_2
|
||||
add esi,eax
|
||||
pop eax
|
||||
mov edi,ebx ;[CDDataBuf_pointer]
|
||||
mov ecx,512 ;/4
|
||||
cld
|
||||
rep movsd ; move data
|
||||
.exit:
|
||||
popad
|
||||
ret
|
||||
|
||||
ReadCDWRetr_1:
|
||||
pushad
|
||||
|
||||
; Цикл, пока команда не выполнена успешно или не
|
||||
; исчерпано количество попыток
|
||||
mov ECX,MaxRetr
|
||||
@@NextRetr:
|
||||
; Подать команду
|
||||
;*************************************************
|
||||
;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА *
|
||||
;* Считываются данные пользователя, информация *
|
||||
;* субканала и контрольная информация *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале; *
|
||||
;* CDSectorAddress - адрес считываемого сектора. *
|
||||
;* Данные считывается в массив CDDataBuf. *
|
||||
;*************************************************
|
||||
;ReadCD:
|
||||
push ecx
|
||||
; pusha
|
||||
; Задать размер сектора
|
||||
; mov [CDBlockSize],2048 ;2352
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать пакетную команду для считывания
|
||||
; сектора данных
|
||||
; Задать код команды Read CD
|
||||
mov [PacketCommand],byte 0x28 ;0xBE
|
||||
; Задать адрес сектора
|
||||
mov AX,word [CDSectorAddress+2]
|
||||
xchg AL,AH
|
||||
mov word [PacketCommand+2],AX
|
||||
mov AX,word [CDSectorAddress]
|
||||
xchg AL,AH
|
||||
mov word [PacketCommand+4],AX
|
||||
; mov eax,[CDSectorAddress]
|
||||
; mov [PacketCommand+2],eax
|
||||
; Задать количество считываемых секторов
|
||||
mov [PacketCommand+8],byte 1
|
||||
; Задать считывание данных в полном объеме
|
||||
; mov [PacketCommand+9],byte 0xF8
|
||||
; Подать команду
|
||||
call SendPacketDatCommand
|
||||
pop ecx
|
||||
; ret
|
||||
|
||||
; cmp [DevErrorCode],0
|
||||
test eax,eax
|
||||
jz @@End_4
|
||||
|
||||
or ecx,ecx ;{SPraid.simba} (for cd load)
|
||||
jz @@End_4
|
||||
dec ecx
|
||||
|
||||
cmp [timer_ticks_enable],0
|
||||
jne @f
|
||||
mov eax,NoTickWaitTime
|
||||
.wait:
|
||||
dec eax
|
||||
; test eax,eax
|
||||
jz @@NextRetr
|
||||
jmp .wait
|
||||
@@:
|
||||
; Задержка на 2,5 секунды
|
||||
; mov EAX,[timer_ticks]
|
||||
; add EAX,50 ;250
|
||||
;@@Wait:
|
||||
; call change_task
|
||||
; cmp EAX,[timer_ticks]
|
||||
; ja @@Wait
|
||||
loop @@NextRetr
|
||||
@@End_4:
|
||||
mov dword [DevErrorCode],eax
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
; Универсальные процедуры, обеспечивающие выполнение
|
||||
; пакетных команд в режиме PIO
|
||||
|
||||
; Максимально допустимое время ожидания реакции
|
||||
; устройства на пакетную команду (в тиках)
|
||||
|
||||
MaxCDWaitTime equ 1000 ;200 ;10 секунд
|
||||
uglobal
|
||||
; Область памяти для формирования пакетной команды
|
||||
PacketCommand: rb 12 ;DB 12 DUP (?)
|
||||
; Область памяти для приема данных от дисковода
|
||||
;CDDataBuf DB 4096 DUP (0)
|
||||
; Размер принимаемого блока данных в байтах
|
||||
;CDBlockSize DW ?
|
||||
; Адрес считываемого сектора данных
|
||||
CDSectorAddress: DD ?
|
||||
; Время начала очередной операции с диском
|
||||
TickCounter_1 DD 0
|
||||
; Время начала ожидания готовности устройства
|
||||
WURStartTime DD 0
|
||||
; указатель буфера для считывания
|
||||
CDDataBuf_pointer dd 0
|
||||
endg
|
||||
;****************************************************
|
||||
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
|
||||
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
|
||||
;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале; *
|
||||
;* PacketCommand - 12-байтный командный пакет; *
|
||||
;* CDBlockSize - размер принимаемого блока данных. *
|
||||
; return eax DevErrorCode
|
||||
;****************************************************
|
||||
SendPacketDatCommand:
|
||||
xor eax,eax
|
||||
; mov byte [DevErrorCode],al
|
||||
; Задать режим CHS
|
||||
mov byte [ATAAddressMode],al
|
||||
; Послать ATA-команду передачи пакетной команды
|
||||
mov byte [ATAFeatures],al
|
||||
mov byte [ATASectorCount],al
|
||||
mov byte [ATASectorNumber],al
|
||||
; Загрузить размер передаваемого блока
|
||||
mov [ATAHead],al
|
||||
; mov AX,[CDBlockSize]
|
||||
mov [ATACylinder],CDBlockSize
|
||||
mov [ATACommand],0A0h
|
||||
call SendCommandToHDD_1
|
||||
test eax,eax
|
||||
; cmp [DevErrorCode],0 ;проверить код ошибки
|
||||
jnz @@End_8 ;закончить, сохранив код ошибки
|
||||
|
||||
; Ожидание готовности дисковода к приему
|
||||
; пакетной команды
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
mov ecx,NoTickWaitTime
|
||||
@@WaitDevice0:
|
||||
cmp [timer_ticks_enable],0
|
||||
jne @f
|
||||
dec ecx
|
||||
; test ecx,ecx
|
||||
jz @@Err1_1
|
||||
jmp .test
|
||||
@@:
|
||||
call change_task
|
||||
; Проверить время выполнения команды
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[TickCounter_1]
|
||||
cmp EAX,BSYWaitTime
|
||||
ja @@Err1_1 ;ошибка тайм-аута
|
||||
; Проверить готовность
|
||||
.test:
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitDevice0
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Err6
|
||||
test AL,08h ;состояние сигнала DRQ
|
||||
jz @@WaitDevice0
|
||||
; Послать пакетную команду
|
||||
cli
|
||||
mov DX,[ATABasePortAddr]
|
||||
mov AX,[PacketCommand]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+2]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+4]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+6]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+8]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+10]
|
||||
out DX,AX
|
||||
sti
|
||||
; Ожидание готовности данных
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
mov ecx,NoTickWaitTime
|
||||
@@WaitDevice1:
|
||||
cmp [timer_ticks_enable],0
|
||||
jne @f
|
||||
dec ecx
|
||||
; test ecx,ecx
|
||||
jz @@Err1_1
|
||||
jmp .test_1
|
||||
@@:
|
||||
call change_task
|
||||
; Проверить время выполнения команды
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[TickCounter_1]
|
||||
cmp EAX,MaxCDWaitTime
|
||||
ja @@Err1_1 ;ошибка тайм-аута
|
||||
; Проверить готовность
|
||||
.test_1:
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitDevice1
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Err6_temp
|
||||
test AL,08h ;состояние сигнала DRQ
|
||||
jz @@WaitDevice1
|
||||
; Принять блок данных от контроллера
|
||||
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf
|
||||
; Загрузить адрес регистра данных контроллера
|
||||
mov DX,[ATABasePortAddr] ;порт 1x0h
|
||||
; Загрузить в счетчик размер блока в байтах
|
||||
xor ecx,ecx
|
||||
mov CX,CDBlockSize
|
||||
; Вычислить размер блока в 16-разрядных словах
|
||||
shr CX,1 ;разделить размер блока на 2
|
||||
; Принять блок данных
|
||||
cli
|
||||
cld
|
||||
rep insw
|
||||
sti
|
||||
; Успешное завершение приема данных
|
||||
@@End_8:
|
||||
xor eax,eax
|
||||
ret
|
||||
|
||||
; Записать код ошибки
|
||||
@@Err1_1:
|
||||
xor eax,eax
|
||||
inc eax
|
||||
ret
|
||||
; mov [DevErrorCode],1
|
||||
; ret
|
||||
@@Err6_temp:
|
||||
mov eax,7
|
||||
ret
|
||||
; mov [DevErrorCode],7
|
||||
; ret
|
||||
@@Err6:
|
||||
mov eax,6
|
||||
ret
|
||||
; mov [DevErrorCode],6
|
||||
;@@End_8:
|
||||
; ret
|
||||
|
||||
|
||||
|
||||
;***********************************************
|
||||
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
|
||||
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ *
|
||||
;* Входные параметры передаются через *
|
||||
;* глобальные перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале; *
|
||||
;* PacketCommand - 12-байтный командный пакет. *
|
||||
;***********************************************
|
||||
SendPacketNoDatCommand:
|
||||
pushad
|
||||
xor eax,eax
|
||||
; mov byte [DevErrorCode],al
|
||||
; Задать режим CHS
|
||||
mov byte [ATAAddressMode],al
|
||||
; Послать ATA-команду передачи пакетной команды
|
||||
mov byte [ATAFeatures],al
|
||||
mov byte [ATASectorCount],al
|
||||
mov byte [ATASectorNumber],al
|
||||
mov word [ATACylinder],ax
|
||||
mov byte [ATAHead],al
|
||||
mov [ATACommand],0A0h
|
||||
call SendCommandToHDD_1
|
||||
; cmp [DevErrorCode],0 ;проверить код ошибки
|
||||
test eax,eax
|
||||
jnz @@End_9 ;закончить, сохранив код ошибки
|
||||
; Ожидание готовности дисковода к приему
|
||||
; пакетной команды
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
@@WaitDevice0_1:
|
||||
call change_task
|
||||
; Проверить время ожидания
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[TickCounter_1]
|
||||
cmp EAX,BSYWaitTime
|
||||
ja @@Err1_3 ;ошибка тайм-аута
|
||||
; Проверить готовность
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitDevice0_1
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Err6_1
|
||||
test AL,08h ;состояние сигнала DRQ
|
||||
jz @@WaitDevice0_1
|
||||
; Послать пакетную команду
|
||||
; cli
|
||||
mov DX,[ATABasePortAddr]
|
||||
mov AX,word [PacketCommand]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+2]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+4]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+6]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+8]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+10]
|
||||
out DX,AX
|
||||
; sti
|
||||
cmp [ignore_CD_eject_wait],1
|
||||
je @@clear_DEC
|
||||
; Ожидание подтверждения приема команды
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
@@WaitDevice1_1:
|
||||
call change_task
|
||||
; Проверить время выполнения команды
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[TickCounter_1]
|
||||
cmp EAX,MaxCDWaitTime
|
||||
ja @@Err1_3 ;ошибка тайм-аута
|
||||
; Ожидать освобождения устройства
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitDevice1_1
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Err6_1
|
||||
test AL,40h ;состояние сигнала DRDY
|
||||
jz @@WaitDevice1_1
|
||||
@@clear_DEC:
|
||||
and [DevErrorCode],0
|
||||
popad
|
||||
ret
|
||||
; Записать код ошибки
|
||||
@@Err1_3:
|
||||
xor eax,eax
|
||||
inc eax
|
||||
jmp @@End_9
|
||||
@@Err6_1:
|
||||
mov eax,6
|
||||
@@End_9:
|
||||
mov [DevErrorCode],eax
|
||||
popad
|
||||
ret
|
||||
|
||||
;****************************************************
|
||||
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала (1 или 2); *
|
||||
;* DiskNumber - номер диска (0 или 1); *
|
||||
;* ATAFeatures - "особенности"; *
|
||||
;* ATASectorCount - количество секторов; *
|
||||
;* ATASectorNumber - номер начального сектора; *
|
||||
;* ATACylinder - номер начального цилиндра; *
|
||||
;* ATAHead - номер начальной головки; *
|
||||
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
|
||||
;* ATACommand - код команды. *
|
||||
;* После успешного выполнения функции: *
|
||||
;* в ATABasePortAddr - базовый адрес HDD; *
|
||||
;* в DevErrorCode - ноль. *
|
||||
;* При возникновении ошибки в DevErrorCode будет *
|
||||
;* возвращен код ошибки в eax *
|
||||
;****************************************************
|
||||
SendCommandToHDD_1:
|
||||
; pushad
|
||||
; mov [DevErrorCode],0 not need
|
||||
; Проверить значение кода режима
|
||||
cmp [ATAAddressMode],1
|
||||
ja @@Err2_4
|
||||
; Проверить корректность номера канала
|
||||
mov BX,[ChannelNumber]
|
||||
cmp BX,1
|
||||
jb @@Err3_4
|
||||
cmp BX,2
|
||||
ja @@Err3_4
|
||||
; Установить базовый адрес
|
||||
dec BX
|
||||
shl BX,1
|
||||
movzx ebx,bx
|
||||
mov AX,[ebx+StandardATABases]
|
||||
mov [ATABasePortAddr],AX
|
||||
; Ожидание готовности HDD к приему команды
|
||||
; Выбрать нужный диск
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,6 ;адрес регистра головок
|
||||
mov AL,[DiskNumber]
|
||||
cmp AL,1 ;проверить номера диска
|
||||
ja @@Err4_4
|
||||
shl AL,4
|
||||
or AL,10100000b
|
||||
out DX,AL
|
||||
; Ожидать, пока диск не будет готов
|
||||
inc DX
|
||||
mov eax,[timer_ticks]
|
||||
mov [TickCounter_1],eax
|
||||
mov ecx,NoTickWaitTime
|
||||
@@WaitHDReady_2:
|
||||
cmp [timer_ticks_enable],0
|
||||
jne @f
|
||||
dec ecx
|
||||
; test ecx,ecx
|
||||
jz @@Err1_4
|
||||
jmp .test
|
||||
@@:
|
||||
call change_task
|
||||
; Проверить время ожидания
|
||||
mov eax,[timer_ticks]
|
||||
sub eax,[TickCounter_1]
|
||||
cmp eax,BSYWaitTime ;300 ;ожидать 3 сек.
|
||||
ja @@Err1_4 ;ошибка тайм-аута
|
||||
; Прочитать регистр состояния
|
||||
.test:
|
||||
in AL,DX
|
||||
; Проверить состояние сигнала BSY
|
||||
test AL,80h
|
||||
jnz @@WaitHDReady_2
|
||||
; Проверить состояние сигнала DRQ
|
||||
test AL,08h
|
||||
jnz @@WaitHDReady_2
|
||||
|
||||
; Загрузить команду в регистры контроллера
|
||||
cli
|
||||
mov DX,[ATABasePortAddr]
|
||||
inc DX ;регистр "особенностей"
|
||||
mov AL,[ATAFeatures]
|
||||
out DX,AL
|
||||
inc DX ;счетчик секторов
|
||||
mov AL,[ATASectorCount]
|
||||
out DX,AL
|
||||
inc DX ;регистр номера сектора
|
||||
mov AL,[ATASectorNumber]
|
||||
out DX,AL
|
||||
inc DX ;номер цилиндра (младший байт)
|
||||
mov AX,[ATACylinder]
|
||||
out DX,AL
|
||||
inc DX ;номер цилиндра (старший байт)
|
||||
mov AL,AH
|
||||
out DX,AL
|
||||
inc DX ;номер головки/номер диска
|
||||
mov AL,[DiskNumber]
|
||||
shl AL,4
|
||||
cmp [ATAHead],0Fh ;проверить номер головки
|
||||
ja @@Err5_4
|
||||
or AL,[ATAHead]
|
||||
or AL,10100000b
|
||||
mov AH,[ATAAddressMode]
|
||||
shl AH,6
|
||||
or AL,AH
|
||||
out DX,AL
|
||||
; Послать команду
|
||||
mov AL,[ATACommand]
|
||||
inc DX ;регистр команд
|
||||
out DX,AL
|
||||
sti
|
||||
; Сбросить признак ошибки
|
||||
; mov [DevErrorCode],0
|
||||
@@End_10:
|
||||
xor eax,eax
|
||||
ret
|
||||
; Записать код ошибки
|
||||
@@Err1_4:
|
||||
xor eax,eax
|
||||
inc eax
|
||||
; mov [DevErrorCode],1
|
||||
ret
|
||||
@@Err2_4:
|
||||
mov eax,2
|
||||
; mov [DevErrorCode],2
|
||||
ret
|
||||
@@Err3_4:
|
||||
mov eax,3
|
||||
; mov [DevErrorCode],3
|
||||
ret
|
||||
@@Err4_4:
|
||||
mov eax,4
|
||||
; mov [DevErrorCode],4
|
||||
ret
|
||||
@@Err5_4:
|
||||
mov eax,5
|
||||
; mov [DevErrorCode],5
|
||||
; Завершение работы программы
|
||||
ret
|
||||
; sti
|
||||
; popad
|
||||
|
||||
;*************************************************
|
||||
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
WaitUnitReady:
|
||||
pusha
|
||||
; Запомнить время начала операции
|
||||
mov EAX,[timer_ticks]
|
||||
mov [WURStartTime],EAX
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать команду TEST UNIT READY
|
||||
mov [PacketCommand],word 00h
|
||||
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
|
||||
mov ecx,NoTickWaitTime
|
||||
@@SendCommand:
|
||||
; Подать команду проверки готовности
|
||||
call SendPacketNoDatCommand
|
||||
cmp [timer_ticks_enable],0
|
||||
jne @f
|
||||
cmp [DevErrorCode],0
|
||||
je @@End_11
|
||||
dec ecx
|
||||
; cmp ecx,0
|
||||
jz .Error
|
||||
jmp @@SendCommand
|
||||
@@:
|
||||
call change_task
|
||||
; Проверить код ошибки
|
||||
cmp [DevErrorCode],0
|
||||
je @@End_11
|
||||
; Проверить время ожидания готовности
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[WURStartTime]
|
||||
cmp EAX,MaxCDWaitTime
|
||||
jb @@SendCommand
|
||||
.Error:
|
||||
; Ошибка тайм-аута
|
||||
mov [DevErrorCode],1
|
||||
@@End_11:
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* ЗАПРЕТИТЬ СМЕНУ ДИСКА *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
prevent_medium_removal:
|
||||
pusha
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Задать код команды
|
||||
mov [PacketCommand],byte 0x1E
|
||||
; Задать код запрета
|
||||
mov [PacketCommand+4],byte 11b
|
||||
; Подать команду
|
||||
call SendPacketNoDatCommand
|
||||
mov eax,ATAPI_IDE0_lock
|
||||
add eax,[cdpos]
|
||||
dec eax
|
||||
mov [eax],byte 1
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* РАЗРЕШИТЬ СМЕНУ ДИСКА *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
allow_medium_removal:
|
||||
pusha
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Задать код команды
|
||||
mov [PacketCommand],byte 0x1E
|
||||
; Задать код запрета
|
||||
mov [PacketCommand+4],byte 00b
|
||||
; Подать команду
|
||||
call SendPacketNoDatCommand
|
||||
mov eax,ATAPI_IDE0_lock
|
||||
add eax,[cdpos]
|
||||
dec eax
|
||||
mov [eax],byte 0
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
LoadMedium:
|
||||
pusha
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать команду START/STOP UNIT
|
||||
; Задать код команды
|
||||
mov [PacketCommand],word 1Bh
|
||||
; Задать операцию загрузки носителя
|
||||
mov [PacketCommand+4],word 00000011b
|
||||
; Подать команду
|
||||
call SendPacketNoDatCommand
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
EjectMedium:
|
||||
pusha
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать команду START/STOP UNIT
|
||||
; Задать код команды
|
||||
mov [PacketCommand],word 1Bh
|
||||
; Задать операцию извлечения носителя
|
||||
mov [PacketCommand+4],word 00000010b
|
||||
; Подать команду
|
||||
call SendPacketNoDatCommand
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* Проверить событие нажатия кнопки извлечения *
|
||||
;* диска *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
align 4
|
||||
check_ATAPI_device_event:
|
||||
pusha
|
||||
mov eax,[timer_ticks]
|
||||
sub eax,[timer_ATAPI_check]
|
||||
cmp eax,100
|
||||
jb .end_1
|
||||
mov al,[DRIVE_DATA+1]
|
||||
and al,11b
|
||||
cmp al,10b
|
||||
jz .ide3
|
||||
.ide2_1:
|
||||
mov al,[DRIVE_DATA+1]
|
||||
and al,1100b
|
||||
cmp al,1000b
|
||||
jz .ide2
|
||||
.ide1_1:
|
||||
mov al,[DRIVE_DATA+1]
|
||||
and al,110000b
|
||||
cmp al,100000b
|
||||
jz .ide1
|
||||
.ide0_1:
|
||||
mov al,[DRIVE_DATA+1]
|
||||
and al,11000000b
|
||||
cmp al,10000000b
|
||||
jz .ide0
|
||||
.end:
|
||||
|
||||
sti
|
||||
mov eax,[timer_ticks]
|
||||
mov [timer_ATAPI_check],eax
|
||||
.end_1:
|
||||
popa
|
||||
ret
|
||||
|
||||
.ide3:
|
||||
cli
|
||||
cmp [ATAPI_IDE3_lock],1
|
||||
jne .ide2_1
|
||||
cmp [IDE_Channel_2],0
|
||||
jne .ide1_1
|
||||
cmp [cd_status],0
|
||||
jne .end
|
||||
mov [IDE_Channel_2],1
|
||||
call reserve_ok2
|
||||
mov [ChannelNumber],2
|
||||
mov [DiskNumber],1
|
||||
mov [cdpos],4
|
||||
call GetEvent_StatusNotification
|
||||
cmp [CDDataBuf+4],byte 1
|
||||
je .eject_ide3
|
||||
call syscall_cdaudio.free
|
||||
jmp .ide2_1
|
||||
.eject_ide3:
|
||||
call .eject
|
||||
call syscall_cdaudio.free
|
||||
jmp .ide2_1
|
||||
|
||||
.ide2:
|
||||
cli
|
||||
cmp [ATAPI_IDE2_lock],1
|
||||
jne .ide1_1
|
||||
cmp [IDE_Channel_2],0
|
||||
jne .ide1_1
|
||||
cmp [cd_status],0
|
||||
jne .end
|
||||
mov [IDE_Channel_2],1
|
||||
call reserve_ok2
|
||||
mov [ChannelNumber],2
|
||||
mov [DiskNumber],0
|
||||
mov [cdpos],3
|
||||
call GetEvent_StatusNotification
|
||||
cmp [CDDataBuf+4],byte 1
|
||||
je .eject_ide2
|
||||
call syscall_cdaudio.free
|
||||
jmp .ide1_1
|
||||
.eject_ide2:
|
||||
call .eject
|
||||
call syscall_cdaudio.free
|
||||
jmp .ide1_1
|
||||
|
||||
.ide1:
|
||||
cli
|
||||
cmp [ATAPI_IDE1_lock],1
|
||||
jne .ide0_1
|
||||
cmp [IDE_Channel_1],0
|
||||
jne .end
|
||||
cmp [cd_status],0
|
||||
jne .end
|
||||
mov [IDE_Channel_1],1
|
||||
call reserve_ok2
|
||||
mov [ChannelNumber],1
|
||||
mov [DiskNumber],1
|
||||
mov [cdpos],2
|
||||
call GetEvent_StatusNotification
|
||||
cmp [CDDataBuf+4],byte 1
|
||||
je .eject_ide1
|
||||
call syscall_cdaudio.free
|
||||
jmp .ide0_1
|
||||
.eject_ide1:
|
||||
call .eject
|
||||
call syscall_cdaudio.free
|
||||
jmp .ide0_1
|
||||
|
||||
.ide0:
|
||||
cli
|
||||
cmp [ATAPI_IDE0_lock],1
|
||||
jne .end
|
||||
cmp [IDE_Channel_1],0
|
||||
jne .end
|
||||
cmp [cd_status],0
|
||||
jne .end
|
||||
mov [IDE_Channel_1],1
|
||||
call reserve_ok2
|
||||
mov [ChannelNumber],1
|
||||
mov [DiskNumber],0
|
||||
mov [cdpos],1
|
||||
call GetEvent_StatusNotification
|
||||
cmp [CDDataBuf+4],byte 1
|
||||
je .eject_ide0
|
||||
call syscall_cdaudio.free
|
||||
jmp .end
|
||||
.eject_ide0:
|
||||
call .eject
|
||||
call syscall_cdaudio.free
|
||||
jmp .end
|
||||
|
||||
.eject:
|
||||
call clear_CD_cache
|
||||
call allow_medium_removal
|
||||
mov [ignore_CD_eject_wait],1
|
||||
call EjectMedium
|
||||
mov [ignore_CD_eject_wait],0
|
||||
ret
|
||||
iglobal
|
||||
timer_ATAPI_check dd 0
|
||||
ATAPI_IDE0_lock db 0
|
||||
ATAPI_IDE1_lock db 0
|
||||
ATAPI_IDE2_lock db 0
|
||||
ATAPI_IDE3_lock db 0
|
||||
ignore_CD_eject_wait db 0
|
||||
endg
|
||||
;*************************************************
|
||||
;* Получить сообщение о событии или состоянии *
|
||||
;* устройства *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
GetEvent_StatusNotification:
|
||||
pusha
|
||||
mov [CDDataBuf_pointer],CDDataBuf
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Задать код команды
|
||||
mov [PacketCommand],byte 4Ah
|
||||
mov [PacketCommand+1],byte 00000001b
|
||||
; Задать запрос класса сообщений
|
||||
mov [PacketCommand+4],byte 00010000b
|
||||
; Размер выделенной области
|
||||
mov [PacketCommand+7],byte 8h
|
||||
mov [PacketCommand+8],byte 0h
|
||||
; Подать команду
|
||||
call SendPacketDatCommand
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
; прочитать информацию из TOC
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
Read_TOC:
|
||||
pusha
|
||||
mov [CDDataBuf_pointer],CDDataBuf
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать пакетную команду для считывания
|
||||
; сектора данных
|
||||
mov [PacketCommand],byte 0x43
|
||||
; Задать формат
|
||||
mov [PacketCommand+2],byte 1
|
||||
; Размер выделенной области
|
||||
mov [PacketCommand+7],byte 0xFF
|
||||
mov [PacketCommand+8],byte 0h
|
||||
; Подать команду
|
||||
call SendPacketDatCommand
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
;ReadCapacity:
|
||||
; pusha
|
||||
;; Очистить буфер пакетной команды
|
||||
; call clear_packet_buffer
|
||||
;; Задать размер буфера в байтах
|
||||
; mov [CDBlockSize],8
|
||||
;; Сформировать команду READ CAPACITY
|
||||
; mov [PacketCommand],word 25h
|
||||
;; Подать команду
|
||||
; call SendPacketDatCommand
|
||||
; popa
|
||||
; ret
|
||||
|
||||
clear_packet_buffer:
|
||||
; Очистить буфер пакетной команды
|
||||
and [PacketCommand],dword 0
|
||||
and [PacketCommand+4],dword 0
|
||||
and [PacketCommand+8],dword 0
|
||||
ret
|
271
kernel/branches/kolibri-cfg/blkdev/cdrom.inc
Normal file
271
kernel/branches/kolibri-cfg/blkdev/cdrom.inc
Normal file
@ -0,0 +1,271 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
sys_cd_audio:
|
||||
|
||||
cmp word [cdbase],word 0
|
||||
jnz @f
|
||||
mov eax,1
|
||||
ret
|
||||
@@:
|
||||
|
||||
; eax=1 cdplay at ebx 0x00FFSSMM
|
||||
; eax=2 get tracklist size of ecx to [ebx]
|
||||
; eax=3 stop/pause playing
|
||||
|
||||
cmp eax,1
|
||||
jnz nocdp
|
||||
call sys_cdplay
|
||||
ret
|
||||
nocdp:
|
||||
|
||||
cmp eax,2
|
||||
jnz nocdtl
|
||||
mov edi,[TASK_BASE]
|
||||
add edi,TASKDATA.mem_start
|
||||
add ebx,[edi]
|
||||
call sys_cdtracklist
|
||||
ret
|
||||
nocdtl:
|
||||
|
||||
cmp eax,3
|
||||
jnz nocdpause
|
||||
call sys_cdpause
|
||||
ret
|
||||
nocdpause:
|
||||
|
||||
mov eax,0xffffff01
|
||||
ret
|
||||
|
||||
|
||||
|
||||
sys_cd_atapi_command:
|
||||
|
||||
pushad
|
||||
|
||||
mov dx,word [cdbase]
|
||||
add dx,6
|
||||
mov ax,word [cdid]
|
||||
out dx,al
|
||||
mov esi,10
|
||||
call delay_ms
|
||||
mov dx,word [cdbase]
|
||||
add dx,7
|
||||
in al,dx
|
||||
and al,0x80
|
||||
cmp al,0
|
||||
jnz res
|
||||
jmp cdl6
|
||||
res:
|
||||
mov dx,word [cdbase]
|
||||
add dx,7
|
||||
mov al,0x8
|
||||
out dx,al
|
||||
mov dx,word [cdbase]
|
||||
add dx,0x206
|
||||
mov al,0xe
|
||||
out dx,al
|
||||
mov esi,1
|
||||
call delay_ms
|
||||
mov dx,word [cdbase]
|
||||
add dx,0x206
|
||||
mov al,0x8
|
||||
out dx,al
|
||||
mov esi,30
|
||||
call delay_ms
|
||||
xor cx,cx
|
||||
cdl5:
|
||||
inc cx
|
||||
cmp cx,10
|
||||
jz cdl6
|
||||
mov dx,word [cdbase]
|
||||
add dx,7
|
||||
in al,dx
|
||||
and al,0x88
|
||||
cmp al,0x00
|
||||
jz cdl5
|
||||
mov esi,100
|
||||
call delay_ms
|
||||
jmp cdl5
|
||||
cdl6:
|
||||
mov dx,word [cdbase]
|
||||
add dx,4
|
||||
mov al,0
|
||||
out dx,al
|
||||
mov dx,word [cdbase]
|
||||
add dx,5
|
||||
mov al,0
|
||||
out dx,al
|
||||
mov dx,word [cdbase]
|
||||
add dx,7
|
||||
mov al,0xec
|
||||
out dx,al
|
||||
mov esi,5
|
||||
call delay_ms
|
||||
mov dx,word [cdbase]
|
||||
add dx,1
|
||||
mov al,0
|
||||
out dx,al
|
||||
add dx,1
|
||||
mov al,0
|
||||
out dx,al
|
||||
add dx,1
|
||||
mov al,0
|
||||
out dx,al
|
||||
add dx,1
|
||||
mov al,0
|
||||
out dx,al
|
||||
add dx,1
|
||||
mov al,128
|
||||
out dx,al
|
||||
add dx,2
|
||||
mov al,0xa0
|
||||
out dx,al
|
||||
xor cx,cx
|
||||
mov dx,word [cdbase]
|
||||
add dx,7
|
||||
cdl1:
|
||||
inc cx
|
||||
cmp cx,100
|
||||
jz cdl2
|
||||
in al,dx
|
||||
and ax,0x88
|
||||
cmp al,0x8
|
||||
jz cdl2
|
||||
mov esi,2
|
||||
call delay_ms
|
||||
jmp cdl1
|
||||
cdl2:
|
||||
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
sys_cdplay:
|
||||
|
||||
mov ax,5
|
||||
push ax
|
||||
push ebx
|
||||
cdplay:
|
||||
call sys_cd_atapi_command
|
||||
cli
|
||||
mov dx,word [cdbase]
|
||||
mov ax,0x0047
|
||||
out dx,ax
|
||||
mov al,1
|
||||
mov ah,[esp+0] ; min xx
|
||||
out dx,ax
|
||||
mov ax,[esp+1] ; fr sec
|
||||
out dx,ax
|
||||
mov ax,256+99
|
||||
out dx,ax
|
||||
mov ax,0x0001
|
||||
out dx,ax
|
||||
mov ax,0x0000
|
||||
out dx,ax
|
||||
mov esi,10
|
||||
call delay_ms
|
||||
sti
|
||||
add dx,7
|
||||
in al,dx
|
||||
test al,1
|
||||
jz cdplayok
|
||||
mov ax,[esp+4]
|
||||
dec ax
|
||||
mov [esp+4],ax
|
||||
cmp ax,0
|
||||
jz cdplayfail
|
||||
jmp cdplay
|
||||
cdplayfail:
|
||||
cdplayok:
|
||||
pop ebx
|
||||
pop ax
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
sys_cdtracklist:
|
||||
|
||||
push ebx
|
||||
tcdplay:
|
||||
call sys_cd_atapi_command
|
||||
mov dx,word [cdbase]
|
||||
mov ax,0x43+2*256
|
||||
out dx,ax
|
||||
mov ax,0x0
|
||||
out dx,ax
|
||||
mov ax,0x0
|
||||
out dx,ax
|
||||
mov ax,0x0
|
||||
out dx,ax
|
||||
mov ax,200
|
||||
out dx,ax
|
||||
mov ax,0x0
|
||||
out dx,ax
|
||||
in al,dx
|
||||
mov cx,1000
|
||||
mov dx,word [cdbase]
|
||||
add dx,7
|
||||
cld
|
||||
cdtrnwewait:
|
||||
mov esi,10
|
||||
call delay_ms
|
||||
in al,dx
|
||||
and al,128
|
||||
cmp al,0
|
||||
jz cdtrl1
|
||||
loop cdtrnwewait
|
||||
cdtrl1:
|
||||
; read the result
|
||||
mov ecx,[esp+0]
|
||||
mov dx,word [cdbase]
|
||||
cdtrread:
|
||||
add dx,7
|
||||
in al,dx
|
||||
and al,8
|
||||
cmp al,8
|
||||
jnz cdtrdone
|
||||
sub dx,7
|
||||
in ax,dx
|
||||
mov [ecx],ax
|
||||
add ecx,2
|
||||
jmp cdtrread
|
||||
cdtrdone:
|
||||
pop ecx
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
sys_cdpause:
|
||||
|
||||
call sys_cd_atapi_command
|
||||
|
||||
mov dx,word [cdbase]
|
||||
mov ax,0x004B
|
||||
out dx,ax
|
||||
mov ax,0
|
||||
out dx,ax
|
||||
mov ax,0
|
||||
out dx,ax
|
||||
mov ax,0
|
||||
out dx,ax
|
||||
mov ax,0
|
||||
out dx,ax
|
||||
mov ax,0
|
||||
out dx,ax
|
||||
|
||||
mov esi,10
|
||||
call delay_ms
|
||||
add dx,7
|
||||
in al,dx
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
|
71
kernel/branches/kolibri-cfg/blkdev/fdc.inc
Normal file
71
kernel/branches/kolibri-cfg/blkdev/fdc.inc
Normal file
@ -0,0 +1,71 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
iglobal
|
||||
;function pointers.
|
||||
fdc_irq_func dd fdc_null
|
||||
endg
|
||||
|
||||
uglobal
|
||||
dmasize db 0x0
|
||||
dmamode db 0x0
|
||||
endg
|
||||
|
||||
fdc_init: ;start with clean tracks.
|
||||
mov edi,OS_BASE+0xD201
|
||||
mov al,0
|
||||
mov ecx,160
|
||||
rep stosb
|
||||
ret
|
||||
|
||||
fdc_irq:
|
||||
call [fdc_irq_func]
|
||||
fdc_null:
|
||||
ret
|
||||
|
||||
save_image:
|
||||
call reserve_flp
|
||||
call restorefatchain
|
||||
pusha
|
||||
call check_label
|
||||
cmp [FDC_Status],0
|
||||
jne unnecessary_save_image
|
||||
mov [FDD_Track],0 ; Öèëèíäð
|
||||
mov [FDD_Head],0 ; Ñòîðîíà
|
||||
mov [FDD_Sector],1 ; Ñåêòîð
|
||||
mov esi,RAMDISK
|
||||
call SeekTrack
|
||||
save_image_1:
|
||||
push esi
|
||||
call take_data_from_application_1
|
||||
pop esi
|
||||
add esi,512
|
||||
call WriteSectWithRetr
|
||||
; call WriteSector
|
||||
cmp [FDC_Status],0
|
||||
jne unnecessary_save_image
|
||||
inc [FDD_Sector]
|
||||
cmp [FDD_Sector],19
|
||||
jne save_image_1
|
||||
mov [FDD_Sector],1
|
||||
inc [FDD_Head]
|
||||
cmp [FDD_Head],2
|
||||
jne save_image_1
|
||||
mov [FDD_Head],0
|
||||
inc [FDD_Track]
|
||||
call SeekTrack
|
||||
cmp [FDD_Track],80
|
||||
jne save_image_1
|
||||
unnecessary_save_image:
|
||||
mov [fdc_irq_func],fdc_null
|
||||
popa
|
||||
mov [flp_status],0
|
||||
ret
|
||||
|
626
kernel/branches/kolibri-cfg/blkdev/flp_drv.inc
Normal file
626
kernel/branches/kolibri-cfg/blkdev/flp_drv.inc
Normal file
@ -0,0 +1,626 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
;**********************************************************
|
||||
; Непосредственная работа с контроллером гибкого диска
|
||||
;**********************************************************
|
||||
; Автор исходного текста Кулаков Владимир Геннадьевич.
|
||||
; Адаптация и доработка Mario79
|
||||
|
||||
;give_back_application_data: ; переслать приложению
|
||||
; mov edi,[TASK_BASE]
|
||||
; mov edi,[edi+TASKDATA.mem_start]
|
||||
; add edi,ecx
|
||||
give_back_application_data_1:
|
||||
mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000
|
||||
xor ecx,ecx
|
||||
mov cx,128
|
||||
cld
|
||||
rep movsd
|
||||
ret
|
||||
|
||||
;take_data_from_application: ; взять из приложени
|
||||
; mov esi,[TASK_BASE]
|
||||
; mov esi,[esi+TASKDATA.mem_start]
|
||||
; add esi,ecx
|
||||
take_data_from_application_1:
|
||||
mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000
|
||||
xor ecx,ecx
|
||||
mov cx,128
|
||||
cld
|
||||
rep movsd
|
||||
ret
|
||||
|
||||
; Коды завершения операции с контроллером (FDC_Status)
|
||||
FDC_Normal equ 0 ;нормальное завершение
|
||||
FDC_TimeOut equ 1 ;ошибка тайм-аута
|
||||
FDC_DiskNotFound equ 2 ;в дисководе нет диска
|
||||
FDC_TrackNotFound equ 3 ;дорожка не найдена
|
||||
FDC_SectorNotFound equ 4 ;сектор не найден
|
||||
|
||||
; Максимальные значения координат сектора (заданные
|
||||
; значения соответствуют параметрам стандартного
|
||||
; трехдюймового гибкого диска объемом 1,44 Мб)
|
||||
MAX_Track equ 79
|
||||
MAX_Head equ 1
|
||||
MAX_Sector equ 18
|
||||
|
||||
uglobal
|
||||
; Счетчик тиков таймера
|
||||
TickCounter dd ?
|
||||
; Код завершения операции с контроллером НГМД
|
||||
FDC_Status DB ?
|
||||
; Флаг прерывания от НГМД
|
||||
FDD_IntFlag DB ?
|
||||
; Момент начала последней операции с НГМД
|
||||
FDD_Time DD ?
|
||||
; Номер дисковода
|
||||
FDD_Type db 0
|
||||
; Координаты сектора
|
||||
FDD_Track DB ?
|
||||
FDD_Head DB ?
|
||||
FDD_Sector DB ?
|
||||
|
||||
; Блок результата операции
|
||||
FDC_ST0 DB ?
|
||||
FDC_ST1 DB ?
|
||||
FDC_ST2 DB ?
|
||||
FDC_C DB ?
|
||||
FDC_H DB ?
|
||||
FDC_R DB ?
|
||||
FDC_N DB ?
|
||||
; Счетчик повторения операции чтени
|
||||
ReadRepCounter DB ?
|
||||
; Счетчик повторения операции рекалибровки
|
||||
RecalRepCounter DB ?
|
||||
endg
|
||||
; Область памяти для хранения прочитанного сектора
|
||||
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?)
|
||||
fdd_motor_status db 0
|
||||
timer_fdd_motor dd 0
|
||||
|
||||
;*************************************
|
||||
;* ИНИЦИАЛИЗАЦИЯ РЕЖИМА ПДП ДЛЯ НГМД *
|
||||
;*************************************
|
||||
Init_FDC_DMA:
|
||||
pushad
|
||||
mov al,0
|
||||
out 0x0c,al ; reset the flip-flop to a known state.
|
||||
mov al,6 ; mask channel 2 so we can reprogram it.
|
||||
out 0x0a,al
|
||||
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy
|
||||
out 0x0b,al
|
||||
mov al,0
|
||||
out 0x0c,al ; reset the flip-flop to a known state.
|
||||
mov eax,0xD000
|
||||
out 0x04,al ; set the channel 2 starting address to 0
|
||||
shr eax,8
|
||||
out 0x04,al
|
||||
shr eax,8
|
||||
out 0x81,al
|
||||
mov al,0
|
||||
out 0x0c, al ; reset flip-flop
|
||||
mov al, 0xff ;set count (actual size -1)
|
||||
out 0x5, al
|
||||
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215)
|
||||
out 0x5,al
|
||||
mov al,2
|
||||
out 0xa,al
|
||||
popad
|
||||
ret
|
||||
|
||||
;***********************************
|
||||
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC *
|
||||
;* Параметры: *
|
||||
;* AL - выводимый байт. *
|
||||
;***********************************
|
||||
FDCDataOutput:
|
||||
; pusha
|
||||
push eax ecx edx
|
||||
mov AH,AL ;запомнить байт в AH
|
||||
; Сбросить переменную состояния контроллера
|
||||
mov [FDC_Status],FDC_Normal
|
||||
; Проверить готовность контроллера к приему данных
|
||||
mov DX,3F4h ;(порт состояния FDC)
|
||||
mov ecx, 0x10000 ;установить счетчик тайм-аута
|
||||
@@TestRS:
|
||||
in AL,DX ;прочитать регистр RS
|
||||
and AL,0C0h ;выделить разряды 6 и 7
|
||||
cmp AL,80h ;проверить разряды 6 и 7
|
||||
je @@OutByteToFDC
|
||||
loop @@TestRS
|
||||
; Ошибка тайм-аута
|
||||
mov [FDC_Status],FDC_TimeOut
|
||||
jmp @@End_5
|
||||
; Вывести байт в порт данных
|
||||
@@OutByteToFDC:
|
||||
inc DX
|
||||
mov AL,AH
|
||||
out DX,AL
|
||||
@@End_5:
|
||||
; popa
|
||||
pop edx ecx eax
|
||||
ret
|
||||
|
||||
;******************************************
|
||||
;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC *
|
||||
;* Процедура не имеет входных параметров. *
|
||||
;* Выходные данные: *
|
||||
;* AL - считанный байт. *
|
||||
;******************************************
|
||||
FDCDataInput:
|
||||
push ECX
|
||||
push DX
|
||||
; Сбросить переменную состояния контроллера
|
||||
mov [FDC_Status],FDC_Normal
|
||||
; Проверить готовность контроллера к передаче данных
|
||||
mov DX,3F4h ;(порт состояния FDC)
|
||||
xor CX,CX ;установить счетчик тайм-аута
|
||||
@@TestRS_1:
|
||||
in AL,DX ;прочитать регистр RS
|
||||
and AL,0C0h ;выдлить разряды 6 и 7
|
||||
cmp AL,0C0h ;проверить разряды 6 и 7
|
||||
je @@GetByteFromFDC
|
||||
loop @@TestRS_1
|
||||
; Ошибка тайм-аута
|
||||
mov [FDC_Status],FDC_TimeOut
|
||||
jmp @@End_6
|
||||
; Ввести байт из порта данных
|
||||
@@GetByteFromFDC:
|
||||
inc DX
|
||||
in AL,DX
|
||||
@@End_6: pop DX
|
||||
pop ECX
|
||||
ret
|
||||
|
||||
;*********************************************
|
||||
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
|
||||
;*********************************************
|
||||
FDCInterrupt:
|
||||
; Установить флаг прерывани
|
||||
mov [FDD_IntFlag],1
|
||||
ret
|
||||
|
||||
|
||||
;******************************************
|
||||
;* УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЙ *
|
||||
;* НГМД *
|
||||
;******************************************
|
||||
SetUserInterrupts:
|
||||
mov [fdc_irq_func],FDCInterrupt
|
||||
ret
|
||||
|
||||
;*******************************************
|
||||
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
|
||||
;*******************************************
|
||||
WaitFDCInterrupt:
|
||||
pusha
|
||||
; Сбросить байт состояния операции
|
||||
mov [FDC_Status],FDC_Normal
|
||||
; Сбросить флаг прерывани
|
||||
mov [FDD_IntFlag],0
|
||||
; Обнулить счетчик тиков
|
||||
mov eax,[timer_ticks]
|
||||
mov [TickCounter],eax
|
||||
; Ожидать установки флага прерывания НГМД
|
||||
@@TestRS_2:
|
||||
cmp [FDD_IntFlag],0
|
||||
jnz @@End_7 ;прерывание произошло
|
||||
call change_task
|
||||
mov eax,[timer_ticks]
|
||||
sub eax,[TickCounter]
|
||||
cmp eax,50 ;25 ;5 ;ожидать 5 тиков
|
||||
jb @@TestRS_2
|
||||
; jl @@TestRS_2
|
||||
; Ошибка тайм-аута
|
||||
mov [FDC_Status],FDC_TimeOut
|
||||
; mov [flp_status],0
|
||||
@@End_7: popa
|
||||
ret
|
||||
|
||||
;*********************************
|
||||
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
|
||||
;*********************************
|
||||
FDDMotorON:
|
||||
pusha
|
||||
; cmp [fdd_motor_status],1
|
||||
; je fdd_motor_on
|
||||
mov al,[flp_number]
|
||||
cmp [fdd_motor_status],al
|
||||
je fdd_motor_on
|
||||
; Произвести сброс контроллера НГМД
|
||||
mov DX,3F2h ;порт управления двигателями
|
||||
mov AL,0
|
||||
out DX,AL
|
||||
; Выбрать и включить мотор дисковода
|
||||
cmp [flp_number],1
|
||||
jne FDDMotorON_B
|
||||
; call FDDMotorOFF_B
|
||||
mov AL,1Ch ; Floppy A
|
||||
jmp FDDMotorON_1
|
||||
FDDMotorON_B:
|
||||
; call FDDMotorOFF_A
|
||||
mov AL,2Dh ; Floppy B
|
||||
FDDMotorON_1:
|
||||
out DX,AL
|
||||
; Обнулить счетчик тиков
|
||||
mov eax,[timer_ticks]
|
||||
mov [TickCounter],eax
|
||||
; Ожидать 0,5 с
|
||||
@@dT:
|
||||
call change_task
|
||||
mov eax,[timer_ticks]
|
||||
sub eax,[TickCounter]
|
||||
cmp eax,50 ;10
|
||||
jb @@dT
|
||||
cmp [flp_number],1
|
||||
jne fdd_motor_on_B
|
||||
mov [fdd_motor_status],1
|
||||
jmp fdd_motor_on
|
||||
fdd_motor_on_B:
|
||||
mov [fdd_motor_status],2
|
||||
fdd_motor_on:
|
||||
call save_timer_fdd_motor
|
||||
popa
|
||||
ret
|
||||
|
||||
;*****************************************
|
||||
;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ *
|
||||
;*****************************************
|
||||
save_timer_fdd_motor:
|
||||
mov eax,[timer_ticks]
|
||||
mov [timer_fdd_motor],eax
|
||||
ret
|
||||
|
||||
;*****************************************
|
||||
;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА *
|
||||
;*****************************************
|
||||
align 4
|
||||
check_fdd_motor_status:
|
||||
cmp [fdd_motor_status],0
|
||||
je end_check_fdd_motor_status_1
|
||||
mov eax,[timer_ticks]
|
||||
sub eax,[timer_fdd_motor]
|
||||
cmp eax,500
|
||||
jb end_check_fdd_motor_status
|
||||
call FDDMotorOFF
|
||||
mov [fdd_motor_status],0
|
||||
end_check_fdd_motor_status_1:
|
||||
mov [flp_status],0
|
||||
end_check_fdd_motor_status:
|
||||
ret
|
||||
|
||||
;**********************************
|
||||
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА *
|
||||
;**********************************
|
||||
FDDMotorOFF:
|
||||
push AX
|
||||
push DX
|
||||
cmp [flp_number],1
|
||||
jne FDDMotorOFF_1
|
||||
call FDDMotorOFF_A
|
||||
jmp FDDMotorOFF_2
|
||||
FDDMotorOFF_1:
|
||||
call FDDMotorOFF_B
|
||||
FDDMotorOFF_2:
|
||||
pop DX
|
||||
pop AX
|
||||
; сброс флагов кеширования в связи с устареванием информации
|
||||
mov [root_read],0
|
||||
mov [flp_fat],0
|
||||
ret
|
||||
|
||||
FDDMotorOFF_A:
|
||||
mov DX,3F2h ;порт управления двигателями
|
||||
mov AL,0Ch ; Floppy A
|
||||
out DX,AL
|
||||
ret
|
||||
|
||||
FDDMotorOFF_B:
|
||||
mov DX,3F2h ;порт управления двигателями
|
||||
mov AL,5h ; Floppy B
|
||||
out DX,AL
|
||||
ret
|
||||
|
||||
;*******************************
|
||||
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
|
||||
;*******************************
|
||||
RecalibrateFDD:
|
||||
pusha
|
||||
call save_timer_fdd_motor
|
||||
; Подать команду "Рекалибровка"
|
||||
mov AL,07h
|
||||
call FDCDataOutput
|
||||
mov AL,00h
|
||||
call FDCDataOutput
|
||||
; Ожидать завершения операции
|
||||
call WaitFDCInterrupt
|
||||
; cmp [FDC_Status],0
|
||||
; je no_fdc_status_error
|
||||
; mov [flp_status],0
|
||||
;no_fdc_status_error:
|
||||
call save_timer_fdd_motor
|
||||
popa
|
||||
ret
|
||||
|
||||
;*****************************************************
|
||||
;* ПОИСК ДОРОЖКИ *
|
||||
;* Параметры передаются через глобальные переменные: *
|
||||
;* FDD_Track - номер дорожки (0-79); *
|
||||
;* FDD_Head - номер головки (0-1). *
|
||||
;* Результат операции заносится в FDC_Status. *
|
||||
;*****************************************************
|
||||
SeekTrack:
|
||||
pusha
|
||||
call save_timer_fdd_motor
|
||||
; Подать команду "Поиск"
|
||||
mov AL,0Fh
|
||||
call FDCDataOutput
|
||||
; Передать байт номера головки/накопител
|
||||
mov AL,[FDD_Head]
|
||||
shl AL,2
|
||||
call FDCDataOutput
|
||||
; Передать байт номера дорожки
|
||||
mov AL,[FDD_Track]
|
||||
call FDCDataOutput
|
||||
; Ожидать завершения операции
|
||||
call WaitFDCInterrupt
|
||||
cmp [FDC_Status],FDC_Normal
|
||||
jne @@Exit
|
||||
; Сохранить результат поиска
|
||||
mov AL,08h
|
||||
call FDCDataOutput
|
||||
call FDCDataInput
|
||||
mov [FDC_ST0],AL
|
||||
call FDCDataInput
|
||||
mov [FDC_C],AL
|
||||
; Проверить результат поиска
|
||||
; Поиск завершен?
|
||||
test [FDC_ST0],100000b
|
||||
je @@Err
|
||||
; Заданный трек найден?
|
||||
mov AL,[FDC_C]
|
||||
cmp AL,[FDD_Track]
|
||||
jne @@Err
|
||||
; Номер головки совпадает с заданным?
|
||||
mov AL,[FDC_ST0]
|
||||
and AL,100b
|
||||
shr AL,2
|
||||
cmp AL,[FDD_Head]
|
||||
jne @@Err
|
||||
; Операция завершена успешно
|
||||
mov [FDC_Status],FDC_Normal
|
||||
jmp @@Exit
|
||||
@@Err: ; Трек не найден
|
||||
mov [FDC_Status],FDC_TrackNotFound
|
||||
; mov [flp_status],0
|
||||
@@Exit:
|
||||
call save_timer_fdd_motor
|
||||
popa
|
||||
ret
|
||||
|
||||
;*******************************************************
|
||||
;* ЧТЕНИЕ СЕКТОРА ДАННЫХ *
|
||||
;* Параметры передаются через глобальные переменные: *
|
||||
;* FDD_Track - номер дорожки (0-79); *
|
||||
;* FDD_Head - номер головки (0-1); *
|
||||
;* FDD_Sector - номер сектора (1-18). *
|
||||
;* Результат операции заносится в FDC_Status. *
|
||||
;* В случае успешного выполнения операции чтения *
|
||||
;* содержимое сектора будет занесено в FDD_DataBuffer. *
|
||||
;*******************************************************
|
||||
ReadSector:
|
||||
pushad
|
||||
call save_timer_fdd_motor
|
||||
; Установить скорость передачи 500 Кбайт/с
|
||||
mov AX,0
|
||||
mov DX,03F7h
|
||||
out DX,AL
|
||||
; Инициализировать канал прямого доступа к памяти
|
||||
mov [dmamode],0x46
|
||||
call Init_FDC_DMA
|
||||
; Подать команду "Чтение данных"
|
||||
mov AL,0E6h ;чтение в мультитрековом режиме
|
||||
call FDCDataOutput
|
||||
mov AL,[FDD_Head]
|
||||
shl AL,2
|
||||
call FDCDataOutput
|
||||
mov AL,[FDD_Track]
|
||||
call FDCDataOutput
|
||||
mov AL,[FDD_Head]
|
||||
call FDCDataOutput
|
||||
mov AL,[FDD_Sector]
|
||||
call FDCDataOutput
|
||||
mov AL,2 ;код размера сектора (512 байт)
|
||||
call FDCDataOutput
|
||||
mov AL,18 ;+1; 3Fh ;число секторов на дорожке
|
||||
call FDCDataOutput
|
||||
mov AL,1Bh ;значение GPL
|
||||
call FDCDataOutput
|
||||
mov AL,0FFh ;значение DTL
|
||||
call FDCDataOutput
|
||||
; Ожидаем прерывание по завершении операции
|
||||
call WaitFDCInterrupt
|
||||
cmp [FDC_Status],FDC_Normal
|
||||
jne @@Exit_1
|
||||
; Считываем статус завершения операции
|
||||
call GetStatusInfo
|
||||
test [FDC_ST0],11011000b
|
||||
jnz @@Err_1
|
||||
mov [FDC_Status],FDC_Normal
|
||||
jmp @@Exit_1
|
||||
@@Err_1: mov [FDC_Status],FDC_SectorNotFound
|
||||
; mov [flp_status],0
|
||||
@@Exit_1:
|
||||
call save_timer_fdd_motor
|
||||
popad
|
||||
ret
|
||||
|
||||
;*******************************************************
|
||||
;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) *
|
||||
;* Параметры передаются через глобальные переменные: *
|
||||
;* FDD_Track - номер дорожки (0-79); *
|
||||
;* FDD_Head - номер головки (0-1); *
|
||||
;* FDD_Sector - номер сектора (1-18). *
|
||||
;* Результат операции заносится в FDC_Status. *
|
||||
;* В случае успешного выполнения операции чтения *
|
||||
;* содержимое сектора будет занесено в FDD_DataBuffer. *
|
||||
;*******************************************************
|
||||
ReadSectWithRetr:
|
||||
pusha
|
||||
; Обнулить счетчик повторения операции рекалибровки
|
||||
mov [RecalRepCounter],0
|
||||
@@TryAgain:
|
||||
; Обнулить счетчик повторения операции чтени
|
||||
mov [ReadRepCounter],0
|
||||
@@ReadSector_1:
|
||||
call ReadSector
|
||||
cmp [FDC_Status],0
|
||||
je @@Exit_2
|
||||
cmp [FDC_Status],1
|
||||
je @@Err_3
|
||||
; Троекратное повторение чтени
|
||||
inc [ReadRepCounter]
|
||||
cmp [ReadRepCounter],3
|
||||
jb @@ReadSector_1
|
||||
; Троекратное повторение рекалибровки
|
||||
call RecalibrateFDD
|
||||
call SeekTrack
|
||||
inc [RecalRepCounter]
|
||||
cmp [RecalRepCounter],3
|
||||
jb @@TryAgain
|
||||
; mov [flp_status],0
|
||||
@@Exit_2:
|
||||
popa
|
||||
ret
|
||||
@@Err_3:
|
||||
mov [flp_status],0
|
||||
popa
|
||||
ret
|
||||
|
||||
;*******************************************************
|
||||
;* ЗАПИСЬ СЕКТОРА ДАННЫХ *
|
||||
;* Параметры передаются через глобальные переменные: *
|
||||
;* FDD_Track - номер дорожки (0-79); *
|
||||
;* FDD_Head - номер головки (0-1); *
|
||||
;* FDD_Sector - номер сектора (1-18). *
|
||||
;* Результат операции заносится в FDC_Status. *
|
||||
;* В случае успешного выполнения операции записи *
|
||||
;* содержимое FDD_DataBuffer будет занесено в сектор. *
|
||||
;*******************************************************
|
||||
WriteSector:
|
||||
pushad
|
||||
call save_timer_fdd_motor
|
||||
; Установить скорость передачи 500 Кбайт/с
|
||||
mov AX,0
|
||||
mov DX,03F7h
|
||||
out DX,AL
|
||||
; Инициализировать канал прямого доступа к памяти
|
||||
mov [dmamode],0x4A
|
||||
call Init_FDC_DMA
|
||||
; Подать команду "Запись данных"
|
||||
mov AL,0xC5 ;0x45 ;запись в мультитрековом режиме
|
||||
call FDCDataOutput
|
||||
mov AL,[FDD_Head]
|
||||
shl AL,2
|
||||
call FDCDataOutput
|
||||
mov AL,[FDD_Track]
|
||||
call FDCDataOutput
|
||||
mov AL,[FDD_Head]
|
||||
call FDCDataOutput
|
||||
mov AL,[FDD_Sector]
|
||||
call FDCDataOutput
|
||||
mov AL,2 ;код размера сектора (512 байт)
|
||||
call FDCDataOutput
|
||||
mov AL,18; 3Fh ;число секторов на дорожке
|
||||
call FDCDataOutput
|
||||
mov AL,1Bh ;значение GPL
|
||||
call FDCDataOutput
|
||||
mov AL,0FFh ;значение DTL
|
||||
call FDCDataOutput
|
||||
; Ожидаем прерывание по завершении операции
|
||||
call WaitFDCInterrupt
|
||||
cmp [FDC_Status],FDC_Normal
|
||||
jne @@Exit_3
|
||||
; Считываем статус завершения операции
|
||||
call GetStatusInfo
|
||||
test [FDC_ST0],11000000b ;11011000b
|
||||
jnz @@Err_2
|
||||
mov [FDC_Status],FDC_Normal
|
||||
jmp @@Exit_3
|
||||
@@Err_2: mov [FDC_Status],FDC_SectorNotFound
|
||||
@@Exit_3:
|
||||
call save_timer_fdd_motor
|
||||
popad
|
||||
ret
|
||||
|
||||
;*******************************************************
|
||||
;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) *
|
||||
;* Параметры передаются через глобальные переменные: *
|
||||
;* FDD_Track - номер дорожки (0-79); *
|
||||
;* FDD_Head - номер головки (0-1); *
|
||||
;* FDD_Sector - номер сектора (1-18). *
|
||||
;* Результат операции заносится в FDC_Status. *
|
||||
;* В случае успешного выполнения операции записи *
|
||||
;* содержимое FDD_DataBuffer будет занесено в сектор. *
|
||||
;*******************************************************
|
||||
WriteSectWithRetr:
|
||||
pusha
|
||||
; Обнулить счетчик повторения операции рекалибровки
|
||||
mov [RecalRepCounter],0
|
||||
@@TryAgain_1:
|
||||
; Обнулить счетчик повторения операции чтени
|
||||
mov [ReadRepCounter],0
|
||||
@@WriteSector_1:
|
||||
call WriteSector
|
||||
cmp [FDC_Status],0
|
||||
je @@Exit_4
|
||||
cmp [FDC_Status],1
|
||||
je @@Err_4
|
||||
; Троекратное повторение чтени
|
||||
inc [ReadRepCounter]
|
||||
cmp [ReadRepCounter],3
|
||||
jb @@WriteSector_1
|
||||
; Троекратное повторение рекалибровки
|
||||
call RecalibrateFDD
|
||||
call SeekTrack
|
||||
inc [RecalRepCounter]
|
||||
cmp [RecalRepCounter],3
|
||||
jb @@TryAgain_1
|
||||
@@Exit_4:
|
||||
popa
|
||||
ret
|
||||
@@Err_4:
|
||||
mov [flp_status],0
|
||||
popa
|
||||
ret
|
||||
|
||||
;*********************************************
|
||||
;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ *
|
||||
;*********************************************
|
||||
GetStatusInfo:
|
||||
push AX
|
||||
call FDCDataInput
|
||||
mov [FDC_ST0],AL
|
||||
call FDCDataInput
|
||||
mov [FDC_ST1],AL
|
||||
call FDCDataInput
|
||||
mov [FDC_ST2],AL
|
||||
call FDCDataInput
|
||||
mov [FDC_C],AL
|
||||
call FDCDataInput
|
||||
mov [FDC_H],AL
|
||||
call FDCDataInput
|
||||
mov [FDC_R],AL
|
||||
call FDCDataInput
|
||||
mov [FDC_N],AL
|
||||
pop AX
|
||||
ret
|
||||
|
947
kernel/branches/kolibri-cfg/blkdev/hd_drv.inc
Normal file
947
kernel/branches/kolibri-cfg/blkdev/hd_drv.inc
Normal file
@ -0,0 +1,947 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
; Low-level driver for HDD access
|
||||
; DMA support by Mario79
|
||||
; Access through BIOS by diamond
|
||||
|
||||
align 4
|
||||
hd_read:
|
||||
;-----------------------------------------------------------
|
||||
; input : eax = block to read
|
||||
; ebx = destination
|
||||
;-----------------------------------------------------------
|
||||
and [hd_error], 0
|
||||
push ecx esi edi ; scan cache
|
||||
|
||||
; mov ecx,cache_max ; entries in cache
|
||||
; mov esi,HD_CACHE+8
|
||||
call calculate_cache
|
||||
add esi,8
|
||||
|
||||
mov edi,1
|
||||
|
||||
hdreadcache:
|
||||
|
||||
cmp dword [esi+4],0 ; empty
|
||||
je nohdcache
|
||||
|
||||
cmp [esi],eax ; correct sector
|
||||
je yeshdcache
|
||||
|
||||
nohdcache:
|
||||
|
||||
add esi,8
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz hdreadcache
|
||||
|
||||
call find_empty_slot ; ret in edi
|
||||
cmp [hd_error],0
|
||||
jne return_01
|
||||
; Read through BIOS?
|
||||
cmp [hdpos], 0x80
|
||||
jae .bios
|
||||
; hd_read_{dma,pio} use old ATA with 28 bit for sector number
|
||||
cmp eax, 0x10000000
|
||||
jb @f
|
||||
inc [hd_error]
|
||||
jmp return_01
|
||||
@@:
|
||||
; DMA read is permitted if [allow_dma_access]=1 or 2
|
||||
cmp [allow_dma_access], 2
|
||||
ja .nodma
|
||||
cmp [dma_hdd], 1
|
||||
jnz .nodma
|
||||
call hd_read_dma
|
||||
jmp @f
|
||||
.nodma:
|
||||
call hd_read_pio
|
||||
jmp @f
|
||||
.bios:
|
||||
call bd_read
|
||||
@@:
|
||||
cmp [hd_error], 0
|
||||
jne return_01
|
||||
; lea esi,[edi*8+HD_CACHE]
|
||||
; push eax
|
||||
call calculate_cache_1
|
||||
lea esi,[edi*8+esi]
|
||||
; pop eax
|
||||
|
||||
mov [esi],eax ; sector number
|
||||
mov dword [esi+4],1 ; hd read - mark as same as in hd
|
||||
|
||||
yeshdcache:
|
||||
|
||||
mov esi,edi
|
||||
shl esi,9
|
||||
; add esi,HD_CACHE+65536
|
||||
push eax
|
||||
call calculate_cache_2
|
||||
add esi,eax
|
||||
pop eax
|
||||
|
||||
mov edi,ebx
|
||||
mov ecx,512/4
|
||||
cld
|
||||
rep movsd ; move data
|
||||
return_01:
|
||||
pop edi esi ecx
|
||||
ret
|
||||
|
||||
align 4
|
||||
hd_read_pio:
|
||||
push eax edx
|
||||
|
||||
call wait_for_hd_idle
|
||||
cmp [hd_error],0
|
||||
jne hd_read_error
|
||||
|
||||
cli
|
||||
xor eax,eax
|
||||
mov edx,[hdbase]
|
||||
inc edx
|
||||
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩"
|
||||
inc edx
|
||||
inc eax
|
||||
out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢
|
||||
inc edx
|
||||
mov eax,[esp+4]
|
||||
out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à
|
||||
shr eax,8
|
||||
inc edx
|
||||
out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â)
|
||||
shr eax,8
|
||||
inc edx
|
||||
out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â)
|
||||
shr eax,8
|
||||
inc edx
|
||||
and al,1+2+4+8
|
||||
add al,byte [hdid]
|
||||
add al,128+64+32
|
||||
out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª
|
||||
inc edx
|
||||
mov al,20h
|
||||
out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤
|
||||
sti
|
||||
|
||||
call wait_for_sector_buffer
|
||||
|
||||
cmp [hd_error],0
|
||||
jne hd_read_error
|
||||
|
||||
cli
|
||||
push edi
|
||||
shl edi,9
|
||||
; add edi,HD_CACHE+65536
|
||||
push eax
|
||||
call calculate_cache_2
|
||||
add edi,eax
|
||||
pop eax
|
||||
|
||||
mov ecx,256
|
||||
mov edx,[hdbase]
|
||||
cld
|
||||
rep insw
|
||||
pop edi
|
||||
sti
|
||||
|
||||
pop edx eax
|
||||
ret
|
||||
|
||||
disable_ide_int:
|
||||
; mov edx,[hdbase]
|
||||
; add edx,0x206
|
||||
; mov al,2
|
||||
; out dx,al
|
||||
cli
|
||||
ret
|
||||
|
||||
enable_ide_int:
|
||||
; mov edx,[hdbase]
|
||||
; add edx,0x206
|
||||
; mov al,0
|
||||
; out dx,al
|
||||
sti
|
||||
ret
|
||||
|
||||
align 4
|
||||
hd_write:
|
||||
;-----------------------------------------------------------
|
||||
; input : eax = block
|
||||
; ebx = pointer to memory
|
||||
;-----------------------------------------------------------
|
||||
push ecx esi edi
|
||||
|
||||
; check if the cache already has the sector and overwrite it
|
||||
|
||||
; mov ecx,cache_max
|
||||
; mov esi,HD_CACHE+8
|
||||
call calculate_cache
|
||||
add esi,8
|
||||
|
||||
mov edi,1
|
||||
|
||||
hdwritecache:
|
||||
|
||||
cmp dword [esi+4],0 ; if cache slot is empty
|
||||
je not_in_cache_write
|
||||
|
||||
cmp [esi],eax ; if the slot has the sector
|
||||
je yes_in_cache_write
|
||||
|
||||
not_in_cache_write:
|
||||
|
||||
add esi,8
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz hdwritecache
|
||||
|
||||
; sector not found in cache
|
||||
; write the block to a new location
|
||||
|
||||
call find_empty_slot ; ret in edi
|
||||
cmp [hd_error],0
|
||||
jne hd_write_access_denied
|
||||
|
||||
; lea esi,[edi*8+HD_CACHE]
|
||||
; push eax
|
||||
call calculate_cache_1
|
||||
lea esi,[edi*8+esi]
|
||||
; pop eax
|
||||
|
||||
mov [esi],eax ; sector number
|
||||
|
||||
yes_in_cache_write:
|
||||
|
||||
mov dword [esi+4],2 ; write - differs from hd
|
||||
|
||||
shl edi,9
|
||||
; add edi,HD_CACHE+65536
|
||||
push eax
|
||||
call calculate_cache_2
|
||||
add edi,eax
|
||||
pop eax
|
||||
|
||||
mov esi,ebx
|
||||
mov ecx,512/4
|
||||
cld
|
||||
rep movsd ; move data
|
||||
hd_write_access_denied:
|
||||
pop edi esi ecx
|
||||
ret
|
||||
|
||||
align 4
|
||||
cache_write_pio:
|
||||
cmp dword[esi],0x10000000
|
||||
jae .bad
|
||||
; call disable_ide_int
|
||||
|
||||
call wait_for_hd_idle
|
||||
cmp [hd_error],0
|
||||
jne hd_write_error
|
||||
|
||||
cli
|
||||
xor eax,eax
|
||||
mov edx,[hdbase]
|
||||
inc edx
|
||||
out dx,al
|
||||
inc edx
|
||||
inc eax
|
||||
out dx,al
|
||||
inc edx
|
||||
mov eax,[esi] ; eax = sector to write
|
||||
out dx,al
|
||||
shr eax,8
|
||||
inc edx
|
||||
out dx,al
|
||||
shr eax,8
|
||||
inc edx
|
||||
out dx,al
|
||||
shr eax,8
|
||||
inc edx
|
||||
and al,1+2+4+8
|
||||
add al,byte [hdid]
|
||||
add al,128+64+32
|
||||
out dx,al
|
||||
inc edx
|
||||
mov al,30h
|
||||
out dx,al
|
||||
sti
|
||||
|
||||
call wait_for_sector_buffer
|
||||
|
||||
cmp [hd_error],0
|
||||
jne hd_write_error
|
||||
|
||||
push ecx esi
|
||||
|
||||
cli
|
||||
mov esi,edi
|
||||
shl esi,9
|
||||
; add esi,HD_CACHE+65536 ; esi = from memory position
|
||||
push eax
|
||||
call calculate_cache_2
|
||||
add esi,eax
|
||||
pop eax
|
||||
|
||||
mov ecx,256
|
||||
mov edx,[hdbase]
|
||||
cld
|
||||
rep outsw
|
||||
sti
|
||||
|
||||
; call enable_ide_int
|
||||
pop esi ecx
|
||||
|
||||
ret
|
||||
.bad:
|
||||
inc [hd_error]
|
||||
ret
|
||||
|
||||
save_hd_wait_timeout:
|
||||
|
||||
push eax
|
||||
mov eax,[timer_ticks]
|
||||
add eax,300 ; 3 sec timeout
|
||||
mov [hd_wait_timeout],eax
|
||||
pop eax
|
||||
ret
|
||||
|
||||
align 4
|
||||
check_hd_wait_timeout:
|
||||
|
||||
push eax
|
||||
mov eax,[hd_wait_timeout]
|
||||
cmp [timer_ticks], eax
|
||||
jg hd_timeout_error
|
||||
pop eax
|
||||
mov [hd_error],0
|
||||
ret
|
||||
|
||||
;iglobal
|
||||
; hd_timeout_str db 'K : FS - HD timeout',0
|
||||
; hd_read_str db 'K : FS - HD read error',0
|
||||
; hd_write_str db 'K : FS - HD write error',0
|
||||
; hd_lba_str db 'K : FS - HD LBA error',0
|
||||
;endg
|
||||
|
||||
hd_timeout_error:
|
||||
|
||||
; call clear_hd_cache
|
||||
; call clear_application_table_status
|
||||
; mov esi,hd_timeout_str
|
||||
; call sys_msg_board_str
|
||||
DEBUGF 1,"K : FS - HD timeout\n"
|
||||
|
||||
mov [hd_error],1
|
||||
pop eax
|
||||
ret
|
||||
|
||||
hd_read_error:
|
||||
|
||||
; call clear_hd_cache
|
||||
; call clear_application_table_status
|
||||
; mov esi,hd_read_str
|
||||
; call sys_msg_board_str
|
||||
DEBUGF 1,"K : FS - HD read error\n"
|
||||
pop edx eax
|
||||
ret
|
||||
|
||||
hd_write_error:
|
||||
|
||||
; call clear_hd_cache
|
||||
; call clear_application_table_status
|
||||
; mov esi,hd_write_str
|
||||
; call sys_msg_board_str
|
||||
DEBUGF 1,"K : FS - HD write error\n"
|
||||
ret
|
||||
|
||||
hd_write_error_dma:
|
||||
; call clear_hd_cache
|
||||
; call clear_application_table_status
|
||||
; mov esi, hd_write_str
|
||||
; call sys_msg_board_str
|
||||
DEBUGF 1,"K : FS - HD read error\n"
|
||||
pop esi
|
||||
ret
|
||||
|
||||
hd_lba_error:
|
||||
; call clear_hd_cache
|
||||
; call clear_application_table_status
|
||||
; mov esi,hd_lba_str
|
||||
; call sys_msg_board_str
|
||||
DEBUGF 1,"K : FS - HD LBA error\n"
|
||||
jmp LBA_read_ret
|
||||
|
||||
|
||||
align 4
|
||||
wait_for_hd_idle:
|
||||
|
||||
push eax edx
|
||||
|
||||
call save_hd_wait_timeout
|
||||
|
||||
mov edx,[hdbase]
|
||||
add edx,0x7
|
||||
|
||||
wfhil1:
|
||||
|
||||
call check_hd_wait_timeout
|
||||
cmp [hd_error],0
|
||||
jne @f
|
||||
|
||||
in al,dx
|
||||
test al,128
|
||||
jnz wfhil1
|
||||
|
||||
@@:
|
||||
|
||||
pop edx eax
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
wait_for_sector_buffer:
|
||||
|
||||
push eax edx
|
||||
|
||||
mov edx,[hdbase]
|
||||
add edx,0x7
|
||||
|
||||
call save_hd_wait_timeout
|
||||
|
||||
hdwait_sbuf: ; wait for sector buffer to be ready
|
||||
|
||||
call check_hd_wait_timeout
|
||||
cmp [hd_error],0
|
||||
jne @f
|
||||
|
||||
in al,dx
|
||||
test al,8
|
||||
jz hdwait_sbuf
|
||||
|
||||
mov [hd_error],0
|
||||
|
||||
cmp [hd_setup],1 ; do not mark error for setup request
|
||||
je buf_wait_ok
|
||||
|
||||
test al,1 ; previous command ended up with an error
|
||||
jz buf_wait_ok
|
||||
@@:
|
||||
mov [hd_error],1
|
||||
|
||||
buf_wait_ok:
|
||||
|
||||
pop edx eax
|
||||
ret
|
||||
|
||||
; \begin{Mario79}
|
||||
align 4
|
||||
wait_for_sector_dma_ide0:
|
||||
push eax
|
||||
push edx
|
||||
call save_hd_wait_timeout
|
||||
.wait:
|
||||
call change_task
|
||||
cmp [irq14_func], hdd_irq14
|
||||
jnz .done
|
||||
call check_hd_wait_timeout
|
||||
cmp [hd_error], 0
|
||||
jz .wait
|
||||
mov [irq14_func], hdd_irq_null
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
mov al, 0
|
||||
out dx, al
|
||||
.done:
|
||||
pop edx
|
||||
pop eax
|
||||
ret
|
||||
|
||||
align 4
|
||||
wait_for_sector_dma_ide1:
|
||||
push eax
|
||||
push edx
|
||||
call save_hd_wait_timeout
|
||||
.wait:
|
||||
call change_task
|
||||
cmp [irq15_func], hdd_irq15
|
||||
jnz .done
|
||||
call check_hd_wait_timeout
|
||||
cmp [hd_error], 0
|
||||
jz .wait
|
||||
mov [irq15_func], hdd_irq_null
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
add dx, 8
|
||||
mov al, 0
|
||||
out dx, al
|
||||
.done:
|
||||
pop edx
|
||||
pop eax
|
||||
ret
|
||||
|
||||
iglobal
|
||||
align 4
|
||||
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
|
||||
IDE_descriptor_table:
|
||||
dd IDE_DMA
|
||||
dw 0x2000
|
||||
dw 0x8000
|
||||
|
||||
dma_cur_sector dd not 40h
|
||||
dma_hdpos dd 0
|
||||
irq14_func dd hdd_irq_null
|
||||
irq15_func dd hdd_irq_null
|
||||
endg
|
||||
|
||||
uglobal
|
||||
; all uglobals are zeroed at boot
|
||||
dma_process dd 0
|
||||
dma_slot_ptr dd 0
|
||||
cache_chain_pos dd 0
|
||||
cache_chain_ptr dd 0
|
||||
cache_chain_size db 0
|
||||
cache_chain_started db 0
|
||||
dma_task_switched db 0
|
||||
dma_hdd db 0
|
||||
allow_dma_access db 0
|
||||
endg
|
||||
|
||||
align 4
|
||||
hdd_irq14:
|
||||
pushfd
|
||||
cli
|
||||
pushad
|
||||
mov [irq14_func], hdd_irq_null
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
mov al, 0
|
||||
out dx, al
|
||||
; call update_counters
|
||||
; mov ebx, [dma_process]
|
||||
; cmp [CURRENT_TASK], ebx
|
||||
; jz .noswitch
|
||||
; mov [dma_task_switched], 1
|
||||
; mov edi, [dma_slot_ptr]
|
||||
; mov eax, [CURRENT_TASK]
|
||||
; mov [dma_process], eax
|
||||
; mov eax, [TASK_BASE]
|
||||
; mov [dma_slot_ptr], eax
|
||||
; mov [CURRENT_TASK], ebx
|
||||
; mov [TASK_BASE], edi
|
||||
; mov byte [DONT_SWITCH], 1
|
||||
; call do_change_task
|
||||
.noswitch:
|
||||
popad
|
||||
popfd
|
||||
align 4
|
||||
hdd_irq_null:
|
||||
ret
|
||||
|
||||
align 4
|
||||
hdd_irq15:
|
||||
pushfd
|
||||
cli
|
||||
pushad
|
||||
mov [irq15_func], hdd_irq_null
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
add dx, 8
|
||||
mov al, 0
|
||||
out dx, al
|
||||
; call update_counters
|
||||
; mov ebx, [dma_process]
|
||||
; cmp [CURRENT_TASK], ebx
|
||||
; jz .noswitch
|
||||
; mov [dma_task_switched], 1
|
||||
; mov edi, [dma_slot_ptr]
|
||||
; mov eax, [CURRENT_TASK]
|
||||
; mov [dma_process], eax
|
||||
; mov eax, [TASK_BASE]
|
||||
; mov [dma_slot_ptr], eax
|
||||
; mov [CURRENT_TASK], ebx
|
||||
; mov [TASK_BASE], edi
|
||||
; mov byte [DONT_SWITCH], 1
|
||||
; call do_change_task
|
||||
.noswitch:
|
||||
popad
|
||||
popfd
|
||||
ret
|
||||
|
||||
align 4
|
||||
hd_read_dma:
|
||||
push eax
|
||||
push edx
|
||||
mov edx,[dma_hdpos]
|
||||
cmp edx,[hdpos]
|
||||
jne .notread
|
||||
mov edx, [dma_cur_sector]
|
||||
cmp eax, edx
|
||||
jb .notread
|
||||
add edx, 15
|
||||
cmp [esp+4], edx
|
||||
ja .notread
|
||||
mov eax, [esp+4]
|
||||
sub eax, [dma_cur_sector]
|
||||
shl eax, 9
|
||||
add eax, (OS_BASE+IDE_DMA)
|
||||
push ecx esi edi
|
||||
mov esi, eax
|
||||
shl edi, 9
|
||||
; add edi, HD_CACHE+0x10000
|
||||
push eax
|
||||
call calculate_cache_2
|
||||
add edi,eax
|
||||
pop eax
|
||||
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
pop edi esi ecx
|
||||
pop edx
|
||||
pop eax
|
||||
ret
|
||||
.notread:
|
||||
mov eax, IDE_descriptor_table
|
||||
mov dword [eax], IDE_DMA
|
||||
mov word [eax+4], 0x2000
|
||||
sub eax, OS_BASE
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
cmp [hdbase], 0x1F0
|
||||
jz @f
|
||||
add edx, 8
|
||||
@@:
|
||||
push edx
|
||||
add edx, 4
|
||||
out dx, eax
|
||||
pop edx
|
||||
mov al, 0
|
||||
out dx, al
|
||||
add edx, 2
|
||||
mov al, 6
|
||||
out dx, al
|
||||
call wait_for_hd_idle
|
||||
cmp [hd_error], 0
|
||||
jnz hd_read_error
|
||||
call disable_ide_int
|
||||
xor eax, eax
|
||||
mov edx, [hdbase]
|
||||
inc edx
|
||||
out dx, al
|
||||
inc edx
|
||||
mov eax, 10h
|
||||
out dx, al
|
||||
inc edx
|
||||
mov eax, [esp+4]
|
||||
out dx, al
|
||||
shr eax, 8
|
||||
inc edx
|
||||
out dx, al
|
||||
shr eax, 8
|
||||
inc edx
|
||||
out dx, al
|
||||
shr eax, 8
|
||||
inc edx
|
||||
and al, 0xF
|
||||
add al, byte [hdid]
|
||||
add al, 11100000b
|
||||
out dx, al
|
||||
inc edx
|
||||
mov al, 0xC8
|
||||
out dx, al
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
cmp [hdbase], 0x1F0
|
||||
jz @f
|
||||
add dx, 8
|
||||
@@:
|
||||
mov al, 9
|
||||
out dx, al
|
||||
mov eax, [CURRENT_TASK]
|
||||
mov [dma_process], eax
|
||||
mov eax, [TASK_BASE]
|
||||
mov [dma_slot_ptr], eax
|
||||
cmp [hdbase], 0x1F0
|
||||
jnz .ide1
|
||||
mov [irq14_func], hdd_irq14
|
||||
jmp @f
|
||||
.ide1:
|
||||
mov [irq15_func], hdd_irq15
|
||||
@@:
|
||||
call enable_ide_int
|
||||
cmp [hdbase], 0x1F0
|
||||
jnz .wait_ide1
|
||||
call wait_for_sector_dma_ide0
|
||||
jmp @f
|
||||
.wait_ide1:
|
||||
call wait_for_sector_dma_ide1
|
||||
@@:
|
||||
cmp [hd_error], 0
|
||||
jnz hd_read_error
|
||||
mov eax,[hdpos]
|
||||
mov [dma_hdpos],eax
|
||||
pop edx
|
||||
pop eax
|
||||
mov [dma_cur_sector], eax
|
||||
jmp hd_read_dma
|
||||
|
||||
align 4
|
||||
write_cache_sector:
|
||||
mov [cache_chain_size],1
|
||||
mov [cache_chain_pos],edi
|
||||
write_cache_chain:
|
||||
cmp [hdpos], 0x80
|
||||
jae bd_write_cache_chain
|
||||
mov eax,[cache_chain_ptr]
|
||||
cmp dword[eax],0x10000000
|
||||
jae .bad
|
||||
push esi
|
||||
mov eax, IDE_descriptor_table
|
||||
mov edx,eax
|
||||
pusha
|
||||
mov esi,[cache_chain_pos]
|
||||
shl esi, 9
|
||||
call calculate_cache_2
|
||||
add esi,eax
|
||||
mov edi, (OS_BASE+IDE_DMA)
|
||||
mov dword [edx], IDE_DMA
|
||||
movzx ecx, [cache_chain_size]
|
||||
shl ecx, 9
|
||||
mov word [edx+4], cx
|
||||
shr ecx,2
|
||||
cld
|
||||
rep movsd
|
||||
popa
|
||||
sub eax, OS_BASE
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
cmp [hdbase], 0x1F0
|
||||
jz @f
|
||||
add edx, 8
|
||||
@@:
|
||||
push edx
|
||||
add edx, 4
|
||||
out dx, eax
|
||||
pop edx
|
||||
mov al, 0
|
||||
out dx, al
|
||||
add edx, 2
|
||||
mov al, 6
|
||||
out dx, al
|
||||
call wait_for_hd_idle
|
||||
cmp [hd_error], 0
|
||||
jnz hd_write_error_dma
|
||||
call disable_ide_int
|
||||
xor eax, eax
|
||||
mov edx, [hdbase]
|
||||
inc edx
|
||||
out dx, al
|
||||
inc edx
|
||||
mov al, [cache_chain_size]
|
||||
out dx, al
|
||||
inc edx
|
||||
mov esi, [cache_chain_ptr]
|
||||
mov eax, [esi]
|
||||
out dx, al
|
||||
shr eax, 8
|
||||
inc edx
|
||||
out dx, al
|
||||
shr eax, 8
|
||||
inc edx
|
||||
out dx, al
|
||||
shr eax, 8
|
||||
inc edx
|
||||
and al, 0xF
|
||||
add al, byte [hdid]
|
||||
add al, 11100000b
|
||||
out dx, al
|
||||
inc edx
|
||||
mov al, 0xCA
|
||||
out dx, al
|
||||
mov dx, [IDEContrRegsBaseAddr]
|
||||
cmp [hdbase], 0x1F0
|
||||
jz @f
|
||||
add dx, 8
|
||||
@@:
|
||||
mov al, 1
|
||||
out dx, al
|
||||
mov eax, [CURRENT_TASK]
|
||||
mov [dma_process], eax
|
||||
mov eax, [TASK_BASE]
|
||||
mov [dma_slot_ptr], eax
|
||||
cmp [hdbase], 0x1F0
|
||||
jnz .ide1
|
||||
mov [irq14_func], hdd_irq14
|
||||
jmp @f
|
||||
.ide1:
|
||||
mov [irq15_func], hdd_irq15
|
||||
@@:
|
||||
call enable_ide_int
|
||||
mov [dma_cur_sector], not 0x40
|
||||
cmp [hdbase], 0x1F0
|
||||
jnz .wait_ide1
|
||||
call wait_for_sector_dma_ide0
|
||||
jmp @f
|
||||
.wait_ide1:
|
||||
call wait_for_sector_dma_ide1
|
||||
@@:
|
||||
cmp [hd_error], 0
|
||||
jnz hd_write_error_dma
|
||||
pop esi
|
||||
ret
|
||||
.bad:
|
||||
inc [hd_error]
|
||||
ret
|
||||
|
||||
uglobal
|
||||
IDEContrRegsBaseAddr dw ?
|
||||
endg
|
||||
; \end{Mario79}
|
||||
|
||||
; \begin{diamond}
|
||||
uglobal
|
||||
bios_hdpos dd 0 ; 0 is invalid value for [hdpos]
|
||||
bios_cur_sector dd ?
|
||||
bios_read_len dd ?
|
||||
endg
|
||||
bd_read:
|
||||
push eax
|
||||
push edx
|
||||
mov edx, [bios_hdpos]
|
||||
cmp edx, [hdpos]
|
||||
jne .notread
|
||||
mov edx, [bios_cur_sector]
|
||||
cmp eax, edx
|
||||
jb .notread
|
||||
add edx, [bios_read_len]
|
||||
dec edx
|
||||
cmp eax, edx
|
||||
ja .notread
|
||||
sub eax, [bios_cur_sector]
|
||||
shl eax, 9
|
||||
add eax, (OS_BASE+0x9A000)
|
||||
push ecx esi edi
|
||||
mov esi, eax
|
||||
shl edi, 9
|
||||
; add edi, HD_CACHE+0x10000
|
||||
push eax
|
||||
call calculate_cache_2
|
||||
add edi,eax
|
||||
pop eax
|
||||
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
pop edi esi ecx
|
||||
pop edx
|
||||
pop eax
|
||||
ret
|
||||
.notread:
|
||||
push ecx
|
||||
mov dl, 42h
|
||||
mov ecx, 16
|
||||
call int13_call
|
||||
pop ecx
|
||||
test eax, eax
|
||||
jnz .v86err
|
||||
test edx, edx
|
||||
jz .readerr
|
||||
mov [bios_read_len], edx
|
||||
mov edx, [hdpos]
|
||||
mov [bios_hdpos], edx
|
||||
pop edx
|
||||
pop eax
|
||||
mov [bios_cur_sector], eax
|
||||
jmp bd_read
|
||||
.readerr:
|
||||
.v86err:
|
||||
mov [hd_error], 1
|
||||
jmp hd_read_error
|
||||
|
||||
bd_write_cache_chain:
|
||||
pusha
|
||||
mov esi, [cache_chain_pos]
|
||||
shl esi, 9
|
||||
call calculate_cache_2
|
||||
add esi, eax
|
||||
mov edi, OS_BASE + 0x9A000
|
||||
movzx ecx, [cache_chain_size]
|
||||
push ecx
|
||||
shl ecx, 9-2
|
||||
rep movsd
|
||||
pop ecx
|
||||
mov dl, 43h
|
||||
mov eax, [cache_chain_ptr]
|
||||
mov eax, [eax]
|
||||
call int13_call
|
||||
test eax, eax
|
||||
jnz .v86err
|
||||
cmp edx, ecx
|
||||
jnz .writeerr
|
||||
popa
|
||||
ret
|
||||
.v86err:
|
||||
.writeerr:
|
||||
popa
|
||||
mov [hd_error], 1
|
||||
jmp hd_write_error
|
||||
|
||||
uglobal
|
||||
int13_regs_in rb v86_regs.size
|
||||
int13_regs_out rb v86_regs.size
|
||||
endg
|
||||
|
||||
int13_call:
|
||||
; Because this code uses fixed addresses,
|
||||
; it can not be run simultaniously by many threads.
|
||||
; In current implementation it is protected by common mutex 'hd1_status'
|
||||
mov word [OS_BASE + 510h], 10h ; packet length
|
||||
mov word [OS_BASE + 512h], cx ; number of sectors
|
||||
mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000
|
||||
mov dword [OS_BASE + 518h], eax
|
||||
and dword [OS_BASE + 51Ch], 0
|
||||
push ebx ecx esi edi
|
||||
mov ebx, int13_regs_in
|
||||
mov edi, ebx
|
||||
mov ecx, v86_regs.size/4
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
mov byte [ebx+v86_regs.eax+1], dl
|
||||
mov eax, [hdpos]
|
||||
lea eax, [BiosDisksData+(eax-80h)*4]
|
||||
mov dl, [eax]
|
||||
mov byte [ebx+v86_regs.edx], dl
|
||||
movzx edx, byte [eax+1]
|
||||
; mov dl, 5
|
||||
test edx, edx
|
||||
jnz .hasirq
|
||||
dec edx
|
||||
jmp @f
|
||||
.hasirq:
|
||||
pushad
|
||||
stdcall enable_irq, edx
|
||||
popad
|
||||
@@:
|
||||
mov word [ebx+v86_regs.esi], 510h
|
||||
mov word [ebx+v86_regs.ss], 9000h
|
||||
mov word [ebx+v86_regs.esp], 0A000h
|
||||
mov word [ebx+v86_regs.eip], 500h
|
||||
mov [ebx+v86_regs.eflags], 20200h
|
||||
mov esi, [sys_v86_machine]
|
||||
mov ecx, 0x502
|
||||
push fs
|
||||
call v86_start
|
||||
pop fs
|
||||
and [bios_hdpos], 0
|
||||
pop edi esi ecx ebx
|
||||
movzx edx, byte [OS_BASE + 512h]
|
||||
test byte [int13_regs_out+v86_regs.eflags], 1
|
||||
jnz @f
|
||||
mov edx, ecx
|
||||
@@:
|
||||
ret
|
||||
; \end{diamond}
|
922
kernel/branches/kolibri-cfg/blkdev/ide_cache.inc
Normal file
922
kernel/branches/kolibri-cfg/blkdev/ide_cache.inc
Normal file
@ -0,0 +1,922 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;**************************************************************************
|
||||
;
|
||||
; [cache_ide[X]_pointer]
|
||||
; or [cache_ide[X]_data_pointer] first entry in cache list
|
||||
;
|
||||
; +0 - lba sector
|
||||
; +4 - state of cache sector
|
||||
; 0 = empty
|
||||
; 1 = used for read ( same as in hd )
|
||||
; 2 = used for write ( differs from hd )
|
||||
;
|
||||
; [cache_ide[X]_system_data]
|
||||
; or [cache_ide[x]_appl_data] - cache entries
|
||||
;
|
||||
;**************************************************************************
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
align 4
|
||||
write_cache:
|
||||
;-----------------------------------------------------------
|
||||
; write all changed sectors to disk
|
||||
;-----------------------------------------------------------
|
||||
push eax ecx edx esi edi
|
||||
|
||||
; write difference ( 2 ) from cache to hd
|
||||
call calculate_cache
|
||||
add esi,8
|
||||
mov edi,1
|
||||
write_cache_more:
|
||||
cmp dword [esi+4],2 ; if cache slot is not different
|
||||
jne .write_chain
|
||||
mov dword [esi+4],1 ; same as in hd
|
||||
mov eax,[esi] ; eax = sector to write
|
||||
cmp eax,[PARTITION_START]
|
||||
jb danger
|
||||
cmp eax,[PARTITION_END]
|
||||
ja danger
|
||||
cmp [hdpos], 0x80
|
||||
jae @f
|
||||
; DMA write is permitted only if [allow_dma_access]=1
|
||||
cmp [allow_dma_access], 2
|
||||
jae .nodma
|
||||
cmp [dma_hdd], 1
|
||||
jnz .nodma
|
||||
@@:
|
||||
; Ž¡ê¥¤¨ï¥¬ § ¯¨áì 楯®çª¨ ¯®á«¥¤®¢ ⥫ìëå ᥪâ®à®¢ ¢ ®¤® ®¡à 饨¥ ª ¤¨áªã
|
||||
cmp ecx, 1
|
||||
jz .nonext
|
||||
cmp dword [esi+8+4], 2
|
||||
jnz .nonext
|
||||
push eax
|
||||
inc eax
|
||||
cmp eax, [esi+8]
|
||||
pop eax
|
||||
jnz .nonext
|
||||
cmp [cache_chain_started], 1
|
||||
jz @f
|
||||
mov [cache_chain_started], 1
|
||||
mov [cache_chain_size], 0
|
||||
mov [cache_chain_pos], edi
|
||||
mov [cache_chain_ptr], esi
|
||||
@@:
|
||||
inc [cache_chain_size]
|
||||
cmp [cache_chain_size], 16
|
||||
jnz .continue
|
||||
jmp .write_chain
|
||||
.nonext:
|
||||
call flush_cache_chain
|
||||
mov [cache_chain_size], 1
|
||||
mov [cache_chain_ptr], esi
|
||||
call write_cache_sector
|
||||
jmp .continue
|
||||
.nodma:
|
||||
call cache_write_pio
|
||||
.write_chain:
|
||||
call flush_cache_chain
|
||||
.continue:
|
||||
danger:
|
||||
add esi,8
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz write_cache_more
|
||||
call flush_cache_chain
|
||||
return_02:
|
||||
pop edi esi edx ecx eax
|
||||
ret
|
||||
|
||||
flush_cache_chain:
|
||||
cmp [cache_chain_started], 0
|
||||
jz @f
|
||||
call write_cache_chain
|
||||
mov [cache_chain_started], 0
|
||||
@@:
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
find_empty_slot:
|
||||
;-----------------------------------------------------------
|
||||
; find empty or read slot, flush cache if next 10% is used by write
|
||||
; output : edi = cache slot
|
||||
;-----------------------------------------------------------
|
||||
; push ecx esi
|
||||
|
||||
search_again:
|
||||
call calculate_cache_3
|
||||
shr ecx,3
|
||||
search_for_empty:
|
||||
inc edi
|
||||
call calculate_cache_4
|
||||
jbe inside_cache
|
||||
mov edi,1
|
||||
inside_cache:
|
||||
push esi
|
||||
call calculate_cache_1
|
||||
cmp dword [edi*8+esi+4],2
|
||||
pop esi
|
||||
jb found_slot ; it's empty or read
|
||||
dec ecx
|
||||
jnz search_for_empty
|
||||
call write_cache ; no empty slots found, write all
|
||||
cmp [hd_error],0
|
||||
jne found_slot_access_denied
|
||||
jmp search_again ; and start again
|
||||
found_slot:
|
||||
call calculate_cache_5
|
||||
found_slot_access_denied:
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
clear_hd_cache:
|
||||
mov [fat_in_cache],-1
|
||||
mov [fat_change],0
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
calculate_cache:
|
||||
; mov ecx,cache_max ; entries in cache
|
||||
; mov esi,HD_CACHE+8
|
||||
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [hdpos],1
|
||||
jne .ide1
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov ecx,[cache_ide0_system_sad_size]
|
||||
mov esi,[cache_ide0_pointer]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov ecx,[cache_ide0_appl_sad_size]
|
||||
mov esi,[cache_ide0_data_pointer]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [hdpos],2
|
||||
jne .ide2
|
||||
cmp [hdd_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 [hdpos],3
|
||||
jne .ide3
|
||||
cmp [hdd_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 [hdpos],4
|
||||
jne .noide
|
||||
cmp [hdd_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
|
||||
.noide:
|
||||
push eax
|
||||
mov eax,[hdpos]
|
||||
sub eax,80h
|
||||
cmp byte [BiosDisksData+eax*4+2], -1
|
||||
jz @f
|
||||
movzx eax,byte [BiosDisksData+eax*4+2]
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,cache_ide0
|
||||
jmp .get
|
||||
@@:
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,BiosDiskCaches
|
||||
.get:
|
||||
cmp [hdd_appl_data],0
|
||||
jne .bd_appl_data
|
||||
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax]
|
||||
mov esi,[cache_ide0_pointer-cache_ide0+eax]
|
||||
pop eax
|
||||
ret
|
||||
.bd_appl_data:
|
||||
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax]
|
||||
mov esi,[cache_ide0_data_pointer-cache_ide0+eax]
|
||||
pop eax
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
calculate_cache_1:
|
||||
; lea esi,[edi*8+HD_CACHE]
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [hdpos],1
|
||||
jne .ide1
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov esi,[cache_ide0_pointer]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov esi,[cache_ide0_data_pointer]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [hdpos],2
|
||||
jne .ide2
|
||||
cmp [hdd_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 [hdpos],3
|
||||
jne .ide3
|
||||
cmp [hdd_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 [hdpos],4
|
||||
jne .noide
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
mov esi,[cache_ide3_pointer]
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
mov esi,[cache_ide3_data_pointer]
|
||||
ret
|
||||
.noide:
|
||||
push eax
|
||||
mov eax,[hdpos]
|
||||
sub eax,80h
|
||||
cmp byte [BiosDisksData+eax*4+2], -1
|
||||
jz @f
|
||||
movzx eax,byte [BiosDisksData+eax*4+2]
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,cache_ide0
|
||||
jmp .get
|
||||
@@:
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,BiosDiskCaches
|
||||
.get:
|
||||
cmp [hdd_appl_data],0
|
||||
jne .bd_appl_data
|
||||
mov esi,[cache_ide0_pointer-cache_ide0+eax]
|
||||
pop eax
|
||||
ret
|
||||
.bd_appl_data:
|
||||
mov esi,[cache_ide0_data_pointer-cache_ide0+eax]
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
calculate_cache_2:
|
||||
; add esi,HD_CACHE+65536
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [hdpos],1
|
||||
jne .ide1
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov eax,[cache_ide0_system_data]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov eax,[cache_ide0_appl_data]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [hdpos],2
|
||||
jne .ide2
|
||||
cmp [hdd_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 [hdpos],3
|
||||
jne .ide3
|
||||
cmp [hdd_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 [hdpos],4
|
||||
jne .noide
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
mov eax,[cache_ide3_system_data]
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
mov eax,[cache_ide3_appl_data]
|
||||
ret
|
||||
.noide:
|
||||
mov eax,[hdpos]
|
||||
sub eax,80h
|
||||
cmp byte [BiosDisksData+eax*4+2], -1
|
||||
jz @f
|
||||
movzx eax,byte [BiosDisksData+eax*4+2]
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,cache_ide0
|
||||
jmp .get
|
||||
@@:
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,BiosDiskCaches
|
||||
.get:
|
||||
cmp [hdd_appl_data],0
|
||||
jne .bd_appl_data
|
||||
mov eax,[cache_ide0_system_data-cache_ide0+eax]
|
||||
ret
|
||||
.bd_appl_data:
|
||||
mov eax,[cache_ide0_appl_data-cache_ide0+eax]
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
calculate_cache_3:
|
||||
; mov ecx,cache_max*10/100
|
||||
; mov edi,[cache_search_start]
|
||||
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [hdpos],1
|
||||
jne .ide1
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov ecx,[cache_ide0_system_sad_size]
|
||||
mov edi,[cache_ide0_search_start]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov ecx,[cache_ide0_appl_sad_size]
|
||||
mov edi,[cache_ide0_appl_search_start]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [hdpos],2
|
||||
jne .ide2
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide1_appl_data
|
||||
mov ecx,[cache_ide1_system_sad_size]
|
||||
mov edi,[cache_ide1_search_start]
|
||||
ret
|
||||
.ide1_appl_data:
|
||||
mov ecx,[cache_ide1_appl_sad_size]
|
||||
mov edi,[cache_ide1_appl_search_start]
|
||||
ret
|
||||
.ide2:
|
||||
cmp [hdpos],3
|
||||
jne .ide3
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide2_appl_data
|
||||
mov ecx,[cache_ide2_system_sad_size]
|
||||
mov edi,[cache_ide2_search_start]
|
||||
ret
|
||||
.ide2_appl_data:
|
||||
mov ecx,[cache_ide2_appl_sad_size]
|
||||
mov edi,[cache_ide2_appl_search_start]
|
||||
ret
|
||||
.ide3:
|
||||
cmp [hdpos],4
|
||||
jne .noide
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
mov ecx,[cache_ide3_system_sad_size]
|
||||
mov edi,[cache_ide3_search_start]
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
mov ecx,[cache_ide3_appl_sad_size]
|
||||
mov edi,[cache_ide3_appl_search_start]
|
||||
ret
|
||||
.noide:
|
||||
push eax
|
||||
mov eax,[hdpos]
|
||||
sub eax,80h
|
||||
cmp byte [BiosDisksData+eax*4+2], -1
|
||||
jz @f
|
||||
movzx eax,byte [BiosDisksData+eax*4+2]
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,cache_ide0
|
||||
jmp .get
|
||||
@@:
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,BiosDiskCaches
|
||||
.get:
|
||||
cmp [hdd_appl_data],0
|
||||
jne .bd_appl_data
|
||||
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax]
|
||||
mov edi,[cache_ide0_search_start-cache_ide0+eax]
|
||||
pop eax
|
||||
ret
|
||||
.bd_appl_data:
|
||||
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax]
|
||||
mov edi,[cache_ide0_appl_search_start-cache_ide0+eax]
|
||||
pop eax
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
calculate_cache_4:
|
||||
; cmp edi,cache_max
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [hdpos],1
|
||||
jne .ide1
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
cmp edi,[cache_ide0_system_sad_size]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
cmp edi,[cache_ide0_appl_sad_size]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [hdpos],2
|
||||
jne .ide2
|
||||
cmp [hdd_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 [hdpos],3
|
||||
jne .ide3
|
||||
cmp [hdd_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 [hdpos],4
|
||||
jne .noide
|
||||
cmp [hdd_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
|
||||
.noide:
|
||||
push eax
|
||||
mov eax,[hdpos]
|
||||
sub eax,80h
|
||||
cmp byte [BiosDisksData+eax*4+2], -1
|
||||
jz @f
|
||||
movzx eax,byte [BiosDisksData+eax*4+2]
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,cache_ide0
|
||||
jmp .get
|
||||
@@:
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,BiosDiskCaches
|
||||
.get:
|
||||
cmp [hdd_appl_data],0
|
||||
jne .bd_appl_data
|
||||
cmp edi,[cache_ide0_system_sad_size-cache_ide0+eax]
|
||||
pop eax
|
||||
ret
|
||||
.bd_appl_data:
|
||||
cmp edi,[cache_ide0_appl_sad_size-cache_ide0+eax]
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
calculate_cache_5:
|
||||
; mov [cache_search_start],edi
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [hdpos],1
|
||||
jne .ide1
|
||||
cmp [hdd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov [cache_ide0_search_start],edi
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov [cache_ide0_appl_search_start],edi
|
||||
ret
|
||||
.ide1:
|
||||
cmp [hdpos],2
|
||||
jne .ide2
|
||||
cmp [hdd_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 [hdpos],3
|
||||
jne .ide3
|
||||
cmp [hdd_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 [hdpos],4
|
||||
jne .noide
|
||||
cmp [hdd_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
|
||||
.noide:
|
||||
push eax
|
||||
mov eax,[hdpos]
|
||||
sub eax,80h
|
||||
cmp byte [BiosDisksData+eax*4+2], -1
|
||||
jz @f
|
||||
movzx eax,byte [BiosDisksData+eax*4+2]
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,cache_ide0
|
||||
jmp .get
|
||||
@@:
|
||||
imul eax,cache_ide1-cache_ide0
|
||||
add eax,BiosDiskCaches
|
||||
.get:
|
||||
cmp [hdd_appl_data],0
|
||||
jne .bd_appl_data
|
||||
mov [cache_ide0_search_start-cache_ide0+eax],edi
|
||||
pop eax
|
||||
ret
|
||||
.bd_appl_data:
|
||||
mov [cache_ide0_appl_search_start-cache_ide0+eax],edi
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
find_empty_slot_CD_cache:
|
||||
;-----------------------------------------------------------
|
||||
; find empty or read slot, flush cache if next 10% is used by write
|
||||
; output : edi = cache slot
|
||||
;-----------------------------------------------------------
|
||||
.search_again:
|
||||
call cd_calculate_cache_3
|
||||
.search_for_empty:
|
||||
inc edi
|
||||
call cd_calculate_cache_4
|
||||
jbe .inside_cache
|
||||
mov edi,1
|
||||
.inside_cache:
|
||||
call cd_calculate_cache_5
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
clear_CD_cache:
|
||||
pusha
|
||||
.ide0:
|
||||
xor eax,eax
|
||||
cmp [cdpos],1
|
||||
jne .ide1
|
||||
mov [cache_ide0_search_start],eax
|
||||
mov ecx,[cache_ide0_system_sad_size]
|
||||
mov edi,[cache_ide0_pointer]
|
||||
call .clear
|
||||
mov [cache_ide0_appl_search_start],eax
|
||||
mov ecx,[cache_ide0_appl_sad_size]
|
||||
mov edi,[cache_ide0_data_pointer]
|
||||
jmp .continue
|
||||
.ide1:
|
||||
cmp [cdpos],2
|
||||
jne .ide2
|
||||
mov [cache_ide1_search_start],eax
|
||||
mov ecx,[cache_ide1_system_sad_size]
|
||||
mov edi,[cache_ide1_pointer]
|
||||
call .clear
|
||||
mov [cache_ide1_appl_search_start],eax
|
||||
mov ecx,[cache_ide1_appl_sad_size]
|
||||
mov edi,[cache_ide1_data_pointer]
|
||||
jmp .continue
|
||||
.ide2:
|
||||
cmp [cdpos],3
|
||||
jne .ide3
|
||||
mov [cache_ide2_search_start],eax
|
||||
mov ecx,[cache_ide2_system_sad_size]
|
||||
mov edi,[cache_ide2_pointer]
|
||||
call .clear
|
||||
mov [cache_ide2_appl_search_start],eax
|
||||
mov ecx,[cache_ide2_appl_sad_size]
|
||||
mov edi,[cache_ide2_data_pointer]
|
||||
jmp .continue
|
||||
.ide3:
|
||||
mov [cache_ide3_search_start],eax
|
||||
mov ecx,[cache_ide3_system_sad_size]
|
||||
mov edi,[cache_ide3_pointer]
|
||||
call .clear
|
||||
mov [cache_ide3_appl_search_start],eax
|
||||
mov ecx,[cache_ide3_appl_sad_size]
|
||||
mov edi,[cache_ide3_data_pointer]
|
||||
.continue:
|
||||
call .clear
|
||||
popa
|
||||
ret
|
||||
.clear:
|
||||
shl ecx,1
|
||||
cld
|
||||
rep stosd
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache:
|
||||
; mov ecx,cache_max ; entries in cache
|
||||
; mov esi,HD_CACHE+8
|
||||
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos],1
|
||||
jne .ide1
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov ecx,[cache_ide0_system_sad_size]
|
||||
mov esi,[cache_ide0_pointer]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov ecx,[cache_ide0_appl_sad_size]
|
||||
mov esi,[cache_ide0_data_pointer]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [cdpos],2
|
||||
jne .ide2
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide1_appl_data
|
||||
mov ecx,[cache_ide1_system_sad_size]
|
||||
mov esi,[cache_ide1_pointer]
|
||||
ret
|
||||
.ide1_appl_data:
|
||||
mov ecx,[cache_ide1_appl_sad_size]
|
||||
mov esi,[cache_ide1_data_pointer]
|
||||
ret
|
||||
.ide2:
|
||||
cmp [cdpos],3
|
||||
jne .ide3
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide2_appl_data
|
||||
mov ecx,[cache_ide2_system_sad_size]
|
||||
mov esi,[cache_ide2_pointer]
|
||||
ret
|
||||
.ide2_appl_data:
|
||||
mov ecx,[cache_ide2_appl_sad_size]
|
||||
mov esi,[cache_ide2_data_pointer]
|
||||
ret
|
||||
.ide3:
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
mov ecx,[cache_ide3_system_sad_size]
|
||||
mov esi,[cache_ide3_pointer]
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
mov ecx,[cache_ide3_appl_sad_size]
|
||||
mov esi,[cache_ide3_data_pointer]
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_1:
|
||||
; lea esi,[edi*8+HD_CACHE]
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos],1
|
||||
jne .ide1
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov esi,[cache_ide0_pointer]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov esi,[cache_ide0_data_pointer]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [cdpos],2
|
||||
jne .ide2
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide1_appl_data
|
||||
mov esi,[cache_ide1_pointer]
|
||||
ret
|
||||
.ide1_appl_data:
|
||||
mov esi,[cache_ide1_data_pointer]
|
||||
ret
|
||||
.ide2:
|
||||
cmp [cdpos],3
|
||||
jne .ide3
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide2_appl_data
|
||||
mov esi,[cache_ide2_pointer]
|
||||
ret
|
||||
.ide2_appl_data:
|
||||
mov esi,[cache_ide2_data_pointer]
|
||||
ret
|
||||
.ide3:
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
mov esi,[cache_ide3_pointer]
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
mov esi,[cache_ide3_data_pointer]
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_2:
|
||||
; add esi,HD_CACHE+65536
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos],1
|
||||
jne .ide1
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov eax,[cache_ide0_system_data]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov eax,[cache_ide0_appl_data]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [cdpos],2
|
||||
jne .ide2
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide1_appl_data
|
||||
mov eax,[cache_ide1_system_data]
|
||||
ret
|
||||
.ide1_appl_data:
|
||||
mov eax,[cache_ide1_appl_data]
|
||||
ret
|
||||
.ide2:
|
||||
cmp [cdpos],3
|
||||
jne .ide3
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide2_appl_data
|
||||
mov eax,[cache_ide2_system_data]
|
||||
ret
|
||||
.ide2_appl_data:
|
||||
mov eax,[cache_ide2_appl_data]
|
||||
ret
|
||||
.ide3:
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
mov eax,[cache_ide3_system_data]
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
mov eax,[cache_ide3_appl_data]
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_3:
|
||||
; mov ecx,cache_max*10/100
|
||||
; mov edi,[cache_search_start]
|
||||
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos],1
|
||||
jne .ide1
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov edi,[cache_ide0_search_start]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov edi,[cache_ide0_appl_search_start]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [cdpos],2
|
||||
jne .ide2
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide1_appl_data
|
||||
mov edi,[cache_ide1_search_start]
|
||||
ret
|
||||
.ide1_appl_data:
|
||||
mov edi,[cache_ide1_appl_search_start]
|
||||
ret
|
||||
.ide2:
|
||||
cmp [cdpos],3
|
||||
jne .ide3
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide2_appl_data
|
||||
mov edi,[cache_ide2_search_start]
|
||||
ret
|
||||
.ide2_appl_data:
|
||||
mov edi,[cache_ide2_appl_search_start]
|
||||
ret
|
||||
.ide3:
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
mov edi,[cache_ide3_search_start]
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
mov edi,[cache_ide3_appl_search_start]
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_4:
|
||||
; cmp edi,cache_max
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos],1
|
||||
jne .ide1
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
cmp edi,[cache_ide0_system_sad_size]
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
cmp edi,[cache_ide0_appl_sad_size]
|
||||
ret
|
||||
.ide1:
|
||||
cmp [cdpos],2
|
||||
jne .ide2
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide1_appl_data
|
||||
cmp edi,[cache_ide1_system_sad_size]
|
||||
ret
|
||||
.ide1_appl_data:
|
||||
cmp edi,[cache_ide1_appl_sad_size]
|
||||
ret
|
||||
.ide2:
|
||||
cmp [cdpos],3
|
||||
jne .ide3
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide2_appl_data
|
||||
cmp edi,[cache_ide2_system_sad_size]
|
||||
ret
|
||||
.ide2_appl_data:
|
||||
cmp edi,[cache_ide2_appl_sad_size]
|
||||
ret
|
||||
.ide3:
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
cmp edi,[cache_ide3_system_sad_size]
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
cmp edi,[cache_ide3_appl_sad_size]
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
align 4
|
||||
cd_calculate_cache_5:
|
||||
; mov [cache_search_start],edi
|
||||
; 1 - IDE0 ... 4 - IDE3
|
||||
.ide0:
|
||||
cmp [cdpos],1
|
||||
jne .ide1
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide0_appl_data
|
||||
mov [cache_ide0_search_start],edi
|
||||
ret
|
||||
.ide0_appl_data:
|
||||
mov [cache_ide0_appl_search_start],edi
|
||||
ret
|
||||
.ide1:
|
||||
cmp [cdpos],2
|
||||
jne .ide2
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide1_appl_data
|
||||
mov [cache_ide1_search_start],edi
|
||||
ret
|
||||
.ide1_appl_data:
|
||||
mov [cache_ide1_appl_search_start],edi
|
||||
ret
|
||||
.ide2:
|
||||
cmp [cdpos],3
|
||||
jne .ide3
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide2_appl_data
|
||||
mov [cache_ide2_search_start],edi
|
||||
ret
|
||||
.ide2_appl_data:
|
||||
mov [cache_ide2_appl_search_start],edi
|
||||
ret
|
||||
.ide3:
|
||||
cmp [cd_appl_data],0
|
||||
jne .ide3_appl_data
|
||||
mov [cache_ide3_search_start],edi
|
||||
ret
|
||||
.ide3_appl_data:
|
||||
mov [cache_ide3_appl_search_start],edi
|
||||
ret
|
||||
;--------------------------------------------------------------------
|
||||
;align 4
|
||||
;calculate_linear_to_real:
|
||||
; shr eax, 12
|
||||
; mov eax, [page_tabs+eax*4]
|
||||
; and eax, 0xFFFFF000
|
||||
; ret
|
2272
kernel/branches/kolibri-cfg/blkdev/rd.inc
Normal file
2272
kernel/branches/kolibri-cfg/blkdev/rd.inc
Normal file
File diff suppressed because it is too large
Load Diff
30
kernel/branches/kolibri-cfg/blkdev/rdsave.inc
Normal file
30
kernel/branches/kolibri-cfg/blkdev/rdsave.inc
Normal file
@ -0,0 +1,30 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
iglobal
|
||||
saverd_fileinfo:
|
||||
dd 2 ; subfunction: write
|
||||
dd 0 ; (reserved)
|
||||
dd 0 ; (reserved)
|
||||
dd 1440*1024 ; size 1440 Kb
|
||||
dd RAMDISK
|
||||
db 0
|
||||
.name:
|
||||
dd ?
|
||||
endg
|
||||
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
|
||||
call restorefatchain
|
||||
mov ebx, saverd_fileinfo
|
||||
mov [saverd_fileinfo.name], ecx
|
||||
pushad
|
||||
call file_system_lfn ;in ebx
|
||||
popad
|
||||
mov [esp+32], eax
|
||||
ret
|
BIN
kernel/branches/kolibri-cfg/boot/ETFONT.FNT
Normal file
BIN
kernel/branches/kolibri-cfg/boot/ETFONT.FNT
Normal file
Binary file not shown.
1240
kernel/branches/kolibri-cfg/boot/bootcode.inc
Normal file
1240
kernel/branches/kolibri-cfg/boot/bootcode.inc
Normal file
File diff suppressed because it is too large
Load Diff
102
kernel/branches/kolibri-cfg/boot/booteng.inc
Normal file
102
kernel/branches/kolibri-cfg/boot/booteng.inc
Normal file
@ -0,0 +1,102 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;======================================================================
|
||||
;
|
||||
; BOOT DATA
|
||||
;
|
||||
;======================================================================
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
db 186,' KolibriOS is based on MenuetOS and comes with ABSOLUTELY '
|
||||
db 'NO WARRANTY ',186
|
||||
db 186,' See file COPYING for details '
|
||||
db ' ',186
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
msg_apm db " APM x.x ", 0
|
||||
vervesa db "Version of Vesa: Vesa x.x",13,10,0
|
||||
novesa db "Display: EGA/CGA",13,10,0
|
||||
s_vesa db "Version of VESA: "
|
||||
.ver db "?.?",13,10,0
|
||||
|
||||
gr_mode db "Select a videomode: ",13,10,0
|
||||
;s_bpp db 13,10,186," ƒ«ã¡¨ 梥â : "
|
||||
; .bpp dw "??"
|
||||
; db 13,10,0
|
||||
|
||||
vrrmprint db "Apply VRR? (picture frequency greater than 60Hz"
|
||||
db " only for transfers:",13,10
|
||||
db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0
|
||||
|
||||
|
||||
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
|
||||
|
||||
bdev db "Load ramdisk from [1-floppy; 2-kolibri.img]: ",0
|
||||
probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, "
|
||||
db "2-probe bios (Vesa 3.0)]: ",0
|
||||
;memokz256 db 13,10,186," RAM 256 Mb",0
|
||||
;memokz128 db 13,10,186," RAM 128 Mb",0
|
||||
;memokz64 db 13,10,186," RAM 64 Mb",0
|
||||
;memokz32 db 13,10,186," RAM 32 Mb",0
|
||||
;memokz16 db 13,10,186," RAM 16 Mb",0
|
||||
prnotfnd db "Fatal - Videomode not found.",0
|
||||
;modena db "Fatal - VBE 0x112+ required.",0
|
||||
not386 db "Fatal - CPU 386+ required.",0
|
||||
btns db "Fatal - Can't determine color depth.",0
|
||||
fatalsel db "Fatal - Graphics mode not supported by hardware.",0
|
||||
pres_key db "Press any key to choose a new videomode.",0
|
||||
badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0
|
||||
memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0
|
||||
okt db " ... OK"
|
||||
linef db 13,10,0
|
||||
diskload db "Loading diskette: 00 %",8,8,8,8,0
|
||||
pros db "00"
|
||||
backspace2 db 8,8,0
|
||||
boot_dev db 0 ; 0=floppy, 1=hd
|
||||
start_msg db "Press [abcd] to change settings, press [Enter] to continue booting",13,10,0
|
||||
time_msg db " or wait "
|
||||
time_str db " 5 seconds"
|
||||
db " before automatical continuation",13,10,0
|
||||
current_cfg_msg db "Current settings:",13,10,0
|
||||
curvideo_msg db " [a] Videomode: ",0
|
||||
|
||||
;modes_msg dw mode4,mode1,mode2,mode3
|
||||
;modevesa20 db " with LFB",0
|
||||
;modevesa12 db ", VESA 1.2 Bnk",0
|
||||
mode0 db "320x200, EGA/CGA 256 colors",13,10,0
|
||||
mode9 db "640x480, VGA 16 colors",13,10,0
|
||||
|
||||
;probeno_msg db " (standard mode)",0
|
||||
;probeok_msg db " (check nonstandard modes)",0
|
||||
;dma_msg db " [b] Use DMA for HDD access:",0
|
||||
usebd_msg db " [b] Add disks visible by BIOS:",0
|
||||
on_msg db " on",13,10,0
|
||||
off_msg db " off",13,10,0
|
||||
;readonly_msg db " only for reading",13,10,0
|
||||
vrrm_msg db " [c] Use VRR:",0
|
||||
preboot_device_msg db " [d] Floppy image: ",0
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1 db "real floppy",13,10,0
|
||||
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
|
||||
loading_msg db "Loading KolibriOS...",0
|
||||
|
||||
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0
|
||||
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0
|
||||
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0
|
||||
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0
|
||||
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0
|
||||
|
||||
remark1 db "Default values were selected to match most of configurations, but not all.",0
|
||||
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
|
||||
remark3 db "If the system does not boot, try to disable the item [b].",0
|
||||
remarks dw remark1, remark2, remark3
|
||||
num_remarks = 3
|
107
kernel/branches/kolibri-cfg/boot/bootet.inc
Normal file
107
kernel/branches/kolibri-cfg/boot/bootet.inc
Normal file
@ -0,0 +1,107 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;======================================================================
|
||||
;
|
||||
; BOOT DATA
|
||||
;
|
||||
;======================================================================
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
|
||||
db 'NO WARRANTY ',186
|
||||
db 186,' See file COPYING for details '
|
||||
db ' ',186
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
novesa db "Ekraan: EGA/CGA",13,10,0
|
||||
vervesa db "Vesa versioon: Vesa x.x",13,10,0
|
||||
vervesa_off=20
|
||||
msg_apm db " APM x.x ", 0
|
||||
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
|
||||
db "[3] 1024x768, [4] 1280x1024",13,10
|
||||
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
|
||||
db "[7] 1024x768, [8] 1280x1024",13,10
|
||||
db 186," EGA/CGA 256 värvi: [9] 320x200, "
|
||||
db "VGA 16 värvi: [0] 640x480",13,10
|
||||
db 186," Vali reziim: ",0
|
||||
bt24 db "Bitti pikseli kohta: 24",13,10,0
|
||||
bt32 db "Bitti pikseli kohta: 32",13,10,0
|
||||
vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz"
|
||||
db " ainult:",13,10
|
||||
db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0
|
||||
;askmouse db " Hiir:"
|
||||
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
|
||||
; db " Vali port [1-3]: ",0
|
||||
;no_com1 db 13,10,186, " No COM1 mouse",0
|
||||
;no_com2 db 13,10,186, " No COM2 mouse",0
|
||||
;ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-no]: ",0
|
||||
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
|
||||
;gr_direct db 186," Use direct LFB writing? "
|
||||
; db "[1-yes/2-no] ? ",0
|
||||
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / "
|
||||
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
|
||||
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
|
||||
bdev db "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0
|
||||
probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, "
|
||||
db "2-leia biosist (Vesa 3.0)]: ",0
|
||||
;memokz256 db 13,10,186," RAM 256 Mb",0
|
||||
;memokz128 db 13,10,186," RAM 128 Mb",0
|
||||
;memokz64 db 13,10,186," RAM 64 Mb",0
|
||||
;memokz32 db 13,10,186," RAM 32 Mb",0
|
||||
;memokz16 db 13,10,186," RAM 16 Mb",0
|
||||
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0
|
||||
;modena db "Fataalne - VBE 0x112+ on vajalik.",0
|
||||
not386 db "Fataalne - CPU 386+ on vajalik.",0
|
||||
btns db "Fataalne - Ei suuda värvisügavust määratleda.",0
|
||||
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0
|
||||
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0
|
||||
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
|
||||
okt db " ... OK"
|
||||
linef db 13,10,0
|
||||
diskload db "Loen disketti: 00 %",8,8,8,8,0
|
||||
pros db "00"
|
||||
backspace2 db 8,8,0
|
||||
boot_dev db 0 ; 0=floppy, 1=hd
|
||||
start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
|
||||
time_msg db " või oota "
|
||||
time_str db " 5 sekundit"
|
||||
db " automaatseks jätkamiseks",13,10,0
|
||||
current_cfg_msg db "Praegused seaded:",13,10,0
|
||||
curvideo_msg db " [a] Videoreziim: ",0
|
||||
mode1 db "640x480",0
|
||||
mode2 db "800x600",0
|
||||
mode3 db "1024x768",0
|
||||
mode4 db "1280x1024",0
|
||||
modes_msg dw mode4,mode1,mode2,mode3
|
||||
modevesa20 db " koos LFB",0
|
||||
modevesa12 db ", VESA 1.2 Bnk",0
|
||||
mode9 db "320x200, EGA/CGA 256 värvi",0
|
||||
mode10 db "640x480, VGA 16 värvi",0
|
||||
probeno_msg db " (standard reziim)",0
|
||||
probeok_msg db " (kontrolli ebastandardseid reziime)",0
|
||||
;dma_msg db " [b] Kasuta DMA'd HDD juurdepääsuks:",0
|
||||
usebd_msg db " [b] Add disks visible by BIOS:",0
|
||||
on_msg db " sees",13,10,0
|
||||
off_msg db " väljas",13,10,0
|
||||
;readonly_msg db " ainult lugemiseks",13,10,0
|
||||
vrrm_msg db " [c] Kasuta VRR:",0
|
||||
preboot_device_msg db " [d] Disketi kujutis: ",0
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1 db "reaalne diskett",13,10,0
|
||||
pdm2 db "kolibri.img",13,10,0
|
||||
loading_msg db "Laadin KolibriOS...",0
|
||||
|
||||
remark1 db "Default values were selected to match most of configurations, but not all.",0
|
||||
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
|
||||
remark3 db "If the system does not boot, try to disable the item [b].",0
|
||||
remarks dw remark1, remark2, remark3
|
||||
num_remarks = 3
|
112
kernel/branches/kolibri-cfg/boot/bootge.inc
Normal file
112
kernel/branches/kolibri-cfg/boot/bootge.inc
Normal file
@ -0,0 +1,112 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;======================================================================
|
||||
;
|
||||
; BOOT DATA
|
||||
;
|
||||
;======================================================================
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
|
||||
; db 'NO WARRANTY ',186
|
||||
; db 186,' See file COPYING for details '
|
||||
; db ' ',186
|
||||
|
||||
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche '
|
||||
db ' Garantie vertrieben ',186
|
||||
db 186,' Details stehen in der Datei COPYING '
|
||||
db ' ',186
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
novesa db "Anzeige: EGA/CGA ",13,10,0
|
||||
vervesa db "Vesa-Version: Vesa ",13,10,0
|
||||
vervesa_off=22
|
||||
msg_apm db " APM x.x ", 0
|
||||
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
|
||||
db "[3] 1024x768, [4] 1280x1024",13,10
|
||||
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
|
||||
db "[7] 1024x768, [8] 1280x1024",13,10
|
||||
db 186," EGA/CGA 256 Farben: [9] 320x200, "
|
||||
db "VGA 16 Farben: [0] 640x480",13,10
|
||||
db 186," Waehle Modus: ",0
|
||||
bt24 db "Bits Per Pixel: 24",13,10,0
|
||||
bt32 db "Bits Per Pixel: 32",13,10,0
|
||||
vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz"
|
||||
db " only for transfers:",13,10
|
||||
db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0
|
||||
;askmouse db " Maus angeschlossen an:"
|
||||
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
|
||||
; db " Waehle Port [1-3]: ",0
|
||||
;no_com1 db 13,10,186, " Keine COM1 Maus",0
|
||||
;no_com2 db 13,10,186, " Keine COM2 Maus",0
|
||||
;ask_dma db "Nutze DMA zum HDD Zugriff? [1-ja, 2-allein fur Lesen, 3-nein]: ",0
|
||||
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
|
||||
;gr_direct db 186," Benutze direct LFB? "
|
||||
; db "[1-ja/2-nein] ? ",0
|
||||
;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / "
|
||||
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
|
||||
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
|
||||
bdev db "Lade die Ramdisk von [1-Diskette; 2-kolibri.img]: ",0
|
||||
probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, "
|
||||
db "2-BIOS Test (Vesa 3.0)]: ",0
|
||||
;memokz256 db 13,10,186," RAM 256 Mb",0
|
||||
;memokz128 db 13,10,186," RAM 128 Mb",0
|
||||
;memokz64 db 13,10,186," RAM 64 Mb",0
|
||||
;memokz32 db 13,10,186," RAM 32 Mb",0
|
||||
;memokz16 db 13,10,186," RAM 16 Mb",0
|
||||
prnotfnd db "Fatal - Videomodus nicht gefunden.",0
|
||||
;modena db "Fatal - VBE 0x112+ required.",0
|
||||
not386 db "Fatal - CPU 386+ benoetigt.",0
|
||||
btns db "Fatal - konnte Farbtiefe nicht erkennen.",0
|
||||
fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0
|
||||
badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0
|
||||
memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0
|
||||
okt db " ... OK"
|
||||
linef db 13,10,0
|
||||
diskload db "Lade Diskette: 00 %",8,8,8,8,0
|
||||
pros db "00"
|
||||
backspace2 db 8,8,0
|
||||
boot_dev db 0 ; 0=floppy, 1=hd
|
||||
start_msg db "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0
|
||||
time_msg db " oder warte "
|
||||
time_str db " 5 Sekunden"
|
||||
db " bis zum automatischen Start",13,10,0
|
||||
current_cfg_msg db "Aktuelle Einstellungen:",13,10,0
|
||||
curvideo_msg db " [a] Videomodus: ",0
|
||||
mode1 db "640x480",0
|
||||
mode2 db "800x600",0
|
||||
mode3 db "1024x768",0
|
||||
mode4 db "1280x1024",0
|
||||
modes_msg dw mode4,mode1,mode2,mode3
|
||||
modevesa20 db " mit LFB",0
|
||||
modevesa12 db ", VESA 1.2 Bnk",0
|
||||
mode9 db "320x200, EGA/CGA 256 colors",0
|
||||
mode10 db "640x480, VGA 16 colors",0
|
||||
probeno_msg db " (Standard Modus)",0
|
||||
probeok_msg db " (teste nicht-standard Modi)",0
|
||||
;dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0
|
||||
usebd_msg db " [b] Add disks visible by BIOS:",0
|
||||
on_msg db " an",13,10,0
|
||||
off_msg db " aus",13,10,0
|
||||
;readonly_msg db " fur Lesen",13,10,0
|
||||
vrrm_msg db " [c] Nutze VRR:",0
|
||||
preboot_device_msg db " [d] Diskettenimage: ",0
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1 db "Echte Diskette",13,10,0
|
||||
pdm2 db "kolibri.img",13,10,0
|
||||
loading_msg db "Lade KolibriOS...",0
|
||||
|
||||
remark1 db "Default values were selected to match most of configurations, but not all.",0
|
||||
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
|
||||
remark3 db "If the system does not boot, try to disable the item [b].",0
|
||||
remarks dw remark1, remark2, remark3
|
||||
num_remarks = 3
|
83
kernel/branches/kolibri-cfg/boot/bootru.inc
Normal file
83
kernel/branches/kolibri-cfg/boot/bootru.inc
Normal file
@ -0,0 +1,83 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;=================================================================
|
||||
;
|
||||
; BOOT DATA
|
||||
;
|
||||
;=================================================================
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
d80x25_bottom:
|
||||
db 186,' Kolibri OS ®á®¢ Menuet OS ¨ ¥ ¯à¥¤®áâ ¢«ï¥â '
|
||||
db '¨ª ª¨å £ àa⨩. ',186
|
||||
db 186,' <20>®¤à®¡¥¥ ᬮâà¨â¥ ¢ ä ©«¥ COPYING.TXT '
|
||||
db ' ',186
|
||||
line_full_bottom
|
||||
d80x25_bottom_num = 3
|
||||
|
||||
msg_apm db " APM x.x ", 0
|
||||
novesa db "‚¨¤¥®ª àâ : EGA/CGA",13,10,0
|
||||
s_vesa db "‚¥àá¨ï VESA: "
|
||||
.ver db "?.?",13,10,0
|
||||
|
||||
gr_mode db "‚ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",13,10,0
|
||||
vrrmprint db "ˆá¯®«ì§®¢ âì VRR? (ç áâ®â ª ¤à®¢ ¢ëè¥ 60 ƒæ"
|
||||
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10
|
||||
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-¥â]: ",0
|
||||
;ask_dma db "ˆá¯®«ì§®¢ âì DMA ¤«ï ¤®áâ㯠ª HDD? [1-¤ , 2-⮫쪮 ç⥨¥, 3-¥â]: ",0
|
||||
ask_bd db "„®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS ¢ ०¨¬¥ V86? [1-¤ , 2-¥â]: ",0
|
||||
bdev db "‡ £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-kolibri.img ¨§ ¯ ¯ª¨ § £à㧪¨]: ",0
|
||||
prnotfnd db "Žè¨¡ª - ‚¨¤¥®à¥¦¨¬ ¥ ©¤¥.",0
|
||||
not386 db "Žè¨¡ª - ’ॡã¥âáï ¯à®æ¥áá®à 386+.",0
|
||||
fatalsel db "Žè¨¡ª - ‚ë¡à ë© ¢¨¤¥®à¥¦¨¬ ¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0
|
||||
pres_key db "<EFBFBD> ¦¨¬¨â¥ «î¡ãî ª« ¢¨èã, ¤«ï ¯¥à¥å®¤ ¢ ¢ë¡®à ०¨¬®¢.",0
|
||||
badsect db 13,10,186," Žè¨¡ª - „¨áª¥â ¯®¢à¥¦¤¥ . <20>®¯à®¡ã©â¥ ¤àã£ãî.",0
|
||||
memmovefailed db 13,10,186," Žè¨¡ª - Int 0x15 move failed.",0
|
||||
okt db " ... OK"
|
||||
linef db 13,10,0
|
||||
diskload db "‡ £à㧪 ¤¨áª¥âë: 00 %",8,8,8,8,0
|
||||
pros db "00"
|
||||
backspace2 db 8,8,0
|
||||
boot_dev db 0
|
||||
start_msg db "<EFBFBD> ¦¬¨â¥ [abcd] ¤«ï ¨§¬¥¥¨ï áâ஥ª, [Enter] ¤«ï ¯à®¤®«¦¥¨ï § £à㧪¨",13,10,0
|
||||
time_msg db " ¨«¨ ¯®¤®¦¤¨â¥ "
|
||||
time_str db " 5 ᥪ㤠"
|
||||
db " ¤® ¢â®¬ â¨ç¥áª®£® ¯à®¤®«¦¥¨ï",13,10,0
|
||||
current_cfg_msg db "’¥ªã騥 áâனª¨:",13,10,0
|
||||
curvideo_msg db " [a] ‚¨¤¥®à¥¦¨¬: ",0
|
||||
|
||||
|
||||
mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0
|
||||
mode9 db "640x480, VGA 16 梥⮢",13,10,0
|
||||
|
||||
usebd_msg db " [b] „®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS:",0
|
||||
on_msg db " ¢ª«",13,10,0
|
||||
off_msg db " ¢ëª«",13,10,0
|
||||
readonly_msg db " ⮫쪮 ç⥨¥",13,10,0
|
||||
vrrm_msg db " [c] ˆá¯®«ì§®¢ ¨¥ VRR:",0
|
||||
preboot_device_msg db " [d] Ž¡à § ¤¨áª¥âë: ",0
|
||||
preboot_device_msgs dw 0,pdm1,pdm2,0
|
||||
pdm1 db " áâ®ïé ï ¤¨áª¥â ",13,10,0
|
||||
pdm2 db "kolibri.img ¨§ ¯ ¯ª¨ § £à㧪¨",13,10,0
|
||||
loading_msg db "ˆ¤ñâ § £à㧪 KolibriOS...",0
|
||||
|
||||
|
||||
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ',13,10,0
|
||||
_r1 db 186,' ³ 320x200 EGA/CGA 256 梥⮢ ³ ³ ',13,10,0
|
||||
_r2 db 186,' ³ 640x480 VGA 16 梥⮢ ³ ³ ',13,10,0
|
||||
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³ ',13,10,0
|
||||
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ',13,10,0
|
||||
|
||||
|
||||
remark1 db "‡ ç¥¨ï ¯® 㬮«ç ¨î ¢ë¡à ë ¤«ï 㤮¡á⢠¡®«ìè¨á⢠, ® ¥ ¢á¥å.",0
|
||||
remark2 db "…᫨ ã ‚ á <20>‹’-¬®¨â®à, ¢ª«îç¨â¥ VRR ¢ ¯ãªâ¥ [c].",0
|
||||
remark3 db "…᫨ ã ‚ á ¥ £à㧨âáï á¨á⥬ , ¯®¯à®¡ã©â¥ ®âª«îç¨âì ¯ãªâ [b].",0
|
||||
remarks dw remark1, remark2, remark3
|
||||
num_remarks = 3
|
62
kernel/branches/kolibri-cfg/boot/bootstr.inc
Normal file
62
kernel/branches/kolibri-cfg/boot/bootstr.inc
Normal file
@ -0,0 +1,62 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
; boot data: common strings (for all languages)
|
||||
macro line_full_top {
|
||||
db 201
|
||||
times 78 db 205
|
||||
db 187
|
||||
}
|
||||
macro line_full_bottom {
|
||||
db 200
|
||||
times 78 db 205
|
||||
db 188
|
||||
}
|
||||
macro line_half {
|
||||
db 186,' '
|
||||
times 76 db 0xc4
|
||||
db ' ',186
|
||||
}
|
||||
macro line_space {
|
||||
db 186
|
||||
times 78 db 32
|
||||
db 186
|
||||
}
|
||||
d80x25_top:
|
||||
line_full_top
|
||||
cur_line_pos = 75
|
||||
store byte ' ' at d80x25_top+cur_line_pos+1
|
||||
rev_var = __REV__
|
||||
while rev_var > 0
|
||||
store byte rev_var mod 10 + '0' at d80x25_top+cur_line_pos
|
||||
cur_line_pos = cur_line_pos - 1
|
||||
rev_var = rev_var / 10
|
||||
end while
|
||||
store byte ' ' at d80x25_top+cur_line_pos
|
||||
store dword ' SVN' at d80x25_top+cur_line_pos-4
|
||||
|
||||
space_msg: line_space
|
||||
verstr:
|
||||
; line_space
|
||||
; version string
|
||||
db 186,32
|
||||
repeat 78
|
||||
load a byte from version+%-1
|
||||
if a = 13
|
||||
break
|
||||
end if
|
||||
db a
|
||||
end repeat
|
||||
repeat 78 - ($-verstr)
|
||||
db ' '
|
||||
end repeat
|
||||
db 32,186
|
||||
line_half
|
||||
d80x25_top_num = 4
|
754
kernel/branches/kolibri-cfg/boot/bootvesa.inc
Normal file
754
kernel/branches/kolibri-cfg/boot/bootvesa.inc
Normal file
@ -0,0 +1,754 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
struc VBE_VGAInfo {
|
||||
.VESASignature dd ? ; char
|
||||
.VESAVersion dw ? ; short
|
||||
.OemStringPtr dd ? ; char *
|
||||
.Capabilities dd ? ; ulong
|
||||
.VideoModePtr dd ? ; ulong
|
||||
.TotalMemory dw ? ; short
|
||||
; VBE 2.0+
|
||||
.OemSoftwareRev db ? ; short
|
||||
.OemVendorNamePtr dw ? ; char *
|
||||
.OemProductNamePtr dw ? ; char *
|
||||
.OemProductRevPtr dw ? ; char *
|
||||
.reserved rb 222 ; char
|
||||
.OemData rb 256 ; char
|
||||
}
|
||||
|
||||
struc VBE_ModeInfo {
|
||||
.ModeAttributes dw ? ; short
|
||||
.WinAAttributes db ? ; char
|
||||
.WinBAttributes db ? ; char
|
||||
.WinGranularity dw ? ; short
|
||||
.WinSize dw ? ; short
|
||||
.WinASegment dw ? ; ushort
|
||||
.WinBSegment dw ? ; ushort
|
||||
.WinFuncPtr dd ? ; void *
|
||||
.BytesPerScanLine dw ? ; short
|
||||
.XRes dw ? ; short
|
||||
.YRes dw ? ; short
|
||||
.XCharSize db ? ; char
|
||||
.YCharSize db ? ; char
|
||||
.NumberOfPlanes db ? ; char
|
||||
.BitsPerPixel db ? ; char
|
||||
.NumberOfBanks db ? ; char
|
||||
.MemoryModel db ? ; char
|
||||
.BankSize db ? ; char
|
||||
.NumberOfImagePages db ? ; char
|
||||
.res1 db ? ; char
|
||||
.RedMaskSize db ? ; char
|
||||
.RedFieldPosition db ? ; char
|
||||
.GreenMaskSize db ? ; char
|
||||
.GreenFieldPosition db ? ; char
|
||||
.BlueMaskSize db ? ; char
|
||||
.BlueFieldPosition db ? ; char
|
||||
.RsvedMaskSize db ? ; char
|
||||
.RsvedFieldPosition db ? ; char
|
||||
.DirectColorModeInfo db ? ; char ; MISSED IN THIS TUTORIAL!! SEE ABOVE
|
||||
; VBE 2.0+
|
||||
.PhysBasePtr dd ? ; ulong
|
||||
.OffScreenMemOffset dd ? ; ulong
|
||||
.OffScreenMemSize dw ? ; short
|
||||
; VBE 3.0+
|
||||
.LinbytesPerScanLine dw ? ; short
|
||||
.BankNumberOfImagePages db ? ; char
|
||||
.LinNumberOfImagePages db ? ; char
|
||||
.LinRedMaskSize db ? ; char
|
||||
.LinRedFieldPosition db ? ; char
|
||||
.LingreenMaskSize db ? ; char
|
||||
.LinGreenFieldPosition db ? ; char
|
||||
.LinBlueMaskSize db ? ; char
|
||||
.LinBlueFieldPosition db ? ; char
|
||||
.LinRsvdMaskSize db ? ; char
|
||||
.LinRsvdFieldPosition db ? ; char
|
||||
.MaxPixelClock dd ? ; ulong
|
||||
.res2 rb 190 ; char
|
||||
}
|
||||
|
||||
virtual at $A000
|
||||
vi VBE_VGAInfo
|
||||
mi VBE_ModeInfo
|
||||
modes_table:
|
||||
end virtual
|
||||
cursor_pos dw 0 ;âðåìåííîå õðàíåíèå êóðñîðà.
|
||||
home_cursor dw 0 ;current shows rows a table
|
||||
end_cursor dw 0 ;end of position current shows rows a table
|
||||
scroll_start dw 0 ;start position of scroll bar
|
||||
scroll_end dw 0 ;end position of scroll bar
|
||||
long_v_table equ 9 ;long of visible video table
|
||||
size_of_step equ 10
|
||||
scroll_area_size equ (long_v_table-2)
|
||||
int2str:
|
||||
dec bl
|
||||
jz @f
|
||||
xor edx,edx
|
||||
div ecx
|
||||
push edx
|
||||
call int2str
|
||||
pop eax
|
||||
@@: or al,0x30
|
||||
mov [ds:di],al
|
||||
inc di
|
||||
ret
|
||||
|
||||
int2strnz:
|
||||
cmp eax,ecx
|
||||
jb @f
|
||||
xor edx,edx
|
||||
div ecx
|
||||
push edx
|
||||
call int2strnz
|
||||
pop eax
|
||||
@@: or al,0x30
|
||||
mov [es:di],al
|
||||
inc di
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------
|
||||
;Write message about incorrect v_mode and write message about jmp on swith v_mode
|
||||
v_mode_error:
|
||||
_setcursor 19,2
|
||||
mov si, fatalsel
|
||||
call printplain
|
||||
_setcursor 20,2
|
||||
mov si,pres_key
|
||||
call printplain
|
||||
xor eax,eax
|
||||
int 16h
|
||||
jmp cfgmanager.d
|
||||
;-------------------------------------------------------
|
||||
;
|
||||
|
||||
|
||||
|
||||
;-------------------------------------------------------
|
||||
print_vesa_info:
|
||||
_setcursor 5,2
|
||||
|
||||
mov [es:vi.VESASignature],'VBE2'
|
||||
mov ax,0x4F00
|
||||
mov di,vi ;0xa000
|
||||
int 0x10
|
||||
or ah,ah
|
||||
jz @f
|
||||
mov [es:vi.VESASignature],'VESA'
|
||||
mov ax,$4F00
|
||||
mov di,vi
|
||||
int 0x10
|
||||
or ah,ah
|
||||
jnz .exit
|
||||
@@:
|
||||
cmp [es:vi.VESASignature],'VESA'
|
||||
jne .exit
|
||||
cmp [es:vi.VESAVersion],0x0100
|
||||
jb .exit
|
||||
jmp .vesaok2
|
||||
|
||||
.exit:
|
||||
mov si,novesa
|
||||
call printplain
|
||||
ret
|
||||
|
||||
.vesaok2:
|
||||
mov ax,[es:vi.VESAVersion]
|
||||
add ax,'00'
|
||||
|
||||
mov [s_vesa.ver], ah
|
||||
mov [s_vesa.ver+2], al
|
||||
mov si,s_vesa
|
||||
call printplain
|
||||
|
||||
_setcursor 4,2
|
||||
mov si,word[es:vi.OemStringPtr]
|
||||
mov di,si
|
||||
|
||||
push ds
|
||||
mov ds,word[es:vi.OemStringPtr+2]
|
||||
call printplain
|
||||
pop ds
|
||||
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
calc_vmodes_table:
|
||||
pushad
|
||||
|
||||
; push 0
|
||||
; pop es
|
||||
|
||||
lfs si, [es:vi.VideoModePtr]
|
||||
|
||||
mov bx,modes_table
|
||||
;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢
|
||||
mov word [es:bx],640
|
||||
mov word [es:bx+2],480
|
||||
mov word [es:bx+6],0x13
|
||||
|
||||
mov word [es:bx+10],640
|
||||
mov word [es:bx+12],480
|
||||
mov word [es:bx+16],0x12
|
||||
add bx,20
|
||||
.next_mode:
|
||||
mov cx,word [fs:si] ; mode number
|
||||
cmp cx,-1
|
||||
je .modes_ok.2
|
||||
|
||||
mov ax,0x4F01
|
||||
mov di,mi
|
||||
int 0x10
|
||||
|
||||
or ah,ah
|
||||
jnz .modes_ok.2;vesa_info.exit
|
||||
|
||||
test [es:mi.ModeAttributes],00000001b ;videomode support ?
|
||||
jz @f
|
||||
test [es:mi.ModeAttributes],00010000b ;picture ?
|
||||
jz @f
|
||||
test [es:mi.ModeAttributes],10000000b ;LFB ?
|
||||
jz @f
|
||||
|
||||
cmp [es:mi.BitsPerPixel], 24 ;It show only videomodes to have support 24 and 32 bpp
|
||||
jb @f
|
||||
|
||||
; cmp [es:mi.BitsPerPixel],16
|
||||
; jne .l0
|
||||
; cmp [es:mi.GreenMaskSize],5
|
||||
; jne .l0
|
||||
; mov [es:mi.BitsPerPixel],15
|
||||
|
||||
|
||||
.l0:
|
||||
cmp [es:mi.XRes],640
|
||||
jb @f
|
||||
cmp [es:mi.YRes],480
|
||||
jb @f
|
||||
; cmp [es:mi.BitsPerPixel],8
|
||||
; jb @f
|
||||
|
||||
mov ax,[es:mi.XRes]
|
||||
mov [es:bx+0],ax ; +0[2] : resolution X
|
||||
mov ax,[es:mi.YRes]
|
||||
mov [es:bx+2],ax ; +2[2] : resolution Y
|
||||
mov ax,[es:mi.ModeAttributes]
|
||||
mov [es:bx+4],ax ; +4[2] : attributes
|
||||
|
||||
cmp [s_vesa.ver],'2'
|
||||
jb .lp1
|
||||
|
||||
or cx,0x4000 ; use LFB
|
||||
.lp1: mov [es:bx+6],cx ; +6 : mode number
|
||||
movzx ax,byte [es:mi.BitsPerPixel]
|
||||
mov word [es:bx+8],ax ; +8 : bits per pixel
|
||||
add bx,size_of_step ; size of record
|
||||
|
||||
@@:
|
||||
add si,2
|
||||
jmp .next_mode
|
||||
|
||||
.modes_ok.2:
|
||||
|
||||
mov word[es:bx],-1 ;end video table
|
||||
mov word[end_cursor],bx ;save end cursor position
|
||||
;;;;;;;;;;;;;;;;;;
|
||||
;Sort array
|
||||
; mov si,modes_table
|
||||
;.new_mode:
|
||||
; mov ax,word [es:si]
|
||||
; cmp ax,-1
|
||||
; je .exxit
|
||||
; add ax,word [es:si+2]
|
||||
; add ax,word [es:si+8]
|
||||
; mov bp,si
|
||||
;.again:
|
||||
; add bp,12
|
||||
; mov bx,word [es:bp]
|
||||
; cmp bx,-1
|
||||
; je .exit
|
||||
; add bx,word [es:bp+2]
|
||||
; add bx,word [es:bp+8]
|
||||
;
|
||||
; cmp ax,bx
|
||||
; ja .loops
|
||||
; jmp .again
|
||||
;.loops:
|
||||
; push dword [es:si]
|
||||
; push dword [es:si+4]
|
||||
; push dword [es:si+8]
|
||||
; push dword [es:bp]
|
||||
; push dword [es:bp+4]
|
||||
; push dword [es:bp+8]
|
||||
;
|
||||
; pop dword [es:si+8]
|
||||
; pop dword [es:si+4]
|
||||
; pop dword [es:si]
|
||||
; pop dword [es:bp+8]
|
||||
; pop dword [es:bp+4]
|
||||
; pop dword [es:bp]
|
||||
; jmp .new_mode
|
||||
;
|
||||
;.exit: add si,12
|
||||
; jmp .new_mode
|
||||
;.exxit:
|
||||
popad
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
draw_current_vmode:
|
||||
push 0
|
||||
pop es
|
||||
|
||||
mov si,word [cursor_pos]
|
||||
|
||||
cmp word [es:si+6],0x12
|
||||
je .no_vesa_0x12
|
||||
|
||||
cmp word [es:si+6],0x13
|
||||
je .no_vesa_0x13
|
||||
|
||||
mov di,config_file_variables
|
||||
movzx eax,word[es:si+0]
|
||||
mov ecx,10
|
||||
call int2strnz
|
||||
mov byte[es:di],'x'
|
||||
inc di
|
||||
movzx eax,word[es:si+2]
|
||||
call int2strnz
|
||||
mov byte[es:di],'x'
|
||||
inc di
|
||||
movzx eax,word[es:si+8]
|
||||
call int2strnz
|
||||
mov dword[es:di],0x00000d0a
|
||||
mov si,config_file_variables
|
||||
push ds
|
||||
push es
|
||||
pop ds
|
||||
call printplain
|
||||
pop ds
|
||||
ret
|
||||
.no_vesa_0x13:
|
||||
mov si,mode0
|
||||
jmp .print
|
||||
.no_vesa_0x12:
|
||||
mov si,mode9
|
||||
.print:
|
||||
call printplain
|
||||
ret
|
||||
;-----------------------------------------------------------------------------
|
||||
check_first_parm:
|
||||
mov cx, [number_vm]
|
||||
jcxz .novbemode
|
||||
mov si, modes_table
|
||||
.findvbemode:
|
||||
cmp [es:si+6], cx
|
||||
jnz @f
|
||||
cmp word [es:si+8],32
|
||||
je .ok_found_mode
|
||||
cmp word [es:si+8],24
|
||||
je .ok_found_mode
|
||||
@@: add si,size_of_step
|
||||
cmp word [es:si],-1
|
||||
jnz .findvbemode
|
||||
.novbemode:
|
||||
mov ax, [x_save]
|
||||
test ax, ax
|
||||
jz .zerro
|
||||
mov bx, [y_save]
|
||||
mov si, modes_table
|
||||
call .loops
|
||||
test ax, ax
|
||||
jz .ok_found_mode
|
||||
.zerro:
|
||||
; mov ax,modes_table
|
||||
; mov word [cursor_pos],ax
|
||||
; mov word [home_cursor],ax
|
||||
; mov word [preboot_graph],ax
|
||||
;SET default video of mode first probe will fined a move of work 1024x768@32
|
||||
|
||||
mov ax,1024
|
||||
mov bx,768
|
||||
mov si,modes_table
|
||||
call .loops
|
||||
test ax,ax
|
||||
jz .ok_found_mode
|
||||
mov ax,800
|
||||
mov bx,600
|
||||
mov si,modes_table
|
||||
call .loops
|
||||
test ax,ax
|
||||
jz .ok_found_mode
|
||||
mov ax,640
|
||||
mov bx,480
|
||||
mov si,modes_table
|
||||
call .loops
|
||||
test ax,ax
|
||||
jz .ok_found_mode
|
||||
|
||||
mov si,modes_table
|
||||
|
||||
.ok_found_mode:
|
||||
mov word [home_cursor],si
|
||||
; mov word [cursor_pos],si
|
||||
mov word [preboot_graph],si
|
||||
mov ax,si
|
||||
|
||||
mov ecx,long_v_table
|
||||
|
||||
.loop: add ax,size_of_step
|
||||
cmp ax,word [end_cursor]
|
||||
jae .next_step
|
||||
loop .loop
|
||||
.next_step:
|
||||
sub ax,size_of_step*long_v_table
|
||||
cmp ax,modes_table
|
||||
jae @f
|
||||
mov ax,modes_table
|
||||
@@:
|
||||
|
||||
mov word [home_cursor],ax
|
||||
mov si,[preboot_graph]
|
||||
mov word [cursor_pos],si
|
||||
|
||||
push word [es:si]
|
||||
pop word [x_save]
|
||||
push word [es:si+2]
|
||||
pop word [y_save]
|
||||
push word [es:si+6]
|
||||
pop word [number_vm]
|
||||
|
||||
ret
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
.loops:
|
||||
cmp ax,word [es:si]
|
||||
jne .next
|
||||
cmp bx,word [es:si+2]
|
||||
jne .next
|
||||
cmp word [es:si+8],32
|
||||
je .ok
|
||||
cmp word [es:si+8],24
|
||||
je .ok
|
||||
.next: add si,size_of_step
|
||||
cmp word [es:si],-1
|
||||
je .exit
|
||||
jmp .loops
|
||||
.ok: xor ax,ax
|
||||
ret
|
||||
.exit: or ax,-1
|
||||
ret
|
||||
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
;default_vmode:
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
draw_vmodes_table:
|
||||
_setcursor 9, 2
|
||||
mov si,gr_mode
|
||||
call printplain
|
||||
|
||||
mov si,_st
|
||||
call printplain
|
||||
|
||||
push word [cursor_pos]
|
||||
pop ax
|
||||
push word [home_cursor]
|
||||
pop si
|
||||
mov cx,si
|
||||
|
||||
cmp ax,si
|
||||
je .ok
|
||||
jb .low
|
||||
|
||||
|
||||
add cx,size_of_step*long_v_table
|
||||
|
||||
cmp ax,cx
|
||||
jb .ok
|
||||
|
||||
sub cx,size_of_step*long_v_table
|
||||
add cx,size_of_step
|
||||
cmp cx,word[end_cursor]
|
||||
jae .ok
|
||||
add si,size_of_step
|
||||
push si
|
||||
pop word [home_cursor]
|
||||
jmp .ok
|
||||
|
||||
|
||||
.low: sub cx,size_of_step
|
||||
cmp cx,modes_table
|
||||
jb .ok
|
||||
push cx
|
||||
push cx
|
||||
pop word [home_cursor]
|
||||
pop si
|
||||
|
||||
|
||||
.ok:
|
||||
; calculate scroll position
|
||||
push si
|
||||
mov ax, [end_cursor]
|
||||
sub ax, modes_table
|
||||
mov bx, size_of_step
|
||||
cwd
|
||||
div bx
|
||||
mov si, ax ; si = size of list
|
||||
mov ax, [home_cursor]
|
||||
sub ax, modes_table
|
||||
cwd
|
||||
div bx
|
||||
mov di, ax
|
||||
mov ax, scroll_area_size*long_v_table
|
||||
cwd
|
||||
div si
|
||||
test ax, ax
|
||||
jnz @f
|
||||
inc ax
|
||||
@@:
|
||||
cmp al, scroll_area_size
|
||||
jb @f
|
||||
mov al, scroll_area_size
|
||||
@@:
|
||||
mov cx, ax
|
||||
; cx = scroll height
|
||||
; calculate scroll pos
|
||||
xor bx, bx ; initialize scroll pos
|
||||
sub al, scroll_area_size+1
|
||||
neg al
|
||||
sub si, long_v_table-1
|
||||
jbe @f
|
||||
mul di
|
||||
div si
|
||||
mov bx, ax
|
||||
@@:
|
||||
inc bx
|
||||
imul ax, bx, size_of_step
|
||||
add ax, [home_cursor]
|
||||
mov [scroll_start], ax
|
||||
imul cx, size_of_step
|
||||
add ax, cx
|
||||
mov [scroll_end], ax
|
||||
pop si
|
||||
mov bp,long_v_table ;show rows
|
||||
.@@_next_bit:
|
||||
;clear cursor
|
||||
mov ax,' '
|
||||
mov word[ds:_r1+21],ax
|
||||
mov word[ds:_r1+50],ax
|
||||
|
||||
mov word[ds:_r2+21],ax
|
||||
mov word[ds:_r2+45],ax
|
||||
|
||||
mov word[ds:_rs+21],ax
|
||||
mov word[ds:_rs+46],ax
|
||||
; draw string
|
||||
cmp word [es:si+6],0x12
|
||||
je .show_0x12
|
||||
cmp word [es:si+6],0x13
|
||||
je .show_0x13
|
||||
|
||||
movzx eax,word[es:si]
|
||||
cmp ax,-1
|
||||
je .@@_end
|
||||
mov di,_rs+23
|
||||
mov ecx,10
|
||||
mov bl,4
|
||||
call int2str
|
||||
movzx eax,word[es:si+2]
|
||||
inc di
|
||||
mov bl,4
|
||||
call int2str
|
||||
|
||||
movzx eax,word[es:si+8]
|
||||
inc di
|
||||
mov bl,2
|
||||
call int2str
|
||||
|
||||
cmp si, word [cursor_pos]
|
||||
jne .next
|
||||
;draw cursor
|
||||
mov word[ds:_rs+21],'>>'
|
||||
mov word[ds:_rs+46],'<<'
|
||||
|
||||
|
||||
|
||||
.next:
|
||||
push si
|
||||
mov si,_rs
|
||||
.@@_sh:
|
||||
; add to the string pseudographics for scrollbar
|
||||
pop bx
|
||||
push bx
|
||||
mov byte [si+53], ' '
|
||||
cmp bx, [scroll_start]
|
||||
jb @f
|
||||
cmp bx, [scroll_end]
|
||||
jae @f
|
||||
mov byte [si+53], 0xDB ; filled bar
|
||||
@@:
|
||||
push bx
|
||||
add bx, size_of_step
|
||||
cmp bx, [end_cursor]
|
||||
jnz @f
|
||||
mov byte [si+53], 31 ; 'down arrow' symbol
|
||||
@@:
|
||||
sub bx, [home_cursor]
|
||||
cmp bx, size_of_step*long_v_table
|
||||
jnz @f
|
||||
mov byte [si+53], 31 ; 'down arrow' symbol
|
||||
@@:
|
||||
pop bx
|
||||
cmp bx, [home_cursor]
|
||||
jnz @f
|
||||
mov byte [si+53], 30 ; 'up arrow' symbol
|
||||
@@:
|
||||
call printplain
|
||||
pop si
|
||||
add si,size_of_step
|
||||
|
||||
dec bp
|
||||
jnz .@@_next_bit
|
||||
|
||||
.@@_end:
|
||||
mov si,_bt
|
||||
call printplain
|
||||
ret
|
||||
.show_0x13:
|
||||
push si
|
||||
|
||||
cmp si, word [cursor_pos]
|
||||
jne @f
|
||||
mov word[ds:_r1+21],'>>'
|
||||
mov word[ds:_r1+50],'<<'
|
||||
@@:
|
||||
mov si,_r1
|
||||
jmp .@@_sh
|
||||
.show_0x12:
|
||||
push si
|
||||
cmp si, word [cursor_pos]
|
||||
jne @f
|
||||
|
||||
mov word[ds:_r2+21],'>>'
|
||||
mov word[ds:_r2+45],'<<'
|
||||
@@:
|
||||
mov si,_r2
|
||||
jmp .@@_sh
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
;Clear arrea of current video page (0xb800)
|
||||
clear_vmodes_table:
|
||||
pusha
|
||||
; draw frames
|
||||
push es
|
||||
push 0xb800
|
||||
pop es
|
||||
mov di,1444
|
||||
xor ax,ax
|
||||
mov ah, 1*16+15
|
||||
mov cx,70
|
||||
mov bp,12
|
||||
.loop_start:
|
||||
rep stosw
|
||||
mov cx,70
|
||||
add di,20
|
||||
dec bp
|
||||
jns .loop_start
|
||||
pop es
|
||||
popa
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
set_vmode:
|
||||
push 0 ;0;x1000
|
||||
pop es
|
||||
|
||||
mov si,word [preboot_graph] ;[preboot_graph]
|
||||
mov cx,word [es:si+6] ; number of mode
|
||||
|
||||
|
||||
mov ax,word [es:si+0] ; resolution X
|
||||
mov bx,word [es:si+2] ; resolution Y
|
||||
|
||||
|
||||
mov word [es:0x900A],ax ; resolution X
|
||||
mov word [es:0x900C],bx ; resolution Y
|
||||
mov word [es:0x9008],cx ; number of mode
|
||||
|
||||
cmp cx,0x12
|
||||
je .mode0x12_0x13
|
||||
cmp cx,0x13
|
||||
je .mode0x12_0x13
|
||||
|
||||
|
||||
cmp byte [s_vesa.ver],'2'
|
||||
jb .vesa12
|
||||
|
||||
; VESA 2 and Vesa 3
|
||||
|
||||
mov ax,0x4f01
|
||||
and cx,0xfff
|
||||
mov di,mi;0xa000
|
||||
int 0x10
|
||||
; LFB
|
||||
mov eax,[es:mi.PhysBasePtr];di+0x28]
|
||||
mov [es:0x9018],eax
|
||||
; ---- vbe voodoo
|
||||
BytesPerLine equ 0x10
|
||||
mov ax, [es:di+BytesPerLine]
|
||||
mov [es:0x9001], ax
|
||||
; BPP
|
||||
cmp [es:mi.BitsPerPixel],16
|
||||
jne .l0
|
||||
cmp [es:mi.GreenMaskSize],5
|
||||
jne .l0
|
||||
mov [es:mi.BitsPerPixel],15
|
||||
.l0:
|
||||
mov al, byte [es:di+0x19]
|
||||
mov [es:0x9000], al
|
||||
jmp .exit
|
||||
|
||||
.mode0x12_0x13:
|
||||
mov byte [es:0x9000], 32
|
||||
or dword [es:0x9018], 0xFFFFFFFF; 0x800000
|
||||
|
||||
|
||||
; VESA 1.2 PM BANK SWITCH ADDRESS
|
||||
|
||||
.vesa12:
|
||||
|
||||
|
||||
mov ax,0x4f0A
|
||||
xor bx,bx
|
||||
int 0x10
|
||||
xor eax,eax
|
||||
xor ebx,ebx
|
||||
mov ax,es
|
||||
shl eax,4
|
||||
mov bx,di
|
||||
add eax,ebx
|
||||
movzx ebx,word[es:di]
|
||||
add eax,ebx
|
||||
push 0x0000
|
||||
pop es
|
||||
mov [es:0x9014],eax
|
||||
.exit:
|
||||
ret
|
||||
|
||||
|
||||
; mov dword[es:0x9018],0x000A0000
|
||||
; ret
|
||||
|
||||
;=============================================================================
|
||||
;=============================================================================
|
||||
;=============================================================================
|
||||
|
16
kernel/branches/kolibri-cfg/boot/et.inc
Normal file
16
kernel/branches/kolibri-cfg/boot/et.inc
Normal file
@ -0,0 +1,16 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
; Full ASCII code font
|
||||
; only õ and ä added
|
||||
; Kaitz
|
||||
ET_FNT:
|
||||
fontfile file "ETFONT.FNT"
|
||||
|
170
kernel/branches/kolibri-cfg/boot/parsers.inc
Normal file
170
kernel/branches/kolibri-cfg/boot/parsers.inc
Normal file
@ -0,0 +1,170 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: $
|
||||
|
||||
; All parsers are called with ds:si -> value of the variable,
|
||||
; possibly with spaces before, and dx = limit of config file.
|
||||
|
||||
; Three subroutines parse_char, parse_number and parse_bool set CF
|
||||
; if something has failed, otherwise return the value in al/ax.
|
||||
|
||||
parse_timeout:
|
||||
; timeout is a number not greater than 9
|
||||
call parse_number
|
||||
jc .nothing
|
||||
cmp ax, 9
|
||||
jbe @f
|
||||
mov ax, 9
|
||||
@@:
|
||||
imul ax, 18
|
||||
mov [es:preboot_timeout], ax
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
parse_resolution:
|
||||
; resolution is <width>*<height>, 'x' can be used instead of '*'
|
||||
; parse width
|
||||
call parse_number
|
||||
jc .nothing
|
||||
; save width
|
||||
xchg ax, bx
|
||||
; test for 'x' or '*'
|
||||
call parse_char
|
||||
cmp al, 'x'
|
||||
jz @f
|
||||
cmp al, '*'
|
||||
jnz .nothing
|
||||
@@:
|
||||
; parse height
|
||||
call parse_number
|
||||
jc .nothing
|
||||
; write width and height
|
||||
mov [es:x_save], bx
|
||||
mov [es:y_save], ax
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
parse_vbemode:
|
||||
; vbemode is a number
|
||||
call parse_number
|
||||
jc .nothing
|
||||
mov [es:number_vm], ax
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
parse_vrr:
|
||||
; vrr is a boolean setting
|
||||
call parse_bool
|
||||
jc .nothing
|
||||
; convert 0 to 2, 1 to 1
|
||||
inc ax
|
||||
xor al, 3
|
||||
mov [es:preboot_vrrm], al
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
parse_biosdisks:
|
||||
; using biosdisks is a boolean setting
|
||||
call parse_bool
|
||||
jc .nothing
|
||||
; convert 0 to 2, 1 to 1
|
||||
inc ax
|
||||
xor al, 3
|
||||
mov [es:preboot_biosdisk], al
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
parse_imgfrom:
|
||||
; boot device (1-floppy 2-kolibri.img using primary loader)
|
||||
call parse_number
|
||||
jc .nothing
|
||||
cmp al, 1
|
||||
jb .nothing
|
||||
cmp al, 2
|
||||
ja .nothing
|
||||
mov [es:preboot_device], al
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
parse_char:
|
||||
; skip spaces and return the next character or CF if EOF.
|
||||
cmp si, dx
|
||||
jae .eof
|
||||
lodsb
|
||||
cmp al, ' '
|
||||
jbe parse_char
|
||||
ret
|
||||
.eof:
|
||||
stc
|
||||
ret
|
||||
|
||||
parse_number:
|
||||
; initialize high part of ax to zero
|
||||
xor ax, ax
|
||||
; skip spaces
|
||||
call parse_char
|
||||
jc .bad
|
||||
; al should be a digit
|
||||
sub al, '0'
|
||||
cmp al, 9
|
||||
ja .bad
|
||||
; accumulate the value in cx
|
||||
xchg cx, ax
|
||||
@@:
|
||||
cmp si, dx
|
||||
jae .eof
|
||||
lodsb
|
||||
sub al, '0'
|
||||
cmp al, 9
|
||||
ja .end
|
||||
imul cx, 10
|
||||
add cx, ax
|
||||
jmp @b
|
||||
; if the end is caused by non-digit, unwind the last character
|
||||
.end:
|
||||
dec si
|
||||
.eof:
|
||||
xchg cx, ax
|
||||
clc
|
||||
ret
|
||||
.bad:
|
||||
stc
|
||||
ret
|
||||
|
||||
parse_bool:
|
||||
; skip spaces
|
||||
call parse_char
|
||||
jc .bad
|
||||
; Boolean false can be represented as 0=no=off,
|
||||
; boolean true can be represented as 1=yes=on.
|
||||
cmp al, '0'
|
||||
jz .false
|
||||
cmp al, '1'
|
||||
jz .true
|
||||
mov ah, al
|
||||
cmp si, dx
|
||||
jae .bad
|
||||
lodsb
|
||||
cmp ax, 'n'*256 + 'o'
|
||||
jz .false
|
||||
cmp ax, 'o'*256 + 'f'
|
||||
jz .false
|
||||
cmp ax, 'y'*256 + 'e'
|
||||
jz .true
|
||||
cmp ax, 'o'*256 + 'n'
|
||||
jz .true
|
||||
.bad:
|
||||
stc
|
||||
ret
|
||||
.true:
|
||||
xor ax, ax
|
||||
inc ax
|
||||
ret
|
||||
.false:
|
||||
xor ax, ax
|
||||
ret
|
39
kernel/branches/kolibri-cfg/boot/preboot.inc
Normal file
39
kernel/branches/kolibri-cfg/boot/preboot.inc
Normal file
@ -0,0 +1,39 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
display_modechg db 0 ; display mode change for text, yes/no (0 or 2)
|
||||
;
|
||||
; !! Important note !!
|
||||
;
|
||||
; Must be set to 2, to avoid two screenmode
|
||||
; changes within a very short period of time.
|
||||
|
||||
display_atboot db 0 ; show boot screen messages ( 2-no )
|
||||
|
||||
preboot_graph dw 0
|
||||
x_save dw 0 ; x
|
||||
y_save dw 0 ; y
|
||||
number_vm dw 0 ;
|
||||
;pixel_save dw 0 ; per to pixel
|
||||
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
|
||||
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
|
||||
preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never)
|
||||
preboot_device db 0 ; boot device
|
||||
; (1-floppy 2-read kolibri.img using primary loader)
|
||||
;!!!! 0 - autodetect !!!!
|
||||
preboot_blogesc = 0 ; start immediately after bootlog
|
||||
preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no)
|
||||
preboot_timeout dw 5*18 ; timeout in 1/18th of second
|
||||
|
||||
if $>0x200
|
||||
ERROR: prebooting parameters must fit in first sector!!!
|
||||
end if
|
||||
hdsysimage db 'KOLIBRI IMG' ; load from
|
||||
image_save db 'KOLIBRI IMG' ; save to
|
102
kernel/branches/kolibri-cfg/boot/ru.inc
Normal file
102
kernel/branches/kolibri-cfg/boot/ru.inc
Normal file
@ -0,0 +1,102 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
; Generated by RUFNT.EXE
|
||||
; By BadBugsKiller (C)
|
||||
; Modifyed by BadBugsKiller 12.01.2004 17:45
|
||||
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé,
|
||||
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà.
|
||||
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòðàíèöà 866.
|
||||
RU_FNT1:
|
||||
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
RU_FNT2:
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
|
||||
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
150
kernel/branches/kolibri-cfg/boot/shutdown.inc
Normal file
150
kernel/branches/kolibri-cfg/boot/shutdown.inc
Normal file
@ -0,0 +1,150 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; Shutdown for Menuet ;;
|
||||
;; ;;
|
||||
;; Distributed under General Public License ;;
|
||||
;; See file COPYING for details. ;;
|
||||
;; Copyright 2003 Ville Turjanmaa ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
align 4
|
||||
pr_mode_exit:
|
||||
|
||||
; setup stack
|
||||
mov ax, 0x3000
|
||||
mov ss, ax
|
||||
mov esp, 0x0EC00
|
||||
; setup ds
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
lidt [old_ints_h]
|
||||
;remap IRQs
|
||||
mov al,0x11
|
||||
out 0x20,al
|
||||
call rdelay
|
||||
out 0xA0,al
|
||||
call rdelay
|
||||
|
||||
mov al,0x08
|
||||
out 0x21,al
|
||||
call rdelay
|
||||
mov al,0x70
|
||||
out 0xA1,al
|
||||
call rdelay
|
||||
|
||||
mov al,0x04
|
||||
out 0x21,al
|
||||
call rdelay
|
||||
mov al,0x02
|
||||
out 0xA1,al
|
||||
call rdelay
|
||||
|
||||
mov al,0x01
|
||||
out 0x21,al
|
||||
call rdelay
|
||||
out 0xA1,al
|
||||
call rdelay
|
||||
|
||||
mov al,0xB8
|
||||
out 0x21,al
|
||||
call rdelay
|
||||
mov al,0xBD
|
||||
out 0xA1,al
|
||||
sti
|
||||
|
||||
temp_3456:
|
||||
xor ax,ax
|
||||
mov es,ax
|
||||
mov al,byte [es:0x9030]
|
||||
cmp al,1
|
||||
jl nbw
|
||||
cmp al,4
|
||||
jle nbw32
|
||||
|
||||
nbw:
|
||||
in al,0x60
|
||||
cmp al,6
|
||||
jae nbw
|
||||
mov bl,al
|
||||
nbw2:
|
||||
in al,0x60
|
||||
cmp al,bl
|
||||
je nbw2
|
||||
cmp al,240 ;ax,240
|
||||
jne nbw31
|
||||
mov al,bl
|
||||
dec ax
|
||||
jmp nbw32
|
||||
nbw31:
|
||||
add bl,128
|
||||
cmp al,bl
|
||||
jne nbw
|
||||
sub al,129
|
||||
|
||||
nbw32:
|
||||
|
||||
dec ax
|
||||
dec ax ; 2 = power off
|
||||
jnz no_apm_off
|
||||
call APM_PowerOff
|
||||
jmp $
|
||||
no_apm_off:
|
||||
|
||||
; 3 = reboot, 4 = obsolete restart kernel
|
||||
push 0x40
|
||||
pop ds
|
||||
mov word[0x0072],0x1234
|
||||
jmp 0xF000:0xFFF0
|
||||
|
||||
|
||||
rdelay:
|
||||
ret
|
||||
|
||||
APM_PowerOff:
|
||||
mov ax, 5304h
|
||||
xor bx, bx
|
||||
int 15h
|
||||
;!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
mov ax,0x5300
|
||||
xor bx,bx
|
||||
int 0x15
|
||||
push ax
|
||||
|
||||
mov ax,0x5301
|
||||
xor bx,bx
|
||||
int 0x15
|
||||
|
||||
mov ax,0x5308
|
||||
mov bx,1
|
||||
mov cx,bx
|
||||
int 0x15
|
||||
|
||||
mov ax,0x530E
|
||||
xor bx,bx
|
||||
pop cx
|
||||
int 0x15
|
||||
|
||||
mov ax,0x530D
|
||||
mov bx,1
|
||||
mov cx,bx
|
||||
int 0x15
|
||||
|
||||
mov ax,0x530F
|
||||
mov bx,1
|
||||
mov cx,bx
|
||||
int 0x15
|
||||
|
||||
mov ax,0x5307
|
||||
mov bx,1
|
||||
mov cx,3
|
||||
int 0x15
|
||||
;!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
ret
|
@ -0,0 +1,2 @@
|
||||
@fasm -m 65535 kordldr.win.asm kordldr.win
|
||||
@pause
|
509
kernel/branches/kolibri-cfg/bootloader/after_win/fat.inc
Normal file
509
kernel/branches/kolibri-cfg/bootloader/after_win/fat.inc
Normal file
@ -0,0 +1,509 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
; in: ss:bp = 0:dat
|
||||
; in: es:bx = address to load file
|
||||
; in: ds:si -> ASCIIZ name
|
||||
; in: cx = limit in sectors
|
||||
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file has been loaded, bx=2 - file not found
|
||||
; out: dx:ax = file size (0xFFFFFFFF if file not found)
|
||||
load_file_fat:
|
||||
mov eax, [bp + root_clus - dat]
|
||||
mov [bp + cur_obj - dat], root_string
|
||||
push es
|
||||
push bx
|
||||
push cx
|
||||
.parse_dir_loop:
|
||||
; convert name to FAT name
|
||||
push [bp + cur_obj - dat]
|
||||
push ax
|
||||
mov [bp + cur_obj - dat], si
|
||||
push ss
|
||||
pop es
|
||||
; convert ASCIIZ filename to FAT name
|
||||
mov di, fat_filename
|
||||
push di
|
||||
mov cx, 8+3
|
||||
mov al, ' '
|
||||
rep stosb
|
||||
pop di
|
||||
mov cl, 8 ; 8 symbols per name
|
||||
mov bl, 1
|
||||
.nameloop:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .namedone
|
||||
cmp al, '/'
|
||||
jz .namedone
|
||||
cmp al, '.'
|
||||
jz .namedot
|
||||
dec cx
|
||||
js .badname
|
||||
cmp al, 'a'
|
||||
jb @f
|
||||
cmp al, 'z'
|
||||
ja @f
|
||||
sub al, 'a'-'A'
|
||||
@@:
|
||||
stosb
|
||||
jmp .nameloop
|
||||
.namedot:
|
||||
inc bx
|
||||
jp .badname
|
||||
add di, cx
|
||||
mov cl, 3
|
||||
jmp .nameloop
|
||||
.badname:
|
||||
mov si, badname_msg
|
||||
jmp find_error_si
|
||||
.namedone:
|
||||
; scan directory
|
||||
pop ax ; eax = cluster of directory
|
||||
; high word of eax is preserved by operations above
|
||||
push ds
|
||||
push si
|
||||
; read a folder sector-by-sector and scan
|
||||
; first, try to use the cache
|
||||
push ss
|
||||
pop ds
|
||||
mov bx, -2
|
||||
mov cx, [bp + rootcache_size - dat]
|
||||
cmp [bp + root_clus - dat], eax
|
||||
jz .lookcache_root
|
||||
mov di, foldcache_mark
|
||||
xor bx, bx
|
||||
mov cx, [bp + cachelimit - dat]
|
||||
@@:
|
||||
lea si, [di+bx]
|
||||
mov edx, dword [foldcache_clus+si-foldcache_mark+bx]
|
||||
cmp edx, eax
|
||||
jz .cacheok
|
||||
test edx, edx
|
||||
jz .cacheadd ; the cache has place for new entry
|
||||
inc bx
|
||||
inc bx
|
||||
dec cx
|
||||
js @b
|
||||
; the folder is not present in the cache, so add it
|
||||
; the cache is full; find the oldest entry and replace it with the new one
|
||||
mov bx, -2
|
||||
mov dx, [bp + cachelimit - dat]
|
||||
@@:
|
||||
inc bx
|
||||
inc bx
|
||||
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
|
||||
jnz @b
|
||||
.cacheadd:
|
||||
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
|
||||
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
|
||||
lea si, [di+bx]
|
||||
mov dword [foldcache_clus+si-foldcache_mark+bx], eax
|
||||
.cacheok:
|
||||
; update cache marks
|
||||
mov dx, [di+bx]
|
||||
mov cx, [foldcache_size+di-foldcache_mark+bx]
|
||||
mov di, [bp + cachelimit - dat]
|
||||
add di, di
|
||||
.cacheupdate:
|
||||
cmp [foldcache_mark+di], dx
|
||||
adc [foldcache_mark+di], 0
|
||||
dec di
|
||||
dec di
|
||||
jns .cacheupdate
|
||||
and [foldcache_mark+bx], 0
|
||||
; done, bx contains (position in cache)*2
|
||||
.lookcache_root:
|
||||
; bx = (position in cache)*2 for non-root folders; bx = -2 for root folder
|
||||
;mov dx, bx
|
||||
;shl dx, 8
|
||||
;add dx, 0x9200
|
||||
lea dx, [bx + 0x92]
|
||||
xchg dl, dh
|
||||
mov ds, dx
|
||||
mov si, fat_filename ; ss:si -> filename in FAT style
|
||||
call fat_scan_for_filename
|
||||
jz .lookup_done
|
||||
; cache miss, read folder data from disk
|
||||
; we are reading parent directory, it can result in disk read errors; restore [cur_obj]
|
||||
mov di, sp
|
||||
mov bx, [bp + cur_obj - dat]
|
||||
xchg bx, [ss:di+4]
|
||||
mov [bp + cur_obj - dat], bx
|
||||
mov bx, cx
|
||||
add bx, 0xF
|
||||
shr bx, 4
|
||||
shl cx, 5
|
||||
mov di, cx ; es:di -> free space in cache entry
|
||||
; external loop: scan clusters
|
||||
.folder_next_cluster:
|
||||
; internal loop: scan sectors in cluster
|
||||
movzx ecx, byte [ss:0x320D] ; BPB_SecPerClus
|
||||
push eax
|
||||
; FAT12/16 root - special handling
|
||||
test eax, eax
|
||||
jnz .folder_notroot
|
||||
mov cx, [ss:0x3211] ; BPB_RootEntCnt
|
||||
mov dx, cx
|
||||
add cx, 0xF
|
||||
rcr cx, 1
|
||||
shr cx, 3
|
||||
mov eax, [bp + root_start - dat]
|
||||
jmp .folder_next_sector
|
||||
.folder_notroot:
|
||||
mul ecx
|
||||
add eax, [bp + data_start - dat]
|
||||
.folder_next_sector:
|
||||
sub dx, 0x10
|
||||
; skip first bx sectors
|
||||
dec bx
|
||||
jns .folder_skip_sector
|
||||
push cx
|
||||
push es di
|
||||
push 0x8000
|
||||
pop es
|
||||
xor bx, bx
|
||||
mov cx, 1
|
||||
push es
|
||||
call read
|
||||
jc ..found_disk_error
|
||||
; copy data to the cache...
|
||||
pop ds
|
||||
pop di es
|
||||
cmp di, 0x2000 ; ...if there is free space, of course
|
||||
jae @f
|
||||
pusha
|
||||
mov cx, 0x100
|
||||
xor si, si
|
||||
rep movsw
|
||||
mov di, es
|
||||
shr di, 8
|
||||
cmp di, 0x90
|
||||
jz .update_rootcache_size
|
||||
add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache
|
||||
jmp .updated_cachesize
|
||||
.update_rootcache_size:
|
||||
mov cl, 0x10
|
||||
cmp cx, dx
|
||||
jb @f
|
||||
mov cx, dx
|
||||
@@:
|
||||
add [bp + rootcache_size - dat], cx
|
||||
.updated_cachesize:
|
||||
popa
|
||||
@@:
|
||||
push es
|
||||
mov cl, 0x10 ; ch=0 at this point
|
||||
cmp cx, dx
|
||||
jb @f
|
||||
mov cx, dx
|
||||
@@:
|
||||
call fat_scan_for_filename
|
||||
pop es
|
||||
pop cx
|
||||
jz .lookup_done_pop
|
||||
.folder_skip_sector:
|
||||
inc eax
|
||||
loop .folder_next_sector
|
||||
pop eax ; eax = current cluster
|
||||
test eax, eax
|
||||
jz @f
|
||||
call [bp + get_next_cluster_ptr - dat]
|
||||
jc .folder_next_cluster
|
||||
@@:
|
||||
stc
|
||||
push eax
|
||||
.lookup_done_pop:
|
||||
pop eax
|
||||
.lookup_done:
|
||||
pop si
|
||||
; CF=1 <=> failed
|
||||
jnc .found
|
||||
pop ds
|
||||
pop [bp + cur_obj - dat]
|
||||
mov si, error_not_found
|
||||
jmp find_error_si
|
||||
.found:
|
||||
mov eax, [di+20-2]
|
||||
mov edx, [di+28]
|
||||
mov ax, [di+26] ; get cluster
|
||||
test byte [di+11], 10h ; directory?
|
||||
pop ds
|
||||
pop [bp + cur_obj - dat] ; forget old [cur_obj]
|
||||
jz .regular_file
|
||||
cmp byte [si-1], 0
|
||||
jnz .parse_dir_loop
|
||||
..directory_error:
|
||||
mov si, directory_string
|
||||
jmp find_error_si
|
||||
.regular_file:
|
||||
cmp byte [si-1], 0
|
||||
jz @f
|
||||
..notdir_error:
|
||||
mov si, notdir_string
|
||||
jmp find_error_si
|
||||
@@:
|
||||
; ok, we have found a regular file and the caller requested it
|
||||
; parse FAT chunk
|
||||
push ss
|
||||
pop es
|
||||
push ss
|
||||
pop ds
|
||||
mov di, 0x4005
|
||||
mov byte [di-5], 1 ; non-resident attribute
|
||||
mov dword [di-4], 1
|
||||
stosd
|
||||
pop cx
|
||||
push cx
|
||||
.parsefat:
|
||||
call [bp + get_next_cluster_ptr - dat]
|
||||
jnc .done
|
||||
mov esi, [di-8]
|
||||
add esi, [di-4]
|
||||
cmp eax, esi
|
||||
jz .contc
|
||||
mov dword [di], 1
|
||||
scasd
|
||||
stosd
|
||||
jmp @f
|
||||
.contc:
|
||||
inc dword [di-8]
|
||||
@@:
|
||||
sub cl, [0x320D]
|
||||
sbb ch, 0
|
||||
ja .parsefat
|
||||
.done:
|
||||
xor eax, eax
|
||||
stosd
|
||||
mov si, 0x4000
|
||||
load_file_common_end:
|
||||
xor ecx, ecx
|
||||
pop cx
|
||||
pop bx
|
||||
pop es
|
||||
mov [bp + filesize - dat], edx
|
||||
mov [bp + sectors_read - dat], ecx
|
||||
add edx, 0x1FF
|
||||
shr edx, 9
|
||||
mov [bp + filesize_sectors - dat], edx
|
||||
cmp edx, ecx
|
||||
seta al
|
||||
mov ah, 0
|
||||
push ax
|
||||
call read_file_chunk
|
||||
continue_load_common_end:
|
||||
mov [bp + cur_chunk_ptr - dat], si
|
||||
pop bx
|
||||
mov ax, word [bp + filesize - dat]
|
||||
mov dx, word [bp + filesize+2 - dat]
|
||||
jnc @f
|
||||
mov bl, 3 ; read error
|
||||
@@:
|
||||
ret
|
||||
|
||||
continue_load_file:
|
||||
; es:bx -> buffer for output, ecx = cx = number of sectors
|
||||
mov si, [bp + cur_chunk_ptr - dat]
|
||||
push ecx
|
||||
add ecx, [bp + sectors_read - dat]
|
||||
mov [bp + sectors_read - dat], ecx
|
||||
cmp [bp + filesize_sectors - dat], ecx
|
||||
pop ecx
|
||||
seta al
|
||||
mov ah, 0
|
||||
push ax
|
||||
push continue_load_common_end
|
||||
push ss
|
||||
pop ds
|
||||
cmp [bp + cur_chunk_resident - dat], ah
|
||||
jnz .nonresident
|
||||
.resident:
|
||||
mov ax, word [bp + num_sectors - dat]
|
||||
jmp read_file_chunk.resident.continue
|
||||
.nonresident:
|
||||
mov eax, [bp + cur_cluster - dat]
|
||||
mov edx, [bp + num_sectors - dat]
|
||||
add eax, [bp + cur_delta - dat]
|
||||
jmp read_file_chunk.nonresident.continue
|
||||
|
||||
fat_scan_for_filename:
|
||||
; in: ss:si -> 11-bytes FAT name
|
||||
; in: ds:0 -> part of directory data
|
||||
; in: cx = number of entries
|
||||
; out: if found: CF=0, ZF=1, es:di -> directory entry
|
||||
; out: if not found, but continue required: CF=1 and ZF=0
|
||||
; out: if not found and zero item reached: CF=1 and ZF=1
|
||||
push ds
|
||||
pop es
|
||||
xor di, di
|
||||
push cx
|
||||
jcxz .noent
|
||||
.loop:
|
||||
cmp byte [di], 0
|
||||
jz .notfound
|
||||
test byte [di+11], 8 ; volume label?
|
||||
jnz .cont ; ignore volume labels
|
||||
pusha
|
||||
mov cx, 11
|
||||
repz cmps byte [ss:si], byte [es:di]
|
||||
popa
|
||||
jz .done
|
||||
.cont:
|
||||
add di, 0x20
|
||||
loop .loop
|
||||
.noent:
|
||||
inc cx ; clear ZF flag
|
||||
.notfound:
|
||||
stc
|
||||
.done:
|
||||
pop cx
|
||||
ret
|
||||
|
||||
fat12_get_next_cluster:
|
||||
; in: ax = cluster (high word of eax is zero)
|
||||
; out: if there is next cluster: CF=1, ax = next cluster
|
||||
; out: if there is no next cluster: CF=0
|
||||
push si
|
||||
push ds
|
||||
push 0x6000
|
||||
pop ds
|
||||
mov si, ax
|
||||
shr si, 1
|
||||
add si, ax
|
||||
test al, 1
|
||||
lodsw
|
||||
jz @f
|
||||
shr ax, 4
|
||||
@@:
|
||||
and ax, 0xFFF
|
||||
cmp ax, 0xFF7
|
||||
pop ds si
|
||||
ret
|
||||
|
||||
fat16_get_next_cluster:
|
||||
; in: ax = cluster (high word of eax is zero)
|
||||
; out: if there is next cluster: CF=1, ax = next cluster
|
||||
; out: if there is no next cluster: CF=0
|
||||
; each sector contains 200h bytes = 100h FAT entries
|
||||
; so ah = # of sector, al = offset in sector
|
||||
push si
|
||||
mov si, ax
|
||||
shr si, 8
|
||||
; calculate segment for this sector of FAT table
|
||||
; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si)
|
||||
; segment = 6000 + 20*si, offset = 0
|
||||
push es
|
||||
push si
|
||||
shl si, 5
|
||||
add si, 0x6000
|
||||
mov es, si
|
||||
pop si
|
||||
cmp byte [ss:0x3400+si], 0 ; sector already loaded?
|
||||
jnz .noread
|
||||
; load corresponding sector, try all FATs if disk read error detected
|
||||
pusha
|
||||
movzx di, byte [ss:0x3210] ; BPB_NumFATs
|
||||
xor bx, bx
|
||||
mov ax, [ss:0x320E] ; BPB_RsvdSecCnt
|
||||
xor dx, dx
|
||||
add ax, si
|
||||
adc dx, bx
|
||||
@@:
|
||||
push es
|
||||
push dx ax
|
||||
pop eax
|
||||
mov cx, 1 ; read 1 sector
|
||||
call read
|
||||
pop es
|
||||
jnc @f
|
||||
add ax, [ss:0x3216] ; BPB_FATSz16
|
||||
adc dx, bx
|
||||
dec di
|
||||
jnz @b
|
||||
..found_disk_error:
|
||||
mov si, disk_error_msg
|
||||
jmp find_error_si
|
||||
@@:
|
||||
popa
|
||||
.noread:
|
||||
mov si, ax
|
||||
and si, 0xFF
|
||||
add si, si
|
||||
mov ax, [es:si]
|
||||
pop es
|
||||
cmp ax, 0xFFF7
|
||||
pop si
|
||||
ret
|
||||
|
||||
fat32_get_next_cluster:
|
||||
; in: eax = cluster
|
||||
; out: if there is next cluster: CF=1, eax = next cluster
|
||||
; out: if there is no next cluster: CF=0
|
||||
push di
|
||||
push ax
|
||||
shr eax, 7
|
||||
; eax = FAT sector number; look in cache
|
||||
push si
|
||||
mov si, cache1head
|
||||
call cache_lookup
|
||||
pop si
|
||||
jnc .noread
|
||||
; read FAT, try all FATs if disk read error detected
|
||||
push es
|
||||
pushad
|
||||
movzx edx, word [ss:0x320E] ; BPB_RsvdSecCnt
|
||||
add eax, edx
|
||||
movzx si, byte [ss:0x3210] ; BPB_NumFATs
|
||||
@@:
|
||||
lea cx, [di - 0x3400 + (0x6000 shr (9-3))]
|
||||
shl cx, 9-3
|
||||
mov es, cx
|
||||
xor bx, bx
|
||||
mov cx, 1
|
||||
call read
|
||||
jnc @f
|
||||
add eax, [ss:0x3224] ; BPB_FATSz32
|
||||
dec si
|
||||
jnz @b
|
||||
jmp ..found_disk_error
|
||||
@@:
|
||||
popad
|
||||
pop es
|
||||
.noread:
|
||||
; get requested item
|
||||
lea ax, [di - 0x3400 + (0x6000 shr (9-3))]
|
||||
pop di
|
||||
and di, 0x7F
|
||||
shl di, 2
|
||||
shl ax, 9-3
|
||||
push ds
|
||||
mov ds, ax
|
||||
and byte [di+3], 0x0F
|
||||
mov eax, [di]
|
||||
pop ds
|
||||
pop di
|
||||
;and eax, 0x0FFFFFFF
|
||||
cmp eax, 0x0FFFFFF7
|
||||
ret
|
921
kernel/branches/kolibri-cfg/bootloader/after_win/kordldr.win.asm
Normal file
921
kernel/branches/kolibri-cfg/bootloader/after_win/kordldr.win.asm
Normal file
@ -0,0 +1,921 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
; KordOS bootloader, based on mtldr, KolibriOS bootloader, by diamond
|
||||
; It is used when main bootloader is Windows loader.
|
||||
|
||||
; this code is loaded:
|
||||
; NT/2k/XP: by ntldr to 0D00:0000
|
||||
; 9x: by io.sys from config.sys to xxxx:0100
|
||||
; Vista: by bootmgr to 0000:7C00
|
||||
format binary
|
||||
use16
|
||||
|
||||
; in any case, we relocate this code to 0000:0600
|
||||
org 0x600
|
||||
; entry point for 9x and Vista booting
|
||||
call @f
|
||||
db 'NTFS'
|
||||
@@:
|
||||
pop si
|
||||
sub si, 3
|
||||
cmp si, 100h
|
||||
jnz boot_vista
|
||||
mov si, load_question + 100h - 600h
|
||||
call out_string
|
||||
; mov si, answer + 100h - 0600h ; already is
|
||||
xxy: mov ah, 0
|
||||
int 16h
|
||||
or al, 20h
|
||||
mov [si], al
|
||||
cmp al, 'y'
|
||||
jz xxz
|
||||
cmp al, 'n'
|
||||
jnz xxy
|
||||
; continue load Windows
|
||||
; call out_string
|
||||
; ret
|
||||
out_string:
|
||||
push bx
|
||||
@@:
|
||||
lodsb
|
||||
test al, al
|
||||
jz @f
|
||||
mov ah, 0Eh
|
||||
mov bx, 7
|
||||
int 10h
|
||||
jmp @b
|
||||
@@:
|
||||
pop bx
|
||||
ret
|
||||
xxz:
|
||||
; boot KordOS
|
||||
call out_string
|
||||
; 9x bootloader has already hooked some interrupts; to correctly remove all DOS handlers,
|
||||
; issue int 19h (reboot interrupt) and trace its DOS handler until original BIOS handler is reached
|
||||
xor di, di
|
||||
mov ds, di
|
||||
mov word [di+4], new01handler + 100h - 600h
|
||||
mov [di+6], cs
|
||||
pushf
|
||||
pop ax
|
||||
or ah, 1
|
||||
push ax
|
||||
popf
|
||||
; we cannot issue INT 19h directly, because INT command clears TF
|
||||
; int 19h ; don't issue it directly, because INT command clears TF
|
||||
; so instead we use direct call
|
||||
; pushf ; there will be no IRET
|
||||
call far [di + 19h*4]
|
||||
xxt:
|
||||
xor di, di
|
||||
mov ds, di
|
||||
cmp word [di + 8*4+2], 0F000h
|
||||
jz @f
|
||||
les bx, [di + 8*4]
|
||||
mov eax, [es:bx+1]
|
||||
mov [di + 8*4], eax
|
||||
@@:
|
||||
mov si, 100h
|
||||
boot_vista:
|
||||
; relocate cs:si -> 0000:0600
|
||||
push cs
|
||||
pop ds
|
||||
xor ax, ax
|
||||
mov es, ax
|
||||
mov di, 0x600
|
||||
mov cx, 2000h/2
|
||||
rep movsw
|
||||
jmp 0:real_entry
|
||||
|
||||
load_question db 'Load KordOS? [y/n]: ',0
|
||||
answer db ?
|
||||
db 13,10,0
|
||||
|
||||
new01handler:
|
||||
; [sp]=ip, [sp+2]=cs, [sp+4]=flags
|
||||
push bp
|
||||
mov bp, sp
|
||||
push ds
|
||||
lds bp, [bp+2]
|
||||
cmp word [ds:bp], 19cdh
|
||||
jz xxt
|
||||
pop ds
|
||||
pop bp
|
||||
iret
|
||||
|
||||
; read from hard disk
|
||||
; in: eax = absolute sector
|
||||
; cx = number of sectors
|
||||
; es:bx -> buffer
|
||||
; out: CF=1 if error
|
||||
read:
|
||||
pushad
|
||||
add eax, [bp + partition_start - dat]
|
||||
cmp [bp + use_lba - dat], 0
|
||||
jz .chs
|
||||
; LBA read
|
||||
push ds
|
||||
.lbado:
|
||||
push ax
|
||||
push cx
|
||||
cmp cx, 0x7F
|
||||
jbe @f
|
||||
mov cx, 0x7F
|
||||
@@:
|
||||
; create disk address packet on the stack
|
||||
; dq starting LBA
|
||||
push 0
|
||||
push 0
|
||||
push eax
|
||||
; dd buffer
|
||||
push es
|
||||
push bx
|
||||
; dw number of blocks to transfer (no more than 0x7F)
|
||||
push cx
|
||||
; dw packet size in bytes
|
||||
push 10h
|
||||
; issue BIOS call
|
||||
push ss
|
||||
pop ds
|
||||
mov si, sp
|
||||
mov dl, [bp + boot_drive - dat]
|
||||
mov ah, 42h
|
||||
int 13h
|
||||
jc .disk_error_lba
|
||||
add sp, 10h ; restore stack
|
||||
; increase current sector & buffer; decrease number of sectors
|
||||
movzx esi, cx
|
||||
mov ax, es
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
pop cx
|
||||
pop ax
|
||||
add eax, esi
|
||||
sub cx, si
|
||||
jnz .lbado
|
||||
pop ds
|
||||
popad
|
||||
ret
|
||||
.disk_error_lba:
|
||||
add sp, 14h
|
||||
pop ds
|
||||
popad
|
||||
stc
|
||||
ret
|
||||
|
||||
.chs:
|
||||
pusha
|
||||
pop edi ; loword(edi) = di, hiword(edi) = si
|
||||
push bx
|
||||
|
||||
; eax / (SectorsPerTrack) -> eax, remainder bx
|
||||
movzx esi, [bp + sectors - dat]
|
||||
xor edx, edx
|
||||
div esi
|
||||
mov bx, dx ; bx = sector-1
|
||||
|
||||
; eax -> dx:ax
|
||||
push eax
|
||||
pop ax
|
||||
pop dx
|
||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
||||
div [bp + heads - dat]
|
||||
|
||||
; number of sectors: read no more than to end of track
|
||||
sub si, bx
|
||||
cmp cx, si
|
||||
jbe @f
|
||||
mov cx, si
|
||||
@@:
|
||||
|
||||
inc bx
|
||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector
|
||||
; convert to int13 format
|
||||
movzx edi, cx
|
||||
mov dh, dl
|
||||
mov dl, [bp + boot_drive - dat]
|
||||
shl ah, 6
|
||||
mov ch, al
|
||||
mov al, cl
|
||||
mov cl, bl
|
||||
or cl, ah
|
||||
pop bx
|
||||
mov si, 3
|
||||
mov ah, 2
|
||||
@@:
|
||||
push ax
|
||||
int 13h
|
||||
jnc @f
|
||||
xor ax, ax
|
||||
int 13h ; reset drive
|
||||
pop ax
|
||||
dec si
|
||||
jnz @b
|
||||
add sp, 12
|
||||
popad
|
||||
stc
|
||||
ret
|
||||
@@:
|
||||
pop ax
|
||||
mov ax, es
|
||||
mov cx, di
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
push edi
|
||||
popa
|
||||
add eax, edi
|
||||
sub cx, di
|
||||
jnz .chs
|
||||
popad
|
||||
ret
|
||||
|
||||
disk_error2 db 'Fatal: cannot read partitions info: '
|
||||
disk_error_msg db 'disk read error',0
|
||||
disk_params_msg db 'Fatal: cannot get drive parameters',0
|
||||
start_msg db 2,' KordOS bootloader',13,10,0
|
||||
part_msg db 'looking at partition '
|
||||
part_char db '0' ; will be incremented before writing message
|
||||
db ' ... ',0
|
||||
errfs_msg db 'unknown filesystem',13,10,0
|
||||
fatxx_msg db 'FATxx'
|
||||
newline db 13,10,0
|
||||
ntfs_msg db 'NTFS',13,10,0
|
||||
error_msg db 'Error'
|
||||
colon db ': ',0
|
||||
root_string db '\',0
|
||||
nomem_msg db 'No memory',0
|
||||
filesys_string db '(filesystem)',0
|
||||
directory_string db 'is a directory',0
|
||||
notdir_string db 'not a directory',0
|
||||
|
||||
; entry point for NT/2k/XP booting
|
||||
; ntldr loads our code to 0D00:0000 and jumps to 0D00:0256
|
||||
repeat 600h + 256h - $
|
||||
db 1 ; any data can be here; 1 in ASCII is a nice face :)
|
||||
end repeat
|
||||
; cs=es=0D00, ds=07C0, ss=0
|
||||
; esi=edi=ebp=0, esp=7C00
|
||||
xor si, si
|
||||
jmp boot_vista
|
||||
|
||||
real_entry:
|
||||
; ax = 0
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
; our stack is 4 Kb: memory range 2000-3000
|
||||
mov ss, ax
|
||||
mov sp, 3000h
|
||||
mov bp, dat
|
||||
sti ; just for case
|
||||
; say hi to user
|
||||
mov si, start_msg
|
||||
call out_string
|
||||
; we are booting from hard disk identified by [boot_drive]
|
||||
mov dl, [bp + boot_drive - dat]
|
||||
; is LBA supported?
|
||||
mov [bp + use_lba - dat], 0
|
||||
mov ah, 41h
|
||||
mov bx, 55AAh
|
||||
int 13h
|
||||
jc .no_lba
|
||||
cmp bx, 0AA55h
|
||||
jnz .no_lba
|
||||
test cl, 1
|
||||
jz .no_lba
|
||||
inc [bp + use_lba - dat]
|
||||
jmp disk_params_ok
|
||||
.no_lba:
|
||||
; get drive geometry
|
||||
mov ah, 8
|
||||
mov dl, [bp + boot_drive - dat]
|
||||
int 13h
|
||||
jnc @f
|
||||
mov si, disk_params_msg
|
||||
call out_string
|
||||
jmp $
|
||||
@@:
|
||||
movzx ax, dh
|
||||
inc ax
|
||||
mov [bp + heads - dat], ax
|
||||
and cx, 3Fh
|
||||
mov [bp + sectors - dat], cx
|
||||
disk_params_ok:
|
||||
; determine size of cache for folders
|
||||
int 12h ; ax = size of available base memory in Kb
|
||||
sub ax, 94000h / 1024
|
||||
jc nomem
|
||||
shr ax, 3
|
||||
mov [bp + cachelimit - dat], ax ; size of cache - 1
|
||||
; scan all partitions
|
||||
new_partition_ex:
|
||||
xor eax, eax ; read first sector of current disk area
|
||||
mov [bp + extended_part_cur - dat], eax ; no extended partition yet
|
||||
mov [bp + cur_partition_ofs - dat], 31BEh ; start from first partition
|
||||
push es
|
||||
mov cx, 1
|
||||
mov bx, 3000h
|
||||
call read
|
||||
pop es
|
||||
jnc new_partition
|
||||
mov si, disk_error2
|
||||
call out_string
|
||||
jmp $
|
||||
new_partition:
|
||||
mov bx, [bp + cur_partition_ofs - dat]
|
||||
mov al, [bx+4] ; partition type
|
||||
test al, al
|
||||
jz next_partition
|
||||
cmp al, 5
|
||||
jz @f
|
||||
cmp al, 0xF
|
||||
jnz not_extended
|
||||
@@:
|
||||
; extended partition
|
||||
mov eax, [bx+8] ; partition start
|
||||
add eax, [bp + extended_part_start - dat]
|
||||
mov [bp + extended_part_cur - dat], eax
|
||||
next_partition:
|
||||
add [bp + cur_partition_ofs - dat], 10h
|
||||
cmp [bp + cur_partition_ofs - dat], 31FEh
|
||||
jb new_partition
|
||||
mov eax, [bp + extended_part_cur - dat]
|
||||
test eax, eax
|
||||
jz partitions_done
|
||||
cmp [bp + extended_part_start - dat], 0
|
||||
jnz @f
|
||||
mov [bp + extended_part_start - dat], eax
|
||||
@@:
|
||||
mov [bp + extended_parent - dat], eax
|
||||
mov [bp + partition_start - dat], eax
|
||||
jmp new_partition_ex
|
||||
partitions_done:
|
||||
mov si, total_kaput
|
||||
call out_string
|
||||
jmp $
|
||||
not_extended:
|
||||
mov eax, [bx+8]
|
||||
add eax, [bp + extended_parent - dat]
|
||||
mov [bp + partition_start - dat], eax
|
||||
; try to load from current partition
|
||||
; inform user
|
||||
mov si, part_msg
|
||||
inc [si + part_char - part_msg]
|
||||
call out_string
|
||||
; read bootsector
|
||||
xor eax, eax
|
||||
mov [bp + cur_obj - dat], filesys_string
|
||||
push es
|
||||
mov cx, 1
|
||||
mov bx, 3200h
|
||||
call read
|
||||
pop es
|
||||
mov si, disk_error_msg
|
||||
jc find_error_si
|
||||
movzx si, byte [bx+13]
|
||||
mov word [bp + sect_per_clust - dat], si
|
||||
test si, si
|
||||
jz unknown_fs
|
||||
lea ax, [si-1]
|
||||
test si, ax
|
||||
jnz unknown_fs
|
||||
; determine file system
|
||||
; Number of bytes per sector == 0x200 (this loader assumes that physical sector size is 200h)
|
||||
cmp word [bx+11], 0x200
|
||||
jnz unknown_fs
|
||||
; is it NTFS?
|
||||
cmp dword [bx+3], 'NTFS'
|
||||
jnz not_ntfs
|
||||
cmp byte [bx+16], bl
|
||||
jz ntfs
|
||||
not_ntfs:
|
||||
; is it FAT? FAT12/FAT16/FAT32?
|
||||
; get count of sectors to dword in cx:si
|
||||
mov si, [bx+19]
|
||||
xor cx, cx
|
||||
test si, si
|
||||
jnz @f
|
||||
mov si, [bx+32]
|
||||
mov cx, [bx+34]
|
||||
@@:
|
||||
xor eax, eax
|
||||
; subtract size of system area
|
||||
sub si, [bx+14] ; BPB_ResvdSecCnt
|
||||
sbb cx, ax
|
||||
mov ax, [bx+17] ; BPB_RootEntCnt
|
||||
add ax, 0xF
|
||||
rcr ax, 1
|
||||
shr ax, 3
|
||||
sub si, ax
|
||||
sbb cx, 0
|
||||
push cx
|
||||
push si
|
||||
mov ax, word [bx+22]
|
||||
test ax, ax
|
||||
jnz @f
|
||||
mov eax, [bx+36]
|
||||
@@:
|
||||
movzx ecx, byte [bx+16]
|
||||
imul ecx, eax
|
||||
pop eax
|
||||
sub eax, ecx
|
||||
; now eax = count of sectors in the data region
|
||||
xor edx, edx
|
||||
div [bp + sect_per_clust - dat]
|
||||
; now eax = count of clusters in the data region
|
||||
mov si, fatxx_msg
|
||||
cmp eax, 0xFFF5
|
||||
jae test_fat32
|
||||
; test magic value in FAT bootsector - FAT12/16 bootsector has it at the offset +38
|
||||
cmp byte [bx+38], 0x29
|
||||
jnz not_fat
|
||||
cmp ax, 0xFF5
|
||||
jae fat16
|
||||
fat12:
|
||||
mov [bp + get_next_cluster_ptr - dat], fat12_get_next_cluster
|
||||
mov di, cx ; BPB_NumFATs
|
||||
mov ax, '12'
|
||||
push ax ; save for secondary loader
|
||||
mov word [si+3], ax
|
||||
call out_string
|
||||
movzx ecx, word [bx+22] ; BPB_FATSz16
|
||||
; FAT12: read entire FAT table (it is no more than 0x1000*3/2 = 0x1800 bytes)
|
||||
.fatloop:
|
||||
; if first copy is not readable, try to switch to other copies
|
||||
push 0x6000
|
||||
pop es
|
||||
xor bx, bx
|
||||
movzx eax, word [0x320E] ; BPB_RsvdSecCnt
|
||||
push cx
|
||||
cmp cx, 12
|
||||
jb @f
|
||||
mov cx, 12
|
||||
@@:
|
||||
call read
|
||||
pop cx
|
||||
jnc fat1x_common
|
||||
add eax, ecx ; switch to next copy of FAT
|
||||
dec di
|
||||
jnz .fatloop
|
||||
mov si, disk_error_msg
|
||||
jmp find_error_si
|
||||
fat16:
|
||||
mov [bp + get_next_cluster_ptr - dat], fat16_get_next_cluster
|
||||
mov ax, '16'
|
||||
push ax ; save for secondary loader
|
||||
mov word [si+3], ax
|
||||
call out_string
|
||||
; FAT16: init FAT cache - no sectors loaded
|
||||
mov di, 0x3400
|
||||
xor ax, ax
|
||||
mov cx, 0x100/2
|
||||
rep stosw
|
||||
fat1x_common:
|
||||
mov bx, 0x3200
|
||||
movzx eax, word [bx+22] ; BPB_FATSz16
|
||||
xor esi, esi ; no root cluster
|
||||
jmp fat_common
|
||||
test_fat32:
|
||||
; FAT32 bootsector has it at the offset +66
|
||||
cmp byte [bx+66], 0x29
|
||||
jnz not_fat
|
||||
mov [bp + get_next_cluster_ptr - dat], fat32_get_next_cluster
|
||||
mov ax, '32'
|
||||
push ax ; save for secondary loader
|
||||
mov word [si+3], ax
|
||||
call out_string
|
||||
; FAT32 - init cache for FAT table: no sectors loaded
|
||||
lea si, [bp + cache1head - dat]
|
||||
mov [si], si ; no sectors in cache:
|
||||
mov [si+2], si ; 'prev' & 'next' links point to self
|
||||
mov [bp + cache1end - dat], 3400h ; first free item = 3400h
|
||||
mov [bp + cache1limit - dat], 3C00h
|
||||
mov eax, [bx+36] ; BPB_FATSz32
|
||||
mov esi, [bx+44] ; BPB_RootClus
|
||||
jmp fat_common
|
||||
not_fat:
|
||||
unknown_fs:
|
||||
mov si, errfs_msg
|
||||
call out_string
|
||||
jmp next_partition
|
||||
fat_common:
|
||||
push ss
|
||||
pop es
|
||||
movzx edx, byte [bx+16] ; BPB_NumFATs
|
||||
mul edx
|
||||
mov [bp + root_start - dat], eax ; this is for FAT1x
|
||||
; eax = total size of all FAT tables, in sectors
|
||||
movzx ecx, word [bx+17] ; BPB_RootEntCnt
|
||||
add ecx, 0xF
|
||||
shr ecx, 4
|
||||
add eax, ecx
|
||||
mov cx, word [bx+14] ; BPB_RsvdSecCnt
|
||||
add [bp + root_start - dat], ecx ; this is for FAT1x
|
||||
add eax, ecx
|
||||
; cluster 2 begins from sector eax
|
||||
movzx ebx, byte [bx+13] ; BPB_SecPerClus
|
||||
sub eax, ebx
|
||||
sub eax, ebx
|
||||
mov [bp + data_start - dat], eax
|
||||
; no clusters in folders cache
|
||||
mov di, foldcache_clus - 2
|
||||
xor ax, ax
|
||||
mov cx, 7*8/2 + 1
|
||||
rep stosw
|
||||
mov [bp + root_clus - dat], esi
|
||||
; load secondary loader
|
||||
mov [bp + load_file_ptr - dat], load_file_fat
|
||||
load_secondary:
|
||||
push 0x1000
|
||||
pop es
|
||||
xor bx, bx
|
||||
mov si, kernel_name
|
||||
mov cx, 0x30000 / 0x200
|
||||
call [bp + load_file_ptr - dat]
|
||||
; say error if needed
|
||||
mov si, error_too_big
|
||||
dec bx
|
||||
js @f
|
||||
jz find_error_si
|
||||
mov si, disk_error_msg
|
||||
jmp find_error_si
|
||||
@@:
|
||||
; fill loader information and jump to secondary loader
|
||||
mov al, 'h' ; boot device: hard drive
|
||||
mov ah, [bp + boot_drive - dat]
|
||||
sub ah, 80h ; boot device: identifier
|
||||
pop bx ; restore file system ID ('12'/'16'/'32'/'nt')
|
||||
mov si, callback
|
||||
jmp 1000h:0000h
|
||||
|
||||
nomem:
|
||||
mov si, nomem_msg
|
||||
call out_string
|
||||
jmp $
|
||||
|
||||
ntfs:
|
||||
push 'nt' ; save for secondary loader
|
||||
mov si, ntfs_msg
|
||||
call out_string
|
||||
xor eax, eax
|
||||
mov [bp + data_start - dat], eax
|
||||
mov ecx, [bx+40h] ; frs_size
|
||||
cmp cl, al
|
||||
jg .1
|
||||
neg cl
|
||||
inc ax
|
||||
shl eax, cl
|
||||
jmp .2
|
||||
.1:
|
||||
mov eax, ecx
|
||||
shl eax, 9
|
||||
.2:
|
||||
mov [bp + frs_size - dat], ax
|
||||
; standard value for frs_size is 0x400 bytes = 1 Kb, and it cannot be set different
|
||||
; (at least with standard tools)
|
||||
; we allow extra size, but no more than 0x1000 bytes = 4 Kb
|
||||
mov si, invalid_volume_msg
|
||||
cmp eax, 0x1000
|
||||
ja find_error_si
|
||||
; must be multiple of sector size
|
||||
test ax, 0x1FF
|
||||
jnz find_error_si
|
||||
shr ax, 9
|
||||
xchg cx, ax
|
||||
; initialize cache - no data loaded
|
||||
lea si, [bp + cache1head - dat]
|
||||
mov [si], si
|
||||
mov [si+2], si
|
||||
mov word [si+4], 3400h ; first free item = 3400h
|
||||
mov word [si+6], 3400h + 8*8 ; 8 items in this cache
|
||||
; read first MFT record - description of MFT itself
|
||||
mov [bp + cur_obj - dat], mft_string
|
||||
mov eax, [bx+30h] ; mft_cluster
|
||||
mul [bp + sect_per_clust - dat]
|
||||
push 0x8000
|
||||
pop es
|
||||
xor bx, bx
|
||||
push es
|
||||
call read
|
||||
pop ds
|
||||
call restore_usa
|
||||
; scan for unnamed $DATA attribute
|
||||
mov [bp + freeattr - dat], 4000h
|
||||
mov ax, 80h
|
||||
call load_attr
|
||||
push ss
|
||||
pop ds
|
||||
mov si, nodata_string
|
||||
jc find_error_si
|
||||
; load secondary loader
|
||||
mov [bp + load_file_ptr - dat], load_file_ntfs
|
||||
jmp load_secondary
|
||||
|
||||
find_error_si:
|
||||
push si
|
||||
find_error_sp:
|
||||
cmp [bp + in_callback - dat], 0
|
||||
jnz error_in_callback
|
||||
push ss
|
||||
pop ds
|
||||
push ss
|
||||
pop es
|
||||
mov si, error_msg
|
||||
call out_string
|
||||
mov si, [bp + cur_obj - dat]
|
||||
@@:
|
||||
lodsb
|
||||
test al, al
|
||||
jz @f
|
||||
cmp al, '/'
|
||||
jz @f
|
||||
mov ah, 0Eh
|
||||
mov bx, 7
|
||||
int 10h
|
||||
jmp @b
|
||||
@@:
|
||||
mov si, colon
|
||||
call out_string
|
||||
pop si
|
||||
call out_string
|
||||
mov si, newline
|
||||
call out_string
|
||||
mov sp, 0x3000
|
||||
jmp next_partition
|
||||
error_in_callback:
|
||||
; return status: file not found, except for read errors
|
||||
mov bx, 2
|
||||
cmp si, disk_error_msg
|
||||
jnz @f
|
||||
inc bx
|
||||
@@:
|
||||
mov ax, 0xFFFF
|
||||
mov dx, ax
|
||||
mov sp, 3000h - 6
|
||||
ret
|
||||
|
||||
callback:
|
||||
; in: ax = function number; only functions 1 and 2 are defined for now
|
||||
; save caller's stack
|
||||
mov dx, ss
|
||||
mov cx, sp
|
||||
; set our stack (required because we need ss=0)
|
||||
xor si, si
|
||||
mov ss, si
|
||||
mov sp, 3000h
|
||||
mov bp, dat
|
||||
mov [bp + in_callback - dat], 1
|
||||
push dx
|
||||
push cx
|
||||
; set ds:si -> ASCIIZ name
|
||||
lea si, [di+6]
|
||||
; set cx = limit in sectors; 4Kb = 8 sectors
|
||||
movzx ecx, word [di+4]
|
||||
shl cx, 3
|
||||
; set es:bx = pointer to buffer
|
||||
les bx, [di]
|
||||
; call our function
|
||||
stc ; unsupported function
|
||||
dec ax
|
||||
jz callback_readfile
|
||||
dec ax
|
||||
jnz callback_ret
|
||||
call continue_load_file
|
||||
jmp callback_ret_succ
|
||||
callback_readfile:
|
||||
; function 1: read file
|
||||
; in: ds:di -> information structure
|
||||
; dw:dw address
|
||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
||||
; ASCIIZ name
|
||||
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
|
||||
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
|
||||
call [bp + load_file_ptr - dat]
|
||||
callback_ret_succ:
|
||||
clc
|
||||
callback_ret:
|
||||
; restore caller's stack
|
||||
pop cx
|
||||
pop ss
|
||||
mov sp, cx
|
||||
; return to caller
|
||||
retf
|
||||
|
||||
read_file_chunk.resident:
|
||||
; auxiliary label for read_file_chunk procedure
|
||||
mov di, bx
|
||||
lodsw
|
||||
read_file_chunk.resident.continue:
|
||||
mov dx, ax
|
||||
add dx, 0x1FF
|
||||
shr dx, 9
|
||||
cmp dx, cx
|
||||
jbe @f
|
||||
mov ax, cx
|
||||
shl ax, 9
|
||||
@@:
|
||||
xchg ax, cx
|
||||
rep movsb
|
||||
xchg ax, cx
|
||||
clc ; no disk error if no disk requests
|
||||
mov word [bp + num_sectors - dat], ax
|
||||
ret
|
||||
|
||||
read_file_chunk:
|
||||
; in: ds:si -> file chunk
|
||||
; in: es:bx -> buffer for output
|
||||
; in: ecx = maximum number of sectors to read (high word must be 0)
|
||||
; out: CF=1 <=> disk read error
|
||||
lodsb
|
||||
mov [bp + cur_chunk_resident - dat], al
|
||||
test al, al
|
||||
jz .resident
|
||||
; normal case: load (non-resident) attribute from disk
|
||||
.read_block:
|
||||
lodsd
|
||||
xchg eax, edx
|
||||
test edx, edx
|
||||
jz .ret
|
||||
lodsd
|
||||
; eax = start cluster, edx = number of clusters, cx = limit in sectors
|
||||
imul eax, [bp + sect_per_clust - dat]
|
||||
add eax, [bp + data_start - dat]
|
||||
mov [bp + cur_cluster - dat], eax
|
||||
imul edx, [bp + sect_per_clust - dat]
|
||||
mov [bp + num_sectors - dat], edx
|
||||
and [bp + cur_delta - dat], 0
|
||||
.nonresident.continue:
|
||||
cmp edx, ecx
|
||||
jb @f
|
||||
mov edx, ecx
|
||||
@@:
|
||||
test dx, dx
|
||||
jz .read_block
|
||||
add [bp + cur_delta - dat], edx
|
||||
sub [bp + num_sectors - dat], edx
|
||||
sub ecx, edx
|
||||
push cx
|
||||
mov cx, dx
|
||||
call read
|
||||
pop cx
|
||||
jc .ret
|
||||
test cx, cx
|
||||
jnz .read_block
|
||||
.ret:
|
||||
ret
|
||||
|
||||
cache_lookup:
|
||||
; in: eax = value to look, si = pointer to cache structure
|
||||
; out: di->cache entry; CF=1 <=> the value was not found
|
||||
push ds bx
|
||||
push ss
|
||||
pop ds
|
||||
mov di, [si+2]
|
||||
.look:
|
||||
cmp di, si
|
||||
jz .not_in_cache
|
||||
cmp eax, [di+4]
|
||||
jz .in_cache
|
||||
mov di, [di+2]
|
||||
jmp .look
|
||||
.not_in_cache:
|
||||
; cache miss
|
||||
; cache is full?
|
||||
mov di, [si+4]
|
||||
cmp di, [si+6]
|
||||
jnz .cache_not_full
|
||||
; yes, delete the oldest entry
|
||||
mov di, [si]
|
||||
mov bx, [di]
|
||||
mov [si], bx
|
||||
push word [di+2]
|
||||
pop word [bx+2]
|
||||
jmp .cache_append
|
||||
.cache_not_full:
|
||||
; no, allocate new item
|
||||
add word [si+4], 8
|
||||
.cache_append:
|
||||
mov [di+4], eax
|
||||
stc
|
||||
jmp @f
|
||||
.in_cache:
|
||||
; delete this sector from the list
|
||||
push si
|
||||
mov si, [di]
|
||||
mov bx, [di+2]
|
||||
mov [si+2], bx
|
||||
mov [bx], si
|
||||
pop si
|
||||
@@:
|
||||
; add new sector to the end of list
|
||||
mov bx, di
|
||||
xchg bx, [si+2]
|
||||
push word [bx]
|
||||
pop word [di]
|
||||
mov [bx], di
|
||||
mov [di+2], bx
|
||||
pop bx ds
|
||||
ret
|
||||
|
||||
include 'fat.inc'
|
||||
include 'ntfs.inc'
|
||||
|
||||
total_kaput db 13,10,'Fatal error: cannot load the secondary loader',0
|
||||
error_too_big db 'file is too big',0
|
||||
nodata_string db '$DATA '
|
||||
error_not_found db 'not found',0
|
||||
noindex_string db '$INDEX_ROOT not found',0
|
||||
badname_msg db 'bad name for FAT',0
|
||||
invalid_volume_msg db 'invalid volume',0
|
||||
mft_string db '$MFT',0
|
||||
fragmented_string db 'too fragmented file',0
|
||||
invalid_read_request_string db 'cannot read attribute',0
|
||||
|
||||
kernel_name db 'kernel.mnt',0
|
||||
|
||||
align 4
|
||||
dat:
|
||||
|
||||
extended_part_start dd 0 ; start sector for main extended partition
|
||||
extended_part_cur dd ? ; start sector for current extended child
|
||||
extended_parent dd 0 ; start sector for current extended parent
|
||||
partition_start dd 0 ; start sector for current logical disk
|
||||
cur_partition_ofs dw ? ; offset in MBR data for current partition
|
||||
sect_per_clust dd 0
|
||||
; change this variable if you want to boot from other physical drive
|
||||
boot_drive db 80h
|
||||
in_callback db 0
|
||||
|
||||
; uninitialized data
|
||||
use_lba db ?
|
||||
cur_chunk_resident db ?
|
||||
align 2
|
||||
heads dw ?
|
||||
sectors dw ?
|
||||
cache1head rw 2
|
||||
cache1end dw ?
|
||||
cache1limit dw ?
|
||||
data_start dd ?
|
||||
cachelimit dw ?
|
||||
load_file_ptr dw ?
|
||||
cur_obj dw ?
|
||||
missing_slash dw ?
|
||||
root_clus dd ?
|
||||
root_start dd ?
|
||||
get_next_cluster_ptr dw ?
|
||||
frs_size dw ?
|
||||
freeattr dw ?
|
||||
index_root dw ?
|
||||
index_alloc dw ?
|
||||
cur_index_seg dw ?
|
||||
cur_index_cache dw ?
|
||||
filesize dd ?
|
||||
filesize_sectors dd ?
|
||||
cur_cluster dd ?
|
||||
cur_delta dd ?
|
||||
num_sectors dd ?
|
||||
sectors_read dd ?
|
||||
cur_chunk_ptr dw ?
|
||||
|
||||
rootcache_size dw ? ; must be immediately before foldcache_clus
|
||||
if $-dat >= 0x80
|
||||
warning: unoptimal data displacement!
|
||||
end if
|
||||
foldcache_clus rd 7
|
||||
foldcache_mark rw 7
|
||||
foldcache_size rw 7
|
||||
fat_filename rb 11
|
||||
|
||||
if $ > 2000h
|
||||
error: file is too big
|
||||
end if
|
||||
|
||||
; for NT/2k/XP, file must be 16 sectors = 0x2000 bytes long
|
||||
repeat 0x2600 - $
|
||||
db 2 ; any data can be here; 2 is another nice face in ASCII :)
|
||||
end repeat
|
391
kernel/branches/kolibri-cfg/bootloader/after_win/kordldr.win.txt
Normal file
391
kernel/branches/kolibri-cfg/bootloader/after_win/kordldr.win.txt
Normal file
@ -0,0 +1,391 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
Нет повести печальнее на свете,
|
||||
Чем повесть о заклинившем Reset'е...
|
||||
|
||||
Загрузчик для FAT- и NTFS-томов для случаев, когда основной бутсектор загружает
|
||||
Windows, для носителей с размером сектора 512 байт.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Требования для работы:
|
||||
1) Все используемые файлы должны быть читабельны.
|
||||
2) Минимальный процессор - 80386.
|
||||
3) В системе должно быть как минимум 592K свободной базовой памяти.
|
||||
4) Пути к используемым файлам не должны содержать символических ссылок NTFS
|
||||
(жёсткие ссылки допускаются).
|
||||
5) Используемые файлы не должны быть сжатыми или разреженными файлами
|
||||
(актуально для NTFS, для FAT выполнено автоматически).
|
||||
|
||||
=====================================================================
|
||||
|
||||
Документация в тему (ссылки проверялись на валидность 08.08.2008):
|
||||
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
||||
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
|
||||
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip
|
||||
спецификация NTFS: file://C:/windows/system32/drivers/ntfs.sys
|
||||
и file://C:/ntldr либо file://C:/bootmgr
|
||||
неофициальное описание NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543
|
||||
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
|
||||
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
|
||||
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
|
||||
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
|
||||
официальное описание bcdedit для Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx
|
||||
официальное описание работы с базой данных загрузчика Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx
|
||||
формат таблицы разделов жёсткого диска: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx
|
||||
|
||||
=====================================================================
|
||||
|
||||
Схема используемой памяти:
|
||||
600-2000 код загрузчика (и данные)
|
||||
2000-3000 стек
|
||||
3000-3200 сектор MBR
|
||||
3200-3400 бутсектор логического диска
|
||||
3400-3C00 информация о кэше для таблиц FAT16/FAT32:
|
||||
для FAT16 - массив на 0x100 байт, каждый байт равен
|
||||
0 или 1 в зависимости от того, загружен ли
|
||||
соответствующий сектор таблицы FAT16;
|
||||
для FAT32 - 100h входов по 8 байт: 4 байта
|
||||
(две ссылки - вперёд и назад) для организации L2-списка
|
||||
всех прочитанных секторов в порядке возрастания
|
||||
последнего времени использования + 4 байта для номера
|
||||
сектора; при переполнении кэша выкидывается элемент из
|
||||
головы списка, то есть тот, к которому дольше всех
|
||||
не было обращений
|
||||
3400-3440 информация о кэше для файловых записей NTFS в
|
||||
таком же формате, как и кэш для FAT32, но на 8 входов
|
||||
3480-34C0 заголовки для кэшей записей индекса NTFS
|
||||
3500-3D00 информация о кэшах записей индекса NTFS: с каждой
|
||||
файловой записью связан свой кэш для
|
||||
соответствующего индекса
|
||||
4000-8000 место для информации об атрибутах для NTFS
|
||||
60000-80000 таблица FAT12 / место под таблицу FAT16 /
|
||||
кэш для таблицы FAT32 / кэш для структур NTFS
|
||||
80000-90000 текущий рассматриваемый кластер
|
||||
90000-92000 FAT: кэш для корневой папки
|
||||
92000-... FAT: кэш для некорневых папок (каждой папке отводится
|
||||
2000h байт = 100h входов, одновременно в кэше
|
||||
может находиться не более 7 папок;
|
||||
точный размер определяется размером доступной
|
||||
физической памяти - как правило, непосредственно
|
||||
перед A0000 размещается EBDA, Extended BIOS Data Area)
|
||||
|
||||
=====================================================================
|
||||
|
||||
Основной процесс загрузки.
|
||||
0a. Загрузка из-под DOS и Win9x: установка kordldr.win осуществляется
|
||||
размещением команды install=c:\kordldr.win в первой строке config.sys;
|
||||
при этом основной загрузчик системы загружает kordldr.win как обычный
|
||||
com-файл, в какой-то сегмент по смещению 100h и передаёт управление
|
||||
в начало кода (xxxx:0100).
|
||||
0б. Загрузка из-под WinNT/2000/XP: установка kordldr.win осуществляется
|
||||
добавлением строки наподобие c:\kordldr.win="KordOS" в секцию
|
||||
[operating systems] файла boot.ini; если загружаемый файл имеет размер
|
||||
не менее 8 Кб (0x2000 байт) и по смещению 3 содержит сигнатуру 'NTFS'
|
||||
(в случае kordldr.win так и есть), то основной загрузчик каждой из
|
||||
этих систем загружает kordldr.win по адресу 0D00:0000 и передаёт
|
||||
управление на адрес 0D00:0256.
|
||||
0в. Загрузка из-под Vista: установка kordldr.win осуществляется манипуляциями
|
||||
с базой данных основного загрузчика через bcdedit и подробно описана в
|
||||
инструкции к kordldr.win; основной загрузчик загружает целиком
|
||||
kordldr.win по адресу 0000:7C00 и передаёт управление в начало кода.
|
||||
1. При загрузке из-под DOS/9x основной загрузчик не ожидает, что загруженная
|
||||
им программа окажется в свою очередь загрузчиком, и в этом случае
|
||||
kordldr.win оказывается в условиях, когда основной загрузчик уже
|
||||
установил какое-то окружение, в частности, перехватил некоторые
|
||||
прерывания. Поэтому перед остальными действиями загрузчик должен
|
||||
восстановить систему в начальное состояние. (При загрузке под
|
||||
NT-линейкой такой проблемы не возникает, поскольку там основной
|
||||
загрузчик ничего в системе не трогает.) Поэтому перед собственно
|
||||
инициализацией KordOS при работе из-под DOS/9x производятся
|
||||
дополнительные действия. Первым делом kordldr проверяет, какой из
|
||||
случаев 0а и 0в имеет место (случай 0б отличается тем, что передаёт
|
||||
управление не на начало кода): определяет значение ip (команда call
|
||||
помещает в стек адрес следующей после call инструкции, команда pop si
|
||||
выталкивает его в регистр si), и если оно равно 100h, то kordldr
|
||||
загружен как com-файл из-под DOS/9x. Тогда он спрашивает подтверждения
|
||||
у пользователя (поскольку в этой схеме kordldr загружается всегда,
|
||||
он должен оставить возможность продолжить загрузку DOS/9x). Если
|
||||
пользователь хочет продолжить обычную загрузку, kordldr завершается.
|
||||
Иначе используется тот факт, что при выдаче прерывания перезагрузки
|
||||
int 19h система предварительно снимает все свои перехваты BIOSовских
|
||||
прерываний, а потом в свою очередь выдаёт int 19h уже BIOSу. Так что
|
||||
kordldr устанавливает свой обработчик трассировочного прерывания,
|
||||
устанавливает флаг трассировки и передаёт управление DOSовскому
|
||||
обработчику. Обработчик трассировочного прерывания ничего не делает
|
||||
до тех пор, пока следующей инструкцией не оказывается int 19h, а
|
||||
в этот момент отбирает управление и продолжает загрузку KordOS.
|
||||
При этом BIOSовские обработчики восстановлены за исключением,
|
||||
быть может, прерывания таймера int 8, которое, возможно, восстановлено
|
||||
до команды jmp far на оригинальный обработчик. В последнем случае его
|
||||
нужно восстановить явно.
|
||||
2. Загрузчик перемещает свой код на адрес 0000:0600.
|
||||
3. (метка real_entry) Загрузчик устанавливает сегментные регистры ds = es = 0,
|
||||
настраивает стек ss:sp = 0000:3000 и устанавливает bp так, чтобы
|
||||
все данные можно было адресовать через [bp+N] с однобайтовым N
|
||||
(в дальнейшем они так и будут адресоваться для освобождения ds и
|
||||
экономии на размере кода). Разрешает прерывания на случай, если
|
||||
они были запрещены. Выдаёт сообщение о начале загрузки, начинающееся
|
||||
с весёлой рожицы (символ с ASCII-кодом 2).
|
||||
4. Определяет характеристики жёсткого диска, указанного в качестве
|
||||
загрузочного: проверяет поддержку LBA (функция 41h прерывания 13h),
|
||||
если LBA не поддерживается, то определяет геометрию - число дорожек
|
||||
и число секторов на дорожке (функция 8 прерывания 13h), эти параметры
|
||||
нужны функции чтения с диска.
|
||||
5. (метка new_partition_ex) Устраивает цикл по разделам жёсткого диска.
|
||||
Цель цикла - для каждого логического диска попытаться загрузиться с
|
||||
него (действия по загрузке с конкретного логического диска начинаются
|
||||
с метки not_extended), при ошибке загрузки управление передаётся
|
||||
назад этому циклу (метка next_partition), и поиск подходящего раздела
|
||||
продолжается. На выходе заполняется одна переменная partition_start,
|
||||
имеющая смысл начала текущего рассматриваемого логического диска,
|
||||
но по ходу дела из-за приколов таблиц разделов используются ещё четыре
|
||||
переменных. cur_partition_ofs - фактически счётчик цикла, формально
|
||||
указатель на текущий вход в текущей загрузочной записи. Сама
|
||||
загрузочная запись считывается в память начиная с адреса 3000h.
|
||||
Три оставшихся нужны для правильной работы с расширенными разделами.
|
||||
В каждой загрузочной записи помещается не более 4 записей о разделах.
|
||||
Поэтому главной загрузочной записи, размещающейся в первом физическом
|
||||
секторе диска, может не хватить, и обычно создаётся так называемый
|
||||
расширенный раздел с расширенными загрузочными записями, формат
|
||||
которых почти идентичен главной. Расширенный раздел может быть только
|
||||
один, но в нём может быть много логических дисков и расширенных
|
||||
загрузочных записей. Расширенные загрузочные записи организованы
|
||||
в односвязный список, в каждой такой записи первый вход указывает
|
||||
на соответствующий логический диск, а второй - на следующую расширенную
|
||||
загрузочную запись.
|
||||
При этом в главной загрузочной записи все адреса разделов являются
|
||||
абсолютными номерами секторов. В расширенных же записях адреса разделов
|
||||
относительны, причём с разными базами: адрес логического диска
|
||||
указывается относительно расширенной записи, а адрес следующей
|
||||
расширенной записи указывается относительно начала расширенного
|
||||
раздела. Такой разнобой выглядит несколько странно, но имеет место
|
||||
быть. Три оставшихся переменных содержат: extended_part_start -
|
||||
начало расширенного раздела; extended_parent - текущая рассматриваемая
|
||||
расширенная загрузочная запись; extended_part_cur - следующая
|
||||
загрузочная запись для рассмотрения.
|
||||
Цикл выглядит так: просматриваются все разделы, указанные в текущей
|
||||
(главной или расширенной) загрузочной записи; для нормальных разделов
|
||||
(они же логические диски) происходит переход на not_extended, где
|
||||
устанавливается partition_start и начинается собственно загрузка
|
||||
(последующие шаги); при встрече с разделом, тип которого указывает
|
||||
на расширенность (5 или 0xF), код запоминает начало этого раздела
|
||||
(в главной загрузочной записи такой тип означает расширенный раздел,
|
||||
в расширенной - только указатель на следующую расширенную запись,
|
||||
в обоих случаях он может встретиться только один раз в данной записи);
|
||||
когда код доходит до конца списка, все нормальные разделы, описываемые
|
||||
в этой записи, уже просмотрены, так что код с чистой совестью переходит
|
||||
к следующей расширенной записи. Если он её не встретил, значит, уже
|
||||
все логические разделы были подвергнуты попыткам загрузиться, и все
|
||||
безрезультатно, так что выводится ругательство и работа останавливается
|
||||
(jmp $).
|
||||
Может возникнуть вопрос, зачем нужна такая сложная схема и почему
|
||||
нельзя узнать нужный логический диск заранее или хотя бы ограничиться
|
||||
первым попавшимся логическим диском, не крутя цикл. Так вот, вариант
|
||||
с предварительным определением нужного раздела в данном случае не
|
||||
используется, поскольку повлёк бы за собой нетривиальные лишние
|
||||
действия по установке (в текущем виде установку можно провести вручную,
|
||||
и она сводится к указанию системному загрузчику на существование
|
||||
kordldr); кстати, в альтернативной версии загрузки после
|
||||
Windows-загрузчика, когда установка осуществляется не вручную, а
|
||||
специальной программой под Windows, используется модифицированная
|
||||
версия, в которой как раз начальный физический сектор нужного раздела
|
||||
прописывается установщиком. Сам kordldr не может установить, с какого
|
||||
раздела его загрузил Windows-загрузчик (и вообще под NT/2000/XP обязан
|
||||
быть файлом на диске C:\). Вариант с первым попавшимся логическим
|
||||
диском был реализован в первой версии загрузчика, но по ходу дела
|
||||
обнаружилось, что таки нужно крутить цикл: во-вторых, может быть
|
||||
приятным, что сама система может стоять вовсе не на системном C:\, а и
|
||||
на других дисках; во-первых, диск C: может и не быть первым логическим
|
||||
разделом - Vista любит создавать скрытый первичный раздел перед
|
||||
системным, и тогда диск C: становится вторым логическим.
|
||||
6. Извещает пользователя о том, что происходит попытка загрузки с очередного
|
||||
логического диска.
|
||||
7. Читает первый сектор логического диска и определяет файловую систему.
|
||||
И в FAT, и в NTFS поле со смещением +11 содержит число байт в секторе
|
||||
и должно совпадать с характеристикой физического носителя, то есть
|
||||
200h байт. И в FAT, и в NTFS поле со смещением +13 содержит число
|
||||
секторов в кластере и должно быть степенью двойки.
|
||||
Критерий NTFS: поле со смещением +3 содержит строку NTFS и поле со
|
||||
смещением +16 нулевое (в FAT оно содержит число таблиц FAT и обязано
|
||||
быть ненулевым).
|
||||
Критерий FAT: загрузчик вычисляет число кластеров, определяет
|
||||
предположительный тип (FAT12/FAT16/FAT32) и проверяет байт по смещению
|
||||
+38 для FAT12/16, +66 для FAT32 (он должен быть равен 0x29).
|
||||
После определения типа файловой системы извещает пользователя об
|
||||
определённом типе. Если файловая система не распознана, выдаёт
|
||||
соответствующее сообщение и переходит к следующему логическому диску.
|
||||
8a. Для FAT12-томов: засовывает в стек идентификатор файловой системы -
|
||||
константу '12'; устанавливает указатель на функцию получения следующего
|
||||
в цепочке FAT кластера на FAT12-обработчик; считывает в память всю
|
||||
таблицу FAT12 (она не превосходит 0x1800 байт = 6 Кб), при ошибке
|
||||
чтения пытается использовать другие копии FAT.
|
||||
8б. Для FAT16-томов: засовывает в стек идентификатор файловой системы -
|
||||
константу '16'; устанавливает указатель на функцию получения следующего
|
||||
в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию
|
||||
о кэше секторов FAT (массив байт с возможными значениями 0 и 1,
|
||||
означающими, был ли уже загружен соответствующий сектор - всего в
|
||||
таблице FAT16 не более 0x100 секторов) - ни один сектор ещё не
|
||||
загружен, все байты нулевые.
|
||||
8в. Для FAT32-томов: засовывает в стек идентификатор файловой системы -
|
||||
константу '32'; устанавливает указатель на функцию получения следующего
|
||||
в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию
|
||||
о кэше секторов FAT (формат информации описан выше, в распределении
|
||||
используемой загрузчиком памяти) - ни один сектор ещё не загружен.
|
||||
8г. Общее для FAT-томов: определяет значения служебных переменных
|
||||
root_start (первый сектор корневого каталога в FAT12/16, игнорируется
|
||||
при обработке FAT32-томов), data_start (начало данных с поправкой,
|
||||
вводимой для того, чтобы кластер N начинался с сектора
|
||||
N*sectors_per_cluster+data_start), root_clus (первый кластер корневого
|
||||
каталога в FAT32, 0 в FAT12/16); устанавливает указатель на функцию
|
||||
загрузки файла на FAT-обработчик.
|
||||
8д. Для NTFS-томов: засовывает в стек идентификатор файловой системы -
|
||||
константу 'nt'; определяет значение служебной переменной frs_size
|
||||
(размер в байтах файловой записи, File Record Segment), для полной
|
||||
корректности проверяет, что это значение (равное 0x400 байт на всех
|
||||
реальных NTFS-томах - единственный способ изменить его заключается
|
||||
в пересоздании всех системных структур вручную) не превосходит 0x1000
|
||||
и кратно размеру сектора 0x200 байт; инициализирует кэш файловых
|
||||
записей - ничего ещё не загружено; считывает первый кластер $MFT
|
||||
и загружает информацию о расположении на диске всей таблицы $MFT
|
||||
(атрибут 0x80, $Data); устанавливает указатель на функцию загрузки
|
||||
файла на NTFS-обработчик.
|
||||
9. (метка load_secondary) Вызывает функцию загрузки файла для файла вторичного
|
||||
загрузчика. При обнаружении ошибки переходит на обработчик ошибок с
|
||||
соответствующим сообщением.
|
||||
10. Устанавливает регистры для вторичного загрузчика: al='h' (жёсткий диск),
|
||||
ah=номер диска (для готового бинарника - 0 (BIOS-идентификатор 80h),
|
||||
может быть изменён путём модификации константы в исходнике или
|
||||
специальным установщиком), bx=идентификатор файловой системы (берётся
|
||||
из стека, куда ранее был засунут на шаге 8), ds:si=указатель на
|
||||
callback-функцию.
|
||||
11. Передаёт управление вторичному загрузчику дальним переходом на 1000:0000.
|
||||
|
||||
Функция обратного вызова для вторичного загрузчика:
|
||||
предоставляет возможность чтения файла.
|
||||
Вход и выход описаны в спецификации на загрузчик.
|
||||
Чтение файла:
|
||||
1. Сохраняет стек вызывающего кода и устанавливает свой стек:
|
||||
ss:sp = 0:3000, bp=dat: пара ss:bp при работе с остальным
|
||||
кодом должна указывать на 0:dat.
|
||||
2. Разбирает переданные параметры и вызывает процедуру загрузки файла.
|
||||
3. Восстанавливает стек вызывающего кода и возвращает управление.
|
||||
|
||||
Вспомогательные процедуры.
|
||||
Процедура чтения секторов (read):
|
||||
на входе должно быть установлено:
|
||||
ss:bp = 0:dat
|
||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
||||
eax = стартовый сектор (относительно начала логического диска)
|
||||
cx = число секторов (должно быть больше нуля)
|
||||
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные,
|
||||
флаг CF установлен, если возникла ошибка чтения
|
||||
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на
|
||||
устройстве, прибавляя номер первого сектора логического диска,
|
||||
найденный при переборе дисков.
|
||||
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации
|
||||
CHS-версия: все читаемые секторы были на одной дорожке.
|
||||
LBA-версия: число читаемых секторов не превосходило 7Fh (требование
|
||||
спецификации EDD BIOS).
|
||||
CHS-версия:
|
||||
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как
|
||||
единица плюс остаток от деления абсолютного номера на число секторов
|
||||
на дорожке; дорожка рассчитывается как остаток от деления частного,
|
||||
полученного на предыдущем шаге, на число дорожек, а цилиндр - как
|
||||
частное от этого же деления. Если число секторов для чтения больше,
|
||||
чем число секторов до конца дорожки, уменьшает число секторов для
|
||||
чтения.
|
||||
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов,
|
||||
dh=головка, (младшие 6 бит cl)=сектор,
|
||||
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер).
|
||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска
|
||||
и повторяет попытку чтения, всего делается не более трёх попыток
|
||||
(несколько попыток нужно в случае дискеты для гарантии того, что
|
||||
мотор раскрутился). Если все три раза происходит ошибка чтения,
|
||||
переходит на код обработки ошибок с сообщением "Read error".
|
||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
||||
работу, иначе возвращается на шаг 3.
|
||||
LBA-версия:
|
||||
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
|
||||
итерации) до 7Fh.
|
||||
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
|
||||
push, причём в обратном порядке: стек - структура LIFO, и данные в
|
||||
стеке хранятся в обратном порядке по отношению к тому, как их туда
|
||||
клали).
|
||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки
|
||||
ошибок с сообщением "Read error". Очищает стек от пакета,
|
||||
сформированного на предыдущем шаге.
|
||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
||||
работу, иначе возвращается на шаг 3.
|
||||
|
||||
Процедура обработки ошибок (find_error_si и find_error_sp):
|
||||
на входе: указатель на сообщение об ошибке в si либо на верхушке стека
|
||||
0. Если вызывается find_error_si, она помещает переданный указатель в стек.
|
||||
1. Если ошибка произошла в процессе работы callback-функции, то
|
||||
(метка error_in_callback) обработчик просто возвращает управление
|
||||
вызвавшему коду, рапортуя о ненайденном файле.
|
||||
2. Если же ошибка произошла до передачи управления вторичному загрузчику,
|
||||
обработчик выводит сообщение типа "Error: <текущий объект>: <ошибка>"
|
||||
и (восстановив стек) переходит к следующему логическому диску.
|
||||
|
||||
Процедура чтения файла/атрибута по известному размещению на диске
|
||||
(read_file_chunk):
|
||||
на входе должно быть установлено:
|
||||
ds:si = указатель на информацию о размещении
|
||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
||||
ecx = лимит числа секторов для чтения, старшее слово должно быть 0
|
||||
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные,
|
||||
флаг CF установлен, если возникла ошибка чтения
|
||||
1. Определяет, является ли атрибут резидентным (возможно только в NTFS
|
||||
и означает, что данные файла/атрибута уже были целиком прочитаны при
|
||||
обработке информации о файле) или нерезидентным (означает, что данные
|
||||
хранятся где-то на диске, и имеется информация о том, где именно).
|
||||
2. Для резидентных атрибутов (метка read_file_chunk.resident) просто копирует
|
||||
данные по месту назначения (с учётом указанного лимита).
|
||||
3. Для нерезидентных атрибутов информация состоит из пар <размер очередного
|
||||
фрагмента файла в кластерах, стартовый кластер фрагмента>; процедура
|
||||
читает фрагменты, пока файл не закончится или пока не будет достигнут
|
||||
указанный лимит.
|
||||
|
||||
Процедура просмотра кэша (cache_lookup):
|
||||
на входе должно быть установлено:
|
||||
eax = искомое значение
|
||||
ss:si = указатель на структуру-заголовок кэша
|
||||
на выходе: ss:di = указатель на вход в кэше; флаг CF установлен, если значение
|
||||
было только что добавлено, и сброшен, если оно уже было в кэше.
|
||||
1. Просматривает кэш в поисках указанного значения. Если значение найдено
|
||||
(при этом флаг CF оказывается сброшенным), переходит к шагу 4.
|
||||
2. Если кэш уже заполнен, удаляет из кэша самый старый вход (он находится в
|
||||
голове двусвязного списка), иначе добавляет к кэшу ещё один вход.
|
||||
3. Устанавливает в полученном входе указанное значение. Устанавливает флаг
|
||||
CF, последующие шаги не меняют состояния флагов. Переходит к шагу 5.
|
||||
4. Удаляет вход из списка.
|
||||
5. Добавляет сектор в конец списка (самый новый вход).
|
587
kernel/branches/kolibri-cfg/bootloader/after_win/ntfs.inc
Normal file
587
kernel/branches/kolibri-cfg/bootloader/after_win/ntfs.inc
Normal file
@ -0,0 +1,587 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
restore_usa:
|
||||
; Update Sequence Array restore
|
||||
; in: ds:bx -> USA-protected structure
|
||||
push bx
|
||||
lea di, [bx+1feh]
|
||||
mov cx, [bx+6]
|
||||
add bx, [bx+4]
|
||||
dec cx
|
||||
@@:
|
||||
mov ax, [bx+2]
|
||||
mov [di], ax
|
||||
inc bx
|
||||
inc bx
|
||||
add di, 200h
|
||||
loop @b
|
||||
pop bx
|
||||
ret
|
||||
|
||||
find_attr:
|
||||
; in: ds:di->file record, ax=attribute
|
||||
; out: ds:di->attribute or di=0 if not found
|
||||
add di, [di+14h]
|
||||
.1:
|
||||
; attributes' codes are formally dwords, but all of them fit in word
|
||||
cmp word [di], -1
|
||||
jz .notfound
|
||||
cmp word [di], ax
|
||||
jnz .continue
|
||||
; for $DATA attribute, scan only unnamed
|
||||
cmp ax, 80h
|
||||
jnz .found
|
||||
cmp byte [di+9], 0
|
||||
jz .found
|
||||
.continue:
|
||||
add di, [di+4]
|
||||
jmp .1
|
||||
.notfound:
|
||||
xor di, di
|
||||
.found:
|
||||
ret
|
||||
|
||||
process_mcb_nonres:
|
||||
; in: ds:si->attribute, es:di->buffer
|
||||
; out: es:di->buffer end
|
||||
pushad
|
||||
pop di
|
||||
add si, [si+20h]
|
||||
xor ebx, ebx
|
||||
.loop:
|
||||
lodsb
|
||||
test al, al
|
||||
jz .done
|
||||
push invalid_read_request_string
|
||||
movzx cx, al
|
||||
shr cx, 4
|
||||
jz find_error_sp
|
||||
xchg ax, dx
|
||||
and dx, 0Fh
|
||||
jz find_error_sp
|
||||
add si, cx
|
||||
add si, dx
|
||||
pop ax
|
||||
push si
|
||||
dec si
|
||||
movsx eax, byte [si]
|
||||
dec cx
|
||||
jz .l1e
|
||||
.l1:
|
||||
dec si
|
||||
shl eax, 8
|
||||
mov al, [si]
|
||||
loop .l1
|
||||
.l1e:
|
||||
xchg ebp, eax
|
||||
dec si
|
||||
movsx eax, byte [si]
|
||||
mov cx, dx
|
||||
dec cx
|
||||
jz .l2e
|
||||
.l2:
|
||||
dec si
|
||||
shl eax, 8
|
||||
mov al, byte [si]
|
||||
loop .l2
|
||||
.l2e:
|
||||
pop si
|
||||
add ebx, ebp
|
||||
; eax=length, ebx=disk block
|
||||
stosd
|
||||
mov eax, ebx
|
||||
stosd
|
||||
cmp di, 0x8000 - 12
|
||||
jbe .loop
|
||||
..attr_overflow:
|
||||
mov si, fragmented_string
|
||||
jmp find_error_si
|
||||
.done:
|
||||
xor ax, ax
|
||||
stosw
|
||||
stosw
|
||||
push di
|
||||
popad
|
||||
ret
|
||||
|
||||
load_attr:
|
||||
; in: ax=attribute, ds:bx->base record
|
||||
; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated,
|
||||
; edx=size of attribute in bytes
|
||||
; out: if not found: CF=1
|
||||
mov di, [bp + freeattr - dat]
|
||||
push ss
|
||||
pop es
|
||||
mov byte [es:di], 1
|
||||
inc di
|
||||
cmp di, 0x8000 - 12
|
||||
ja ..attr_overflow
|
||||
or edx, -1 ; file size is not known yet
|
||||
; scan for attribute
|
||||
push di
|
||||
mov di, bx
|
||||
add di, [di+14h]
|
||||
@@:
|
||||
call find_attr.1
|
||||
test di, di
|
||||
jz .notfound1
|
||||
cmp byte [di+8], 0
|
||||
jnz .nonresident
|
||||
mov si, di
|
||||
pop di
|
||||
push ds
|
||||
jmp .resident
|
||||
.aux_resident:
|
||||
mov ax, ds
|
||||
mov si, di
|
||||
pop di ds bx ds edx
|
||||
push ss
|
||||
pop es
|
||||
push ds
|
||||
mov ds, ax
|
||||
; resident attribute
|
||||
.resident:
|
||||
dec di
|
||||
mov al, 0
|
||||
stosb
|
||||
mov ax, [si+10h]
|
||||
stosw
|
||||
push di
|
||||
add di, ax
|
||||
cmp di, 0x8000 - 12
|
||||
pop di
|
||||
ja ..attr_overflow
|
||||
movzx edx, ax ; length of attribute
|
||||
xchg ax, cx
|
||||
add si, [si+14h]
|
||||
rep movsb
|
||||
mov [bp + freeattr - dat], di
|
||||
pop ds
|
||||
ret
|
||||
.nonresident:
|
||||
; nonresident attribute
|
||||
cmp dword [di+10h], 0
|
||||
jnz @b
|
||||
; read start of data
|
||||
mov si, di
|
||||
mov edx, [di+30h] ; size of attribute
|
||||
pop di
|
||||
call process_mcb_nonres
|
||||
sub di, 4
|
||||
push di
|
||||
.notfound1:
|
||||
pop di
|
||||
push edx
|
||||
; $ATTRIBUTE_LIST is always in base file record
|
||||
cmp ax, 20h
|
||||
jz .nofragmented
|
||||
; try to load $ATTRIBUTE_LIST = 20h
|
||||
push ax
|
||||
mov ax, 20h
|
||||
push [bp + freeattr - dat]
|
||||
mov [bp + freeattr - dat], di
|
||||
push di
|
||||
call load_attr
|
||||
pop di
|
||||
pop [bp + freeattr - dat]
|
||||
pop ax
|
||||
jc .nofragmented
|
||||
push ds bx
|
||||
pusha
|
||||
mov si, di
|
||||
push ss
|
||||
pop ds
|
||||
push 0x8100
|
||||
pop es
|
||||
xor ecx, ecx
|
||||
mov cl, 0x78
|
||||
xor bx, bx
|
||||
push es
|
||||
call read_file_chunk
|
||||
pop ds
|
||||
jc ..found_disk_error
|
||||
test cx, cx
|
||||
jz ..attr_overflow
|
||||
popa
|
||||
push ss
|
||||
pop es
|
||||
xor bx, bx
|
||||
.1:
|
||||
cmp [bx], ax
|
||||
jnz .continue1
|
||||
; only unnamed $DATA attributes!
|
||||
cmp ax, 80h
|
||||
jnz @f
|
||||
cmp byte [bx+6], 0
|
||||
jnz .continue1
|
||||
@@:
|
||||
cmp dword [bx+10h], 0
|
||||
jz .continue1
|
||||
cmp dword [bx+8], 0
|
||||
jnz @f
|
||||
dec di
|
||||
cmp di, [bp + freeattr - dat]
|
||||
lea di, [di+1]
|
||||
jnz .continue1
|
||||
@@:
|
||||
push ds di
|
||||
push ax
|
||||
mov eax, [bx+10h]
|
||||
mov ecx, [bx+8]
|
||||
call read_file_record
|
||||
pop ax
|
||||
mov di, [14h]
|
||||
.2:
|
||||
call find_attr.1
|
||||
cmp byte [di+8], 0
|
||||
jz .aux_resident
|
||||
cmp dword [di+10h], ecx
|
||||
jnz .2
|
||||
mov si, di
|
||||
mov di, sp
|
||||
cmp dword [ss:di+8], -1
|
||||
jnz @f
|
||||
push dword [si+30h] ; size of attribute
|
||||
pop dword [ss:di+8]
|
||||
@@:
|
||||
pop di
|
||||
call process_mcb_nonres
|
||||
sub di, 4
|
||||
pop ds
|
||||
.continue1:
|
||||
add bx, [bx+4]
|
||||
cmp bx, dx
|
||||
jb .1
|
||||
pop bx ds
|
||||
.nofragmented:
|
||||
pop edx
|
||||
dec di
|
||||
cmp di, [bp + freeattr - dat]
|
||||
jnz @f
|
||||
stc
|
||||
ret
|
||||
@@:
|
||||
inc di
|
||||
xor ax, ax
|
||||
stosw
|
||||
stosw
|
||||
mov [bp + freeattr - dat], di
|
||||
ret
|
||||
|
||||
read_file_record:
|
||||
; in: eax = index of record
|
||||
; out: ds:0 -> record
|
||||
; find place in cache
|
||||
push di
|
||||
push si
|
||||
mov si, cache1head
|
||||
call cache_lookup
|
||||
pop si
|
||||
pushf
|
||||
sub di, 3400h
|
||||
shl di, 10-3
|
||||
add di, 0x6000
|
||||
mov ds, di
|
||||
popf
|
||||
pop di
|
||||
jnc .noread
|
||||
; read file record <eax> to ds:0
|
||||
pushad
|
||||
push ds
|
||||
push es
|
||||
movzx ecx, [bp + frs_size - dat]
|
||||
shr cx, 9
|
||||
mul ecx
|
||||
push ds
|
||||
pop es
|
||||
push ss
|
||||
pop ds
|
||||
mov si, 0x4000
|
||||
xor bx, bx
|
||||
push [bp + cur_obj - dat]
|
||||
mov [bp + cur_obj - dat], mft_string
|
||||
push es
|
||||
call read_attr
|
||||
; initialize cache for $INDEX_ALLOCATION for this record
|
||||
pop si
|
||||
push si
|
||||
sub si, 0x6000
|
||||
mov ax, si
|
||||
shr si, 10-3
|
||||
shr ax, 2
|
||||
add si, 3480h
|
||||
add ax, 3500h
|
||||
mov [si], si
|
||||
mov [si+2], si
|
||||
mov [si+4], ax
|
||||
pop ds
|
||||
call restore_usa
|
||||
pop [bp + cur_obj - dat]
|
||||
pop es
|
||||
pop ds
|
||||
popad
|
||||
.noread:
|
||||
ret
|
||||
|
||||
read_attr:
|
||||
; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute
|
||||
push invalid_read_request_string
|
||||
cmp byte [si], 0
|
||||
jnz .nonresident
|
||||
cmp eax, 10000h shr 9
|
||||
jae find_error_sp
|
||||
shl ax, 9
|
||||
shl cx, 9
|
||||
cmp ax, [si+2]
|
||||
jae find_error_sp
|
||||
cmp cx, [si+2]
|
||||
ja find_error_sp
|
||||
add si, 3
|
||||
add si, ax
|
||||
mov di, bx
|
||||
rep movsb
|
||||
pop ax
|
||||
ret
|
||||
.nonresident:
|
||||
inc si
|
||||
.loop:
|
||||
mov edx, dword [si]
|
||||
add si, 8
|
||||
test edx, edx
|
||||
jz find_error_sp
|
||||
imul edx, [bp + sect_per_clust - dat]
|
||||
sub eax, edx
|
||||
jnc .loop
|
||||
add eax, edx
|
||||
sub edx, eax
|
||||
push cx
|
||||
cmp ecx, edx
|
||||
jb @f
|
||||
mov cx, dx
|
||||
@@:
|
||||
push bx
|
||||
mov ebx, [si-4]
|
||||
imul ebx, [bp + sect_per_clust - dat]
|
||||
add eax, ebx
|
||||
pop bx
|
||||
call read
|
||||
jc ..found_disk_error
|
||||
mov dx, cx
|
||||
pop cx
|
||||
xor eax, eax
|
||||
sub cx, dx
|
||||
jnz .loop
|
||||
pop ax
|
||||
ret
|
||||
|
||||
load_file_ntfs:
|
||||
; in: ss:bp = 0:dat
|
||||
; in: es:bx = address to load file
|
||||
; in: ds:si -> ASCIIZ name
|
||||
; in: cx = limit in sectors
|
||||
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found
|
||||
; out: dx:ax = file size (0xFFFFFFFF if file not found)
|
||||
push es bx cx
|
||||
mov eax, 5 ; root cluster
|
||||
mov [bp + cur_obj - dat], root_string
|
||||
.parse_dir_loop:
|
||||
push ds si
|
||||
call read_file_record
|
||||
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
|
||||
mov ax, [bp + freeattr - dat]
|
||||
mov [bp + index_root - dat], ax
|
||||
mov ax, 90h ; $INDEX_ROOT
|
||||
xor bx, bx
|
||||
call load_attr
|
||||
mov si, noindex_string
|
||||
jc find_error_si
|
||||
mov ax, [bp + freeattr - dat]
|
||||
mov [bp + index_alloc - dat], ax
|
||||
mov ax, 0A0h ; $INDEX_ALLOCATION
|
||||
call load_attr
|
||||
jnc @f
|
||||
mov [bp + index_alloc - dat], bx
|
||||
@@:
|
||||
push ds
|
||||
; search for entry
|
||||
mov si, [bp + index_root - dat]
|
||||
push ss
|
||||
pop ds
|
||||
push 0x8100
|
||||
pop es
|
||||
xor ecx, ecx
|
||||
mov cl, 0x78
|
||||
xor bx, bx
|
||||
push es
|
||||
call read_file_chunk
|
||||
pop ds
|
||||
jc ..found_disk_error
|
||||
test cx, cx
|
||||
jz ..attr_overflow
|
||||
mov si, invalid_read_request_string
|
||||
cmp word [bx+10], 0
|
||||
jnz find_error_si
|
||||
; calculate number of items in cache
|
||||
mov di, [bx+8] ; subnode_size
|
||||
mov ax, 0x4000
|
||||
sub ax, word [bp + frs_size - dat]
|
||||
cwd
|
||||
div di
|
||||
test ax, ax
|
||||
jz find_error_si
|
||||
mov si, invalid_volume_msg
|
||||
test di, 0x1FF
|
||||
jnz find_error_si
|
||||
pop cx
|
||||
mov [bp + cur_index_seg - dat], cx
|
||||
shl ax, 3
|
||||
sub cx, 6000h
|
||||
mov si, cx
|
||||
shr cx, 2
|
||||
shr si, 10-3
|
||||
add cx, ax
|
||||
add si, 3480h
|
||||
mov [bp + cur_index_cache - dat], si
|
||||
add cx, 3500h
|
||||
mov [ss:si+6], cx
|
||||
mov dx, di
|
||||
add bx, 10h
|
||||
.scan_record:
|
||||
add bx, [bx]
|
||||
.scan:
|
||||
test byte [bx+0Ch], 2
|
||||
jnz .look_child
|
||||
movzx cx, byte [bx+50h] ; namelen
|
||||
lea di, [bx+52h] ; name
|
||||
push ds
|
||||
pop es
|
||||
pop si ds
|
||||
push ds si
|
||||
xor ax, ax
|
||||
.1:
|
||||
lodsb
|
||||
cmp al, '/'
|
||||
jnz @f
|
||||
mov al, 0
|
||||
@@:
|
||||
cmp al, 'A'
|
||||
jb .nocapital
|
||||
cmp al, 'Z'
|
||||
ja .nocapital
|
||||
or al, 20h
|
||||
.nocapital:
|
||||
cmp al, 'a'
|
||||
jb .notletter
|
||||
cmp al, 'z'
|
||||
ja .notletter
|
||||
or byte [es:di], 20h
|
||||
.notletter:
|
||||
scasw
|
||||
loopz .1
|
||||
jb .look_child
|
||||
ja @f
|
||||
cmp byte [si], 0
|
||||
jz .file_found
|
||||
cmp byte [si], '/'
|
||||
jz .file_found
|
||||
@@:
|
||||
push es
|
||||
pop ds
|
||||
add bx, [bx+8]
|
||||
jmp .scan
|
||||
.look_child:
|
||||
push es
|
||||
pop ds
|
||||
test byte [bx+0Ch], 1
|
||||
jz .not_found
|
||||
mov si, [bp + index_alloc - dat]
|
||||
test si, si
|
||||
jz .not_found
|
||||
add bx, [bx+8]
|
||||
mov eax, [bx-8]
|
||||
mov es, [bp + cur_index_seg - dat]
|
||||
push si
|
||||
mov si, [bp + cur_index_cache - dat]
|
||||
call cache_lookup
|
||||
pop si
|
||||
pushf
|
||||
mov bx, di
|
||||
mov bh, 0
|
||||
shr bx, 3
|
||||
imul bx, dx
|
||||
add bx, [bp + frs_size - dat]
|
||||
popf
|
||||
jnc .noread
|
||||
push es
|
||||
push dx
|
||||
push ss
|
||||
pop ds
|
||||
movzx ecx, dx
|
||||
shr cx, 9
|
||||
mul [bp + sect_per_clust - dat]
|
||||
call read_attr
|
||||
pop dx
|
||||
pop es
|
||||
push es
|
||||
pop ds
|
||||
call restore_usa
|
||||
.noread:
|
||||
push es
|
||||
pop ds
|
||||
add bx, 18h
|
||||
jmp .scan_record
|
||||
.not_found:
|
||||
pop [bp + cur_obj - dat]
|
||||
mov si, error_not_found
|
||||
jmp find_error_si
|
||||
.file_found:
|
||||
pop [bp + cur_obj - dat]
|
||||
pop cx
|
||||
mov ax, [bp + index_root - dat]
|
||||
mov [bp + freeattr - dat], ax
|
||||
mov eax, [es:bx]
|
||||
test byte [es:bx+48h+3], 10h
|
||||
jz .regular_file
|
||||
cmp byte [si], 0
|
||||
jz ..directory_error
|
||||
inc si
|
||||
jmp .parse_dir_loop
|
||||
.regular_file:
|
||||
cmp byte [si], 0
|
||||
jnz ..notdir_error
|
||||
; read entry
|
||||
call read_file_record
|
||||
xor bx, bx
|
||||
mov ax, 80h
|
||||
call load_attr
|
||||
mov si, nodata_string
|
||||
jc find_error_si
|
||||
mov si, [bp + index_root - dat]
|
||||
mov [bp + freeattr - dat], si
|
||||
push ss
|
||||
pop ds
|
||||
jmp load_file_common_end
|
1024
kernel/branches/kolibri-cfg/bootloader/cdfs/bootsect.asm
Normal file
1024
kernel/branches/kolibri-cfg/bootloader/cdfs/bootsect.asm
Normal file
File diff suppressed because it is too large
Load Diff
418
kernel/branches/kolibri-cfg/bootloader/cdfs/bootsect.txt
Normal file
418
kernel/branches/kolibri-cfg/bootloader/cdfs/bootsect.txt
Normal file
@ -0,0 +1,418 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.?
|
||||
|
||||
Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660.
|
||||
(ISO-9660 и её расширения - стандарт для CD; DVD может использовать
|
||||
либо ISO-9660, либо UDF.)
|
||||
|
||||
=====================================================================
|
||||
|
||||
Требования для работы:
|
||||
1) Сам бутсектор и все используемые файлы должны быть читабельны.
|
||||
2) Минимальный процессор - 80386.
|
||||
3) В системе должно быть как минимум 452K свободной базовой памяти.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Документация в тему (ссылки проверялись на валидность 14.09.2008):
|
||||
стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
|
||||
стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf
|
||||
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
|
||||
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
|
||||
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
|
||||
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
|
||||
|
||||
=====================================================================
|
||||
|
||||
Схема используемой памяти:
|
||||
1000-1800 временный буфер для чтения одиночных секторов
|
||||
...-7C00 стек
|
||||
7C00-8400 код бутсектора
|
||||
8400-8A00 информация о кэше для папок: массив входов следующего
|
||||
формата:
|
||||
dw следующий элемент в L2-списке закэшированных папок,
|
||||
упорядоченном по времени использования
|
||||
(голова списка - самый старый);
|
||||
dw предыдущий элемент в том же списке;
|
||||
dd первый сектор папки;
|
||||
dw размер папки в байтах;
|
||||
dw сегмент кэша
|
||||
60000-... содержимое Path Table, если она используется
|
||||
+ кэш для папок;
|
||||
точный размер определяется размером доступной
|
||||
физической памяти - как правило, непосредственно
|
||||
перед A0000 размещается EBDA, Extended BIOS Data Area
|
||||
|
||||
=====================================================================
|
||||
|
||||
Основной процесс загрузки.
|
||||
Точка входа (start): получает управление от BIOS при загрузке, при этом
|
||||
dl содержит идентификатор диска, с которого идёт загрузка
|
||||
1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip
|
||||
равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает
|
||||
дальний прыжок на самого себя с целью получить cs=0 (в некоторых
|
||||
местах используется адресация переменных загрузчика через cs, поскольку
|
||||
и ds, и es могут быть заняты под другие сегменты).
|
||||
2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом)
|
||||
и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления
|
||||
и разрешённые прерывания. Сохраняет идентификатор загрузочного диска
|
||||
в специальную переменную.
|
||||
3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять
|
||||
LBA-функции.
|
||||
4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту
|
||||
ISO9660 со смещения 10h начинается цепочка описателей тома,
|
||||
завершающаяся специальным описателем (Volume Descriptor Set
|
||||
Terminator). Код по очереди считывает все сектора, пока не наткнётся
|
||||
либо на искомый описатель, либо на терминатор. Во втором случае
|
||||
выдаётся соответствующее сообщение, и загрузка прекращается.
|
||||
Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD
|
||||
располагается в последней сессии. И спецификация ElTorito загрузочного
|
||||
CD оперирует также с последней сессией. Однако на практике оказывается,
|
||||
что: во-первых, реальные BIOSы не понимают мультисессионных CD и
|
||||
всегда используют первую сессию; во-вторых, BIOSовский int 13h просто
|
||||
не позволяет получить информацию о последней сессии. В связи с этим
|
||||
загрузчик также использует первую сессию. (В-третьих, в одной из BIOS
|
||||
обнаружилась заготовка, которая в случае запроса сектора 10h, в котором
|
||||
во всех нормальных случаях и располагается PVD, перенаправляет его
|
||||
на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с
|
||||
последней сессии, то благодаря заготовке загрузчик без всяких
|
||||
модификаций также читал бы последнюю сессию.)
|
||||
5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во
|
||||
внутренние переменные: размер логического блока (согласно спецификации,
|
||||
должен быть степенью двойки от 512 до размера логического сектора,
|
||||
равного 2048 для CD и DVD); положение на диске корневой папки;
|
||||
вычисляет число блоков в секторе (из предыдущего примечания следует,
|
||||
что оно всегда целое и само является степенью двойки).
|
||||
6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет
|
||||
размер пространства, которое может использовать загрузчик (от
|
||||
адреса 6000:0000 до конца доступной памяти).
|
||||
7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит
|
||||
базовую информацию обо всех папках на диске. Если таблица слишком
|
||||
велика (больше 62K или больше половины доступной памяти), то она
|
||||
игнорируется. Если таблица путей недоступна, то запрос типа
|
||||
dir1/dir2/dir3/file приведёт к последовательному разбору корневой
|
||||
папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать
|
||||
саму таблицу путей (где записано положение папки dir1/dir2/dir3)
|
||||
и папку dir3. Если таблица загружена, то соответственно уменьшается
|
||||
объём оставшейся доступной памяти и увеличивается указатель на
|
||||
свободную область.
|
||||
8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7
|
||||
доступная память отводится под этот кэш).
|
||||
9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке
|
||||
печатает соответствующее сообщение и прекращает загрузку с CD.
|
||||
10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует
|
||||
тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is'
|
||||
идентифицирует файловую систему ISO-9660; ds:si указывает на
|
||||
callback-функцию, которую может вызывать вторичный загрузчик.
|
||||
11. Передаёт управление вторичному загрузчику, совершая дальний прыжок
|
||||
на адрес, куда kord/loader был загружен.
|
||||
|
||||
Функция обратного вызова для вторичного загрузчика (callback):
|
||||
предоставляет возможность чтения файла.
|
||||
Вход и выход описаны в спецификации на загрузчик.
|
||||
Перенаправляет запрос соответствующей локальной процедуре (load_file при
|
||||
первом запросе на загрузку файла, loadloop.loadnew при последующих
|
||||
запросах на продолжение загрузки файла).
|
||||
|
||||
Вспомогательные процедуры.
|
||||
Код обработки ошибок (err):
|
||||
1. Выводит строку с сообщением об ошибке.
|
||||
2. Выводит строку "Press any key...".
|
||||
3. Ждёт нажатия any key.
|
||||
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
|
||||
5. Для подстраховки зацикливается.
|
||||
|
||||
Процедура чтения секторов (read_sectors):
|
||||
на входе должно быть установлено:
|
||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
||||
eax = стартовый сектор
|
||||
cx = число секторов
|
||||
на выходе:
|
||||
es:bx указывает на конец буфера, в который были прочитаны данные
|
||||
если произошла ошибка чтения, флаг CF установлен
|
||||
1. В цикле (шаги 2-4) читает секторы, следит за тем, чтобы на каждой итерации
|
||||
число читаемых секторов не превосходило 7Fh (требование спецификации
|
||||
EDD BIOS).
|
||||
2. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
|
||||
итерации) до 7Fh.
|
||||
3. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
|
||||
push, причём в обратном порядке: стек - структура LIFO, и данные в
|
||||
стеке хранятся в обратном порядке по отношению к тому, как их туда
|
||||
клали).
|
||||
4. Вызывает BIOS. Если BIOS рапортует об ошибке, очищает стек,
|
||||
устанавливает CF=1 и выходит из процедуры.
|
||||
Очищает стек от пакета, сформированного на предыдущем шаге.
|
||||
5. В соответствии с числом прочитанных на текущей итерации секторов
|
||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
||||
работу, иначе возвращается на шаг 2.
|
||||
|
||||
Процедура вывода на экран ASCIIZ-строки (out_string):
|
||||
на входе: ds:si -> строка
|
||||
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh.
|
||||
|
||||
Процедура загрузки файла (load_file):
|
||||
на входе:
|
||||
ds:di = указатель на информационную структуру, описанную в спецификации
|
||||
на загрузчик, а также в комментариях к коду
|
||||
на выходе:
|
||||
bx = статус: 0=успех, 1=файл слишком большой, прочитана только часть,
|
||||
2=файл не найден, 3=ошибка чтения
|
||||
dx:ax = размер файла, 0xFFFFFFFF, если файл не найден
|
||||
1. Если подготовительный код загрузил таблицу путей, то ищет папку в таблице,
|
||||
иначе переходит сразу к шагу 4, установив eax = начальный блок
|
||||
корневой папки.
|
||||
2. Устанавливает es:di на начало таблицы путей. Ограничение на размер
|
||||
гарантирует, что вся таблица помещается в сегменте 6000h.
|
||||
Инициализирует dx (в котором будет хранится номер текущего входа в
|
||||
таблице, считая с 1), cx (размер оставшегося участка таблицы),
|
||||
bx (номер входа, соответствующего родительской папке для текущего
|
||||
рассматриваемого участка пути).
|
||||
3. В цикле ищет вход с нужным родительским элементом и нужным именем. Элементы
|
||||
таблицы путей упорядочены (подробно о порядке написано в спецификации),
|
||||
так что если родительский элемент для очередного входа больше нужного,
|
||||
то нужного входа в таблице нет совсем, и в этом случае происходит
|
||||
выход из процедуры с bx=2, ax=dx=0xFFFF. Если обнаружился элемент,
|
||||
соответствующий очередной папке в запрошенном пути, то на рассмотрение
|
||||
выносится следующая компонента пути. Если эта компонента последняя,
|
||||
то осталось найти файл в папке, и код переходит к пункту 4,
|
||||
установив eax = начальный блок этой папки. Если же нет, то эта
|
||||
компонента должна задавать имя папки, и код возвращается к пункту 3,
|
||||
скорректировав указатель на имя ds:si и номер родительского входа bx.
|
||||
4. (parse_dir) На этом шаге заданы начальный логический блок папки в eax
|
||||
и указатель на имя файла относительно этой папки в ds:si. Если
|
||||
папку искали по таблице путей, то имя файла уже не содержит подпапок;
|
||||
если же нет, то подпапки вполне возможны.
|
||||
5. Файлы в ISO-9660 могут состоять из нескольких кусков (File Section), каждый
|
||||
из которых задаётся отдельным входом в папке. Информация обо всех
|
||||
таких кусках при просмотре папки запоминается в области, начинающейся
|
||||
с адреса 0000:2000. Переменная cur_desc_end содержит указатель на
|
||||
конец этой области, он же указатель, куда будет помещена информация
|
||||
при обнаружении следующего входа. (Папки, согласно спецификации,
|
||||
должны задаваться одним куском.)
|
||||
6. Код сначала ищет запрошенную папку в кэше папок.
|
||||
7. (parse_dir.found) Если папка уже есть в кэше, то она удаляется из списка,
|
||||
отсортированного по давности последнего обращения и код переходит к
|
||||
п.15. (Следующим действием станет добавление папки в конец списка.)
|
||||
8. (parse_dir.notfound) Если же папки нет в кэше, то её придётся загружать
|
||||
с диска. Сначала загружается первый сектор (физический сектор,
|
||||
содержащий первый логический блок). При ошибке ввода/вывода
|
||||
происходит немедленный выход из процедуры с bx=3, dx=ax=0xFFFF.
|
||||
Первый элемент папки содержит информацию о самой этой папке, конкретно
|
||||
загрузчик интересуется её размером.
|
||||
9. Если размер папки слишком большой (больше или равен 64K либо больше половины
|
||||
общего размера кэша), то кэшироваться она не будет. В этом случае код
|
||||
считывает папку посекторно во временный буфер (0000:1000) и посекторно
|
||||
сканирует на наличие запрошенного имени, пока не найдёт такого имени
|
||||
или пока не кончатся данные. (Цикл начинается со сканирования,
|
||||
поскольку первая часть данных уже прочитана.) В конце код переходит
|
||||
к п.17.
|
||||
10. (parse_dir.yescache) Если принято решение о кэшировании папки, то нужно
|
||||
обеспечить достаточное количество свободного места. Для этого может
|
||||
понадобиться выкинуть какое-то количество старых данных (цикл
|
||||
parse_dir.freeloop). Но если просто выкидывать, то, вообще говоря,
|
||||
свободное пространство окажется разорванным на несколько фрагментов.
|
||||
Поэтому при выкидывании какой-то папки из кэша загрузчик перемещает
|
||||
все следующие за ней данные назад по памяти и соответственно
|
||||
корректирует информацию о местонахождении данных в информации о кэше.
|
||||
При этом новое пространство всегда добавляется в конец доступной
|
||||
памяти. Цикл выкидывания продолжается, пока не освободится место,
|
||||
достаточное для хранения папки. Из-за ограничений на размер кэшируемых
|
||||
папок в конце концов место найдётся.
|
||||
11. Выделяется новый элемент кэша. Все удалённые на шаге 10 элементы
|
||||
организуются в единый список свободных элементов; если он непуст,
|
||||
то очередной элемент берётся из этого списка; если же пуст, то
|
||||
берётся совсем новый элемент из области памяти, предназначенной для
|
||||
элементов кэша.
|
||||
12. В новом элементе заполняются поля начального блока, сегмента с данными,
|
||||
размера в байтах.
|
||||
13. Уже прочитанные данные первого физического сектора пересылаются на
|
||||
законное место в кэше.
|
||||
14. Если все данные не исчерпываются первым сектором, то догружаются оставшиеся
|
||||
данные с диска. При ошибке чтения, как и раньше, происходит выход из
|
||||
процедуры с bx=3, ax=dx=0xFFFF.
|
||||
15. (parse_dir.scan) Новый элемент добавляется в конец списка всех элементов
|
||||
кэша.
|
||||
16. Загрузчик ищет запрошенное имя в загруженных данных папки.
|
||||
(Из-за ограничений на размер кэшируемой папки все данные располагаются
|
||||
в одном сегменте.)
|
||||
17. (parse_dir.scandone) Если в процессе сканирования папки не было найдено
|
||||
никаких кусков файла, то cur_desc_end такой же, каким был вначале.
|
||||
В этом случае процедура рапортует о ненайденном файле и выходит.
|
||||
18. (filefound) Пропускает текущую компоненту имени. Если она была не последней
|
||||
(то есть подпапкой, в которой нужно производить дальнейший поиск),
|
||||
то код проверяет, что найденный вход - действительно подпапка,
|
||||
устанавливает новый стартовый блок и возвращается к п.4.
|
||||
Если же последней, то код проверяет, что найденный вход - регулярный
|
||||
файл и начинает загрузку файла.
|
||||
19. Нормализует указатель, по которому требуется прочитать файл. Под
|
||||
нормализацией понимается преобразование типа
|
||||
1234:FC08 -> (1234+0FC0):0008, которое не меняет суммарного адреса,
|
||||
но гарантирует отсутствие переполнений: в приведённом примере попытка
|
||||
переслать 400h байт по rep movsb приведёт к тому, что последние 8
|
||||
байт запишутся не в нужное место, а на 64K раньше. Далее нормализация
|
||||
будет производиться после каждой пересылки. В cur_limit помещает
|
||||
предельный размер для чтения в байтах.
|
||||
20. (loadloop) В цикле по найденным фрагментам файла загружает эти фрагменты
|
||||
(пункты 21-27).
|
||||
21. Обнуляет переменную [cur_start], имеющую смысл числа байт, которое
|
||||
нужно пропустить с начала фрагмента.
|
||||
22. (loadloop.loadnew) На эту метку управление может попасть либо с предыдущего
|
||||
шага, либо напрямую из callback-процедуры при запросе на продолжение
|
||||
чтения. Для этого и нужна вышеупомянутая переменная [cur_start] -
|
||||
при продолжении чтения, прервавшегося из-за конца буфера посередине
|
||||
фрагмента, там будет записано соответствующее значение.
|
||||
23. Определяет текущую длину (хранится в esi) как минимум из длины фрагмента
|
||||
и максимальной длины остатка. Если второе строго меньше, то
|
||||
запоминает, что файл слишком большой и прочитан только частично.
|
||||
Определяет новое значение числа прочитанных байт во фрагменте
|
||||
для возможных будущих вызовов [cur_start].
|
||||
24. Переводит пропускаемое число байт в число логических блоков и байт
|
||||
в первом блоке, последнее число записывает в переменную [first_byte],
|
||||
откуда её позднее достанет read_many_bytes.with_first.
|
||||
25. Если фрагмент записан в обычном режиме (non-interleaved mode), то код
|
||||
определяет начальный блок фрагмента и вызывает вспомогательную функцию
|
||||
чтения блоков. При ошибке чтения устанавливает bx=3 (код ошибки чтения)
|
||||
и выходит из цикла к п.28.
|
||||
26. Если фрагмент записан в чередуемом режиме (interleaved mode), то сначала
|
||||
код пропускает нужное количество непрерывных частей, а потом
|
||||
в цикле загружает непрерывные части с помощью той же функции,
|
||||
в промежутках между частями увеличивая номер начального блока.
|
||||
Пока не кончится фрагмент или пока не наберётся запрошенное число байт.
|
||||
При ошибке чтения делает то же самое, что и в предыдущем случае.
|
||||
27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер
|
||||
ещё не достигнут, переходит к следующему фрагменту и п.20. В противном
|
||||
случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли
|
||||
переполнение в п.23.
|
||||
28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех
|
||||
фрагментов.
|
||||
|
||||
Процедура проверки, является ли текущая компонента имени файла последней
|
||||
(is_last_component):
|
||||
на входе: ds:si = указатель на имя
|
||||
на выходе: флаг CF установлен, если есть последующие компоненты
|
||||
В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый,
|
||||
то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF
|
||||
и выходит.
|
||||
|
||||
Процедуры проверки на совпадение текущей компоненты имени файла с именем
|
||||
текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки):
|
||||
на входе: ds:si = указатель на имя, es:di = указатель на элемент
|
||||
таблицы путей для test_filename1, папки для test_filename2
|
||||
на выходе: CF установлен, если имена не совпадают
|
||||
В цикле проверяет совпадение приведённых к верхнему регистру очередных символов
|
||||
имён файла и элемента. Условия выхода из цикла: закончилось имя файла
|
||||
в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение
|
||||
возможно только в ситуации типа имени "filename.ext" и элемента
|
||||
"filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми
|
||||
именами в папке отсортированы по убыванию версий);
|
||||
несовпадение символов - означает, что имена не совпадают;
|
||||
закончилось имя элемента - нужно проверить, закончилось ли при этом имя
|
||||
файла, и в зависимости от этого принимать решение о совпадении.
|
||||
|
||||
Процедура приведения символа в верхний регистр (toupper):
|
||||
на входе: ASCII-символ
|
||||
на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к
|
||||
нему неприменимо)
|
||||
Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A',
|
||||
остальные символы не трогает.
|
||||
|
||||
Процедура поиска файла в данных папки (scan_for_filename_in_sector):
|
||||
на входе:
|
||||
ds:si = указатель на имя файла
|
||||
es:bx = указатель на начало данных папки
|
||||
es:dx = указатель на конец данных папки
|
||||
на выходе:
|
||||
CF сброшен, если найден финальный фрагмент файла
|
||||
(и дальше сканировать папку не нужно)
|
||||
в область для информации о фрагментах файла записывается найденное
|
||||
В цикле просматривает все входы папки, пропуская те, у которых установлен
|
||||
бит Associated (это специальные входы, дополняющие основные). Если
|
||||
имя очередного входа совпадает с именем файла, то запоминает новый
|
||||
фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent),
|
||||
то код выходит с CF=0. Если достигнут конец данных, то код выходит
|
||||
с CF=1. Если очередной вход нулевой (первый байт настоящего входа
|
||||
содержит длину и не может быть нулём), то процедура переходит к
|
||||
рассмотрению следующего логического блока. При этом потенциально
|
||||
возможно переполнение при добавлении размера блока; поскольку такой
|
||||
сценарий означает, что процедура вызвана для кэшированной папки
|
||||
с размером почти 64K и началом данных bx=0 (это свойство вызывающего
|
||||
кода), а размер блока - степень двойки, то после переполнения всегда
|
||||
bx=0, так что это можно обнаружить по взведённому ZF после сложения;
|
||||
в этом случае также происходит выход (а после переполнения CF=1).
|
||||
|
||||
Процедура перевода логического блока в номер сектора:
|
||||
на входе: eax = логический блок
|
||||
на выходе: eax = физический сектор, dx = номер логического блока в секторе
|
||||
Осуществляет обычное деление 32-битного числа на 32-битное (число логических
|
||||
блоков в секторе, хранящееся во внутренней переменной).
|
||||
|
||||
Процедура загрузки физического сектора, содержащего указанный логический блок
|
||||
(load_phys_sector_for_lb_force):
|
||||
на входе: eax = логический блок;
|
||||
si - индикатор, задающий, следует ли читать данные в случае,
|
||||
если логический блок начинается с начала физического:
|
||||
si = 0 - не нужно, si ненулевой - нужно
|
||||
на выходе:
|
||||
физический сектор загружен по адресу 0000:1000
|
||||
si указывает на данные логического блока
|
||||
CF установлен при ошибке чтения
|
||||
Преобразует предыдущей процедурой номер логического блока в номер физического
|
||||
сектора и номер логического блока внутри сектора; если последняя
|
||||
величина нулевая и никаких действий в этом случае не запрошено (si=0),
|
||||
то ничего и не делает; иначе устанавливает si в соответствии с ней
|
||||
и читает сектор.
|
||||
|
||||
Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков
|
||||
(read_many_bytes и read_many_bytes.with_first):
|
||||
на входе:
|
||||
eax = логический блок
|
||||
esi = число байт для чтения
|
||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
||||
cur_limit = размер буфера (не меньше esi)
|
||||
на выходе:
|
||||
es:bx указывает на конец буфера, в который были прочитаны данные
|
||||
если произошла ошибка чтения, флаг CF установлен
|
||||
cur_limit соответствующим образом уменьшен
|
||||
Отличие двух процедур: вторая дополнительно принимает во внимание переменную
|
||||
[first_byte], начиная чтение первого блока со смещения [first_byte];
|
||||
соответственно, первая читает блок с начала, обнуляя [first_byte]
|
||||
при входе.
|
||||
1. Отдельно считывает первый физический сектор во временную область 0000:1000,
|
||||
если первый логический блок начинается не с начала сектора. При
|
||||
ошибке чтения выходит из процедуры.
|
||||
2. Пересылает нужную часть данных (возможно, 0 байт), прочитанных в п.1,
|
||||
в буфер. Нормализует указатель на буфер.
|
||||
3. Если все необходимые данные уже прочитаны, выходит из процедуры.
|
||||
4. Дальнейшие данные находятся в нескольких физических секторах, при этом,
|
||||
возможно, последний сектор считывать нужно не целиком.
|
||||
5. Если в буфере есть место для считывания всех секторов, то сразу читаются
|
||||
все сектора, после чего указатель на буфер нужным образом уменьшается.
|
||||
6. Если же нет, то считываются все сектора, кроме последнего, после чего
|
||||
последний сектор считывается отдельно во временную область, и уже
|
||||
оттуда нужная часть данных копируется в буфер.
|
2
kernel/branches/kolibri-cfg/bootloader/cdfs/build.bat
Normal file
2
kernel/branches/kolibri-cfg/bootloader/cdfs/build.bat
Normal file
@ -0,0 +1,2 @@
|
||||
@fasm -m 65535 bootsect.asm bootsect.bin
|
||||
@pause
|
392
kernel/branches/kolibri-cfg/bootloader/fat1x/bootsect.asm
Normal file
392
kernel/branches/kolibri-cfg/bootloader/fat1x/bootsect.asm
Normal file
@ -0,0 +1,392 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
use_lba = 0
|
||||
org 0x7C00
|
||||
jmp start
|
||||
nop
|
||||
; FAT parameters, BPB
|
||||
; note: they can be changed at install, replaced with real values
|
||||
; these settings are for most typical 1.44M floppies
|
||||
db 'KOLIBRI ' ; BS_OEMName, ignored
|
||||
dw 200h ; BPB_BytsPerSec
|
||||
BPB_SecsPerClus db 1
|
||||
BPB_RsvdSecCnt dw 1
|
||||
BPB_NumFATs db 2
|
||||
BPB_RootEntCnt dw 0xE0
|
||||
dw 2880 ; BPB_TotSec16
|
||||
db 0xF0 ; BPB_Media
|
||||
BPB_FATSz16 dw 9
|
||||
BPB_SecPerTrk dw 18
|
||||
BPB_NumHeads dw 2
|
||||
BPB_HiddSec dd 0
|
||||
dd 0 ; BPB_TotSec32
|
||||
BS_DrvNum db 0
|
||||
db 0 ; BS_Reserved1
|
||||
db ')' ; BS_BootSig
|
||||
dd 12344321h ; BS_VolID
|
||||
filename:
|
||||
db 'KORD.OS ' ; BS_VolLab
|
||||
db 'FAT12 ' ; BS_FilSysType
|
||||
; Used memory map:
|
||||
; 8000:0000 - current directory
|
||||
; 9000:0000 - root directory data [cached]
|
||||
start:
|
||||
xor ax, ax
|
||||
mov ss, ax
|
||||
mov sp, 0x7C00
|
||||
mov ds, ax
|
||||
mov bp, sp
|
||||
cld
|
||||
sti
|
||||
mov [bp+BS_DrvNum-0x7C00], dl
|
||||
if use_lba
|
||||
mov ah, 41h
|
||||
mov bx, 55AAh
|
||||
int 13h
|
||||
mov si, aNoLBA
|
||||
jc err_
|
||||
cmp bx, 0AA55h
|
||||
jnz err_
|
||||
test cx, 1
|
||||
jz err_
|
||||
else
|
||||
mov ah, 8
|
||||
int 13h
|
||||
jc @f ; on error, assume that BPB geometry is valid
|
||||
mov al, dh
|
||||
mov ah, 0
|
||||
inc ax
|
||||
mov [bp+BPB_NumHeads-0x7C00], ax
|
||||
and cx, 3Fh
|
||||
mov [bp+BPB_SecPerTrk-0x7C00], cx
|
||||
@@:
|
||||
end if
|
||||
; get FAT parameters
|
||||
xor bx, bx
|
||||
mov al, [bp+BPB_NumFATs-0x7C00]
|
||||
mov ah, 0
|
||||
mul [bp+BPB_FATSz16-0x7C00]
|
||||
add ax, [bp+BPB_RsvdSecCnt-0x7C00]
|
||||
adc dx, bx
|
||||
push dx
|
||||
push ax ; root directory start = dword [bp-4]
|
||||
mov cx, [bp+BPB_RootEntCnt-0x7C00]
|
||||
add cx, 0xF
|
||||
rcr cx, 1
|
||||
shr cx, 3 ; cx = size of root directory in sectors
|
||||
add ax, cx
|
||||
adc dx, bx
|
||||
push dx
|
||||
push ax ; data start = dword [bp-8]
|
||||
; load start of root directory (no more than 0x2000 bytes = 0x10 sectors)
|
||||
cmp cx, 0x10
|
||||
jb @f
|
||||
mov cx, 0x10
|
||||
@@:
|
||||
mov ax, [bp-4]
|
||||
mov dx, [bp-2]
|
||||
push 0x9000
|
||||
pop es
|
||||
call read_sectors
|
||||
add word [bp-4], cx ; dword [bp-4] = start of non-cached root data
|
||||
adc word [bp-2], bx
|
||||
; load kordldr.f12
|
||||
mov si, main_loader
|
||||
call lookup_in_root_dir
|
||||
jc noloader
|
||||
test byte [es:di+11], 10h ; directory?
|
||||
jz kordldr_ok
|
||||
noloader:
|
||||
mov si, aLoaderNotFound
|
||||
err_:
|
||||
call out_string
|
||||
mov si, aPressAnyKey
|
||||
call out_string
|
||||
xor ax, ax
|
||||
int 16h
|
||||
int 18h
|
||||
jmp $
|
||||
kordldr_ok:
|
||||
mov ax, [es:di+26] ; get file cluster
|
||||
mov bx, 0x7E00
|
||||
xor cx, cx
|
||||
mov es, cx
|
||||
sub ax, 2
|
||||
jc noloader
|
||||
push bx ; save return address: bx = 7E00
|
||||
mov cl, [bp+BPB_SecsPerClus-0x7C00]
|
||||
mul cx
|
||||
; fall through - 'ret' in read_sectors will return to 7E00
|
||||
|
||||
read_sectors2:
|
||||
; same as read_sectors, but dx:ax is relative to start of data
|
||||
add ax, [bp-8]
|
||||
adc dx, [bp-6]
|
||||
read_sectors:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; dx:ax = first sector
|
||||
; cx = number of sectors
|
||||
pusha
|
||||
add ax, word [bp+BPB_HiddSec-0x7C00]
|
||||
adc dx, word [bp+BPB_HiddSec+2-0x7C00]
|
||||
if use_lba
|
||||
push ds
|
||||
do_read_sectors:
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
cmp cx, 0x7F
|
||||
jbe @f
|
||||
mov cx, 0x7F
|
||||
@@:
|
||||
; create disk address packet on the stack
|
||||
; dq starting LBA
|
||||
push 0
|
||||
push 0
|
||||
push dx
|
||||
push ax
|
||||
; dd buffer
|
||||
push es
|
||||
push bx
|
||||
; dw number of blocks to transfer (no more than 0x7F)
|
||||
push cx
|
||||
; dw packet size in bytes
|
||||
push 10h
|
||||
; issue BIOS call
|
||||
push ss
|
||||
pop ds
|
||||
mov si, sp
|
||||
mov dl, [bp+BS_DrvNum-0x7C00]
|
||||
mov ah, 42h
|
||||
int 13h
|
||||
mov si, aReadError
|
||||
jc err_
|
||||
; restore stack
|
||||
add sp, 10h
|
||||
; increase current sector & buffer; decrease number of sectors
|
||||
mov si, cx
|
||||
mov ax, es
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
add ax, si
|
||||
adc dx, 0
|
||||
sub cx, si
|
||||
jnz do_read_sectors
|
||||
pop ds
|
||||
popa
|
||||
ret
|
||||
else
|
||||
do_read_sectors:
|
||||
pusha
|
||||
pop di
|
||||
push bx
|
||||
|
||||
; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx
|
||||
mov si, ax
|
||||
xchg ax, dx
|
||||
xor dx, dx
|
||||
div [bp+BPB_SecPerTrk-0x7C00]
|
||||
push ax
|
||||
mov ax, si
|
||||
div [bp+BPB_SecPerTrk-0x7C00]
|
||||
mov bx, dx ; bx=sector-1
|
||||
pop dx
|
||||
|
||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
||||
div [bp+BPB_NumHeads-0x7C00]
|
||||
|
||||
; number of sectors: read no more than to end of track
|
||||
push bx
|
||||
sub bx, [bp+BPB_SecPerTrk-0x7C00]
|
||||
neg bx
|
||||
cmp cx, bx
|
||||
jbe @f
|
||||
mov cx, bx
|
||||
@@:
|
||||
pop bx
|
||||
|
||||
inc bx
|
||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
|
||||
mov di, cx
|
||||
mov dh, dl
|
||||
mov dl, [bp+BS_DrvNum-0x7C00]
|
||||
shl ah, 6
|
||||
mov ch, al
|
||||
mov al, cl
|
||||
mov cl, bl
|
||||
or cl, ah
|
||||
pop bx
|
||||
mov si, 3
|
||||
mov ah, 2
|
||||
@@:
|
||||
push ax
|
||||
int 13h
|
||||
jnc @f
|
||||
xor ax, ax
|
||||
int 13h ; reset drive
|
||||
pop ax
|
||||
dec si
|
||||
jnz @b
|
||||
mov si, aReadError
|
||||
jmp err_
|
||||
@@:
|
||||
pop ax
|
||||
mov ax, es
|
||||
mov cx, di
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
push di
|
||||
popa
|
||||
add ax, di
|
||||
adc dx, 0
|
||||
sub cx, di
|
||||
jnz do_read_sectors
|
||||
popa
|
||||
ret
|
||||
end if
|
||||
|
||||
scan_for_filename:
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; in: es:0 -> part of directory data
|
||||
; in: cx = number of entries
|
||||
; out: if found: CF=0, ZF=1, es:di -> directory entry
|
||||
; out: if not found, but continue required: CF=1 and ZF=0
|
||||
; out: if not found and zero item reached: CF=1 and ZF=1
|
||||
xor di, di
|
||||
push cx
|
||||
sloop:
|
||||
cmp byte [es:di], 0
|
||||
jz snotfound
|
||||
test byte [es:di+11], 8 ; volume label?
|
||||
jnz scont ; ignore volume labels
|
||||
pusha
|
||||
mov cx, 11
|
||||
repz cmpsb
|
||||
popa
|
||||
jz sdone
|
||||
scont:
|
||||
add di, 0x20
|
||||
loop sloop
|
||||
inc cx ; clear ZF flag
|
||||
snotfound:
|
||||
stc
|
||||
sdone:
|
||||
pop cx
|
||||
lrdret:
|
||||
ret
|
||||
|
||||
lookup_in_root_dir:
|
||||
; ss:bp = 0:7C00
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; out: if found: CF=0, es:di -> directory entry
|
||||
; out: if not found: CF=1
|
||||
mov cx, [bp+BPB_RootEntCnt-0x7C00]
|
||||
push cx
|
||||
; first, look in root directory cache
|
||||
push 0x9000
|
||||
pop es
|
||||
test ch, ch
|
||||
jz @f
|
||||
mov cx, 0x100
|
||||
@@:
|
||||
mov ax, [bp-4]
|
||||
mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory
|
||||
lrdloop:
|
||||
call scan_for_filename
|
||||
pop bx
|
||||
jz lrdret
|
||||
sub bx, cx
|
||||
mov cx, bx
|
||||
stc
|
||||
jz lrdret
|
||||
; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries
|
||||
push cx
|
||||
cmp ch, 0x8
|
||||
jb @f
|
||||
mov cx, 0x800
|
||||
@@:
|
||||
push 0x8000
|
||||
pop es
|
||||
push cx
|
||||
push es
|
||||
xor bx, bx
|
||||
add cx, 0xF
|
||||
shr cx, 4
|
||||
call read_sectors
|
||||
pop es
|
||||
add ax, cx
|
||||
adc dx, bx
|
||||
pop cx
|
||||
jmp lrdloop
|
||||
|
||||
out_string:
|
||||
; in: ds:si -> ASCIIZ string
|
||||
lodsb
|
||||
test al, al
|
||||
jz lrdret
|
||||
mov ah, 0Eh
|
||||
mov bx, 7
|
||||
int 10h
|
||||
jmp out_string
|
||||
|
||||
aReadError db 'Read error',0
|
||||
if use_lba
|
||||
aNoLBA db 'The drive does not support LBA!',0
|
||||
end if
|
||||
aLoaderNotFound db 'Loader not found',0
|
||||
aPressAnyKey db 13,10,'Press any key...',13,10,0
|
||||
main_loader db 'KORDLDR F1X'
|
||||
|
||||
if use_lba
|
||||
db 0 ; make bootsector 512 bytes in length
|
||||
end if
|
||||
|
||||
; bootsector signature
|
||||
dw 0xAA55
|
||||
|
||||
; display offsets of all procedures used by kordldr.f12.asm
|
||||
macro show [procedure]
|
||||
{
|
||||
bits = 16
|
||||
display `procedure,' = '
|
||||
repeat bits/4
|
||||
d = '0' + procedure shr (bits - %*4) and 0Fh
|
||||
if d > '9'
|
||||
d = d + 'A'-'9'-1
|
||||
end if
|
||||
display d
|
||||
end repeat
|
||||
display 13,10
|
||||
}
|
||||
|
||||
show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader
|
360
kernel/branches/kolibri-cfg/bootloader/fat1x/bootsect.txt
Normal file
360
kernel/branches/kolibri-cfg/bootloader/fat1x/bootsect.txt
Normal file
@ -0,0 +1,360 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
Встречаются вирус и FAT.
|
||||
- Привет, ты кто?
|
||||
- Я? Вирус.
|
||||
- A я AFT, то есть TAF, то есть FTA, черт, совсем запутался...
|
||||
|
||||
Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Есть две версии в зависимости от того, поддерживает ли носитель LBA,
|
||||
выбор осуществляется установкой константы use_lba в первой строке исходника.
|
||||
Требования для работы:
|
||||
1) Сам бутсектор, первая копия FAT и все используемые файлы
|
||||
должны быть читабельны.
|
||||
2) Минимальный процессор - 80186.
|
||||
3) В системе должно быть как минимум 592K свободной базовой памяти.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Документация в тему (ссылки валидны на момент написания этого файла, 15.05.2008):
|
||||
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
||||
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
|
||||
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip
|
||||
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
|
||||
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
|
||||
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
|
||||
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
|
||||
|
||||
=====================================================================
|
||||
|
||||
Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер
|
||||
занимает 12 бит в таблице FAT, так что общий размер не превосходит
|
||||
0x17EE = 6126 байт. Вся таблица помещается в памяти.
|
||||
Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый
|
||||
кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит
|
||||
0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в
|
||||
этом случае несколько нецелесообразно считывать всю таблицу, поскольку
|
||||
на практике нужна только небольшая её часть. Поэтому место в памяти
|
||||
резервируется, но данные считываются только в момент, когда к ним
|
||||
действительно идёт обращение.
|
||||
|
||||
Схема используемой памяти:
|
||||
...-7C00 стек
|
||||
7C00-7E00 код бутсектора
|
||||
7E00-8200 вспомогательный файл загрузчика (kordldr.f1x)
|
||||
8200-8300 список загруженных секторов таблицы FAT16
|
||||
(1 = соответствующий сектор загружен)
|
||||
60000-80000 загруженная таблица FAT12 / место для таблицы FAT16
|
||||
80000-90000 текущий кластер текущей рассматриваемой папки
|
||||
90000-92000 кэш для корневой папки
|
||||
92000-... кэш для некорневых папок (каждой папке отводится
|
||||
2000h байт = 100h входов, одновременно в кэше
|
||||
может находиться не более 7 папок;
|
||||
точный размер определяется размером доступной
|
||||
физической памяти - как правило, непосредственно
|
||||
перед A0000 размещается EBDA, Extended BIOS Data Area)
|
||||
|
||||
=====================================================================
|
||||
|
||||
Основной процесс загрузки.
|
||||
Точка входа (start): получает управление от BIOS при загрузке, при этом
|
||||
dl содержит идентификатор диска, с которого идёт загрузка
|
||||
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед
|
||||
кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало
|
||||
бутсектора (в дальнейшем данные будут адресоваться через [bp+N] -
|
||||
это освобождает ds и экономит на размере кода).
|
||||
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h
|
||||
прерывания 13h. Если нет, переходит на код обработки ошибок с
|
||||
сообщением об отсутствии LBA.
|
||||
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и
|
||||
записывает полученные данные поверх BPB. Если вызов завершился ошибкой,
|
||||
предполагает уже существующие данные корректными.
|
||||
3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки
|
||||
и начальный сектор данных. Кладёт их в стек; впоследствии они
|
||||
всегда будут лежать в стеке и адресоваться через bp.
|
||||
4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых
|
||||
секторов - минимум из размера корневой папки, указанного в BPB, и 16
|
||||
(размер кэша для корневой папки - 2000h байт = 16 секторов).
|
||||
5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если
|
||||
он оказывается папкой, или если файл имеет нулевую длину -
|
||||
переходит на код обработки ошибок с сообщением о
|
||||
ненайденном загрузчике.
|
||||
Замечание: на этом этапе загрузки искать можно только в корневой
|
||||
папке и только имена, заданные в формате файловой системе FAT
|
||||
(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны
|
||||
быть заглавными, при необходимости имя и расширение дополняются
|
||||
пробелами, разделяющей точки нет, завершающего нуля нет).
|
||||
6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт
|
||||
ему управление. При этом в регистрах dx:ax оказывается абсолютный
|
||||
номер первого сектора kordldr.f1x, а в cx - число считанных секторов
|
||||
(равное размеру кластера).
|
||||
|
||||
Вспомогательные процедуры бутсектора.
|
||||
Код обработки ошибок (err):
|
||||
1. Выводит строку с сообщением об ошибке.
|
||||
2. Выводит строку "Press any key...".
|
||||
3. Ждёт нажатия any key.
|
||||
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
|
||||
5. Для подстраховки зацикливается.
|
||||
|
||||
Процедура чтения секторов (read_sectors и read_sectors2):
|
||||
на входе должно быть установлено:
|
||||
ss:bp = 0:7C00
|
||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
||||
dx:ax = стартовый сектор (относительно начала логического диска
|
||||
для read_sectors, относительно начала данных для read_sectors2)
|
||||
cx = число секторов (должно быть больше нуля)
|
||||
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные
|
||||
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора
|
||||
в номер относительно начала логического диска, прибавляя номер сектора
|
||||
начала данных, хранящийся в стеке как [bp-8].
|
||||
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на
|
||||
устройстве, прибавляя значение соответствующего поля из BPB.
|
||||
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации
|
||||
CHS-версия: все читаемые секторы были на одной дорожке.
|
||||
LBA-версия: число читаемых секторов не превосходило 7Fh (требование
|
||||
спецификации EDD BIOS).
|
||||
CHS-версия:
|
||||
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как
|
||||
единица плюс остаток от деления абсолютного номера на число секторов
|
||||
на дорожке; дорожка рассчитывается как остаток от деления частного,
|
||||
полученного на предыдущем шаге, на число дорожек, а цилиндр - как
|
||||
частное от этого же деления. Если число секторов для чтения больше,
|
||||
чем число секторов до конца дорожки, уменьшает число секторов для
|
||||
чтения.
|
||||
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов,
|
||||
dh=головка, (младшие 6 бит cl)=сектор,
|
||||
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер).
|
||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска
|
||||
и повторяет попытку чтения, всего делается не более трёх попыток
|
||||
(несколько попыток нужно в случае дискеты для гарантии того, что
|
||||
мотор раскрутился). Если все три раза происходит ошибка чтения,
|
||||
переходит на код обработки ошибок с сообщением "Read error".
|
||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
||||
работу, иначе возвращается на шаг 3.
|
||||
LBA-версия:
|
||||
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
|
||||
итерации) до 7Fh.
|
||||
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
|
||||
push, причём в обратном порядке: стек - структура LIFO, и данные в
|
||||
стеке хранятся в обратном порядке по отношению к тому, как их туда
|
||||
клали).
|
||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки
|
||||
ошибок с сообщением "Read error". Очищает стек от пакета,
|
||||
сформированного на предыдущем шаге.
|
||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
||||
работу, иначе возвращается на шаг 3.
|
||||
|
||||
Процедура поиска элемента по имени в уже прочитанных данных папки
|
||||
(scan_for_filename):
|
||||
на входе должно быть установлено:
|
||||
ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя,
|
||||
3 на расширение, все буквы заглавные, если имя/расширение
|
||||
короче, оно дополняется до максимума пробелами)
|
||||
es = сегмент данных папки
|
||||
cx = число элементов в прочитанных данных
|
||||
на выходе: ZF определяет, нужно ли продолжать разбор данных папки
|
||||
(ZF=1, если либо найден запрошенный элемент, либо достигнут
|
||||
конец папки); CF определяет, удалось ли найти элемент с искомым именем
|
||||
(CF=1, если не удалось); если удалось, то es:di указывает на него.
|
||||
scan_for_filename считает, что данные папки размещаются начиная с es:0.
|
||||
Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки
|
||||
проверяет имена.
|
||||
|
||||
Процедура поиска элемента в корневой папке (lookup_in_root_dir):
|
||||
на входе должно быть установлено:
|
||||
ss:bp = 0:7C00
|
||||
ds:si = указатель на имя файла в формате FAT (см. выше)
|
||||
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то
|
||||
CF сброшен и es:di указывает на элемент папки
|
||||
Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле
|
||||
сканирует элементы; если по результатам сканирования обнаруживает,
|
||||
что нужно читать папку дальше, то считывает не более 0x10000 = 64K
|
||||
байт (ограничение введено по двум причинам: во-первых, чтобы заведомо
|
||||
не вылезти за пределы используемой памяти, во-вторых, сканирование
|
||||
предполагает, что все обрабатываемые элементы располагаются в одном
|
||||
сегменте) и продолжает цикл.
|
||||
Сканирование прекращается в трёх случаях: обнаружен искомый элемент;
|
||||
кончились элементы в папке (судя по числу элементов, указанному в BPB);
|
||||
очередной элемент папки сигнализирует о конце (первый байт нулевой).
|
||||
|
||||
Процедура вывода на экран ASCIIZ-строки (out_string):
|
||||
на входе: ds:si -> строка
|
||||
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Работа вспомогательного загрузчика kordldr.f1x:
|
||||
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора.
|
||||
В зависимости от этого устанавливает смещения используемых процедур
|
||||
бутсектора. Критерий проверки: scan_for_filename должна начинаться
|
||||
с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может
|
||||
с равным успехом ассемблироваться и как 33 FF, но fasm генерирует
|
||||
именно такую форму).
|
||||
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска
|
||||
адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с
|
||||
ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента
|
||||
место должно быть, отсюда ограничение в 592 Kb (94000h байт).
|
||||
Замечание: этот размер не может превосходить 0A0000h байт и
|
||||
на практике оказывается немного (на 1-2 килобайта) меньшим из-за
|
||||
наличия дополнительной области данных BIOS "вверху" базовой памяти.
|
||||
3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной
|
||||
спецификации от Microsoft (версия 1.03 спецификации датирована,
|
||||
к слову, 06 декабря 2000 года), разрядность FAT определяется
|
||||
исключительно числом кластеров: максимальное число кластеров на
|
||||
FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12
|
||||
может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2,
|
||||
а число 0xFF7 не может быть корректным номером кластера.
|
||||
Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается
|
||||
по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает
|
||||
явно неверно, считая, что 0xFF6 (или меньше) кластеров означает
|
||||
FAT12-том, в результате получается, что последний кластер
|
||||
(в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe
|
||||
[встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик
|
||||
[бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы
|
||||
лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили
|
||||
в соответствии со спецификацией. Linux при определении FAT12/FAT16
|
||||
честно следует спецификации.
|
||||
Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT
|
||||
Microsoft если и будет исправлять ошибки, то согласно собственному
|
||||
описанию.
|
||||
4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000.
|
||||
Если размер, указанный в BPB, превосходит 12 секторов,
|
||||
это означает, что заявленный размер слишком большой (это не считается
|
||||
ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12
|
||||
заведомо влезает в такой объём данных).
|
||||
Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор
|
||||
FAT не загружен (они будут подгружаться позднее, когда понадобятся
|
||||
и только те, которые понадобятся).
|
||||
5. Если кластер равен сектору, то бутсектор загрузил только часть файла
|
||||
kordldr.f1x, и загрузчик подгружает вторую свою часть, используя
|
||||
значения регистров на входе в kordldr.f1x.
|
||||
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не
|
||||
найден, или оказался папкой, или оказался слишком большим, то переходит
|
||||
на код обработки ошибок из бутсектора с сообщением
|
||||
"Fatal error: cannot load the secondary loader".
|
||||
Замечание: на этом этапе имя файла уже можно указывать вместе с путём
|
||||
и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов
|
||||
по-прежнему нет.
|
||||
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err.
|
||||
Это нужно, чтобы последующие обращения к коду бутсектора в случае
|
||||
ошибок чтения не выводил соответствующее сообщение с последующей
|
||||
перезагрузкой, а рапортовал об ошибке чтения, которую мог бы
|
||||
как-нибудь обработать вторичный загрузчик.
|
||||
8. Если загрузочный диск имеет идентификатор меньше 0x80,
|
||||
то устанавливает al='f' ("floppy"), ah=идентификатор диска,
|
||||
иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска).
|
||||
Устанавливает bx='12', если тип файловой системы - FAT12, и
|
||||
bx='16' в случае FAT16. Устанавливает si=смещение функции обратного
|
||||
вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес.
|
||||
9. Передаёт управление по адресу 1000:0000.
|
||||
|
||||
Функция обратного вызова для вторичного загрузчика:
|
||||
предоставляет возможность чтения файла.
|
||||
Вход и выход описаны в спецификации на загрузчик.
|
||||
1. Сохраняет стек вызывающего кода и устанавливает свой стек:
|
||||
ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным
|
||||
кодом должна указывать на 0:7C00, а -8 берётся от того, что
|
||||
инициализирующий код бутсектора уже поместил в стек 2 двойных слова,
|
||||
и они должны сохраняться в неизменности.
|
||||
2. Разбирает переданные параметры, выясняет, какое действие запрошено,
|
||||
и вызывает нужную вспомогательную процедуру.
|
||||
3. Восстанавливает стек вызывающего кода и возвращает управление.
|
||||
|
||||
Вспомогательные процедуры kordldr.f1x.
|
||||
Процедура получения следующего кластера в FAT (get_next_cluster):
|
||||
1. Вспоминает разрядность FAT, вычисленную ранее.
|
||||
Для FAT12:
|
||||
2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана
|
||||
вся таблица FAT.
|
||||
3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте
|
||||
слова, задающего следующий кластер. Загружает слово по этому адресу.
|
||||
4. Если кластер имеет нечётный номер, то соответствующий ему элемент
|
||||
располагается в старших 12 битах слова, и слово нужно сдвинуть вправо
|
||||
на 4 бита; в противном случае - в младших 12 битах, и делать ничего не
|
||||
надо.
|
||||
5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7:
|
||||
номера нормальных кластеров меньше, и флаг CF устанавливается;
|
||||
специальные значения EOF и BadClus сбрасывают флаг CF.
|
||||
Для FAT16:
|
||||
2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных
|
||||
в таблице FAT.
|
||||
3. Если сектор ещё не загружен, то загружает его.
|
||||
4. Вычисляет смещение данных для конкретного кластера относительно начала
|
||||
сектора.
|
||||
5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3.
|
||||
6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг
|
||||
CF устанавливается; специальные значения EOF и BadClus сбрасывают CF.
|
||||
|
||||
Процедура загрузки файла (load_file):
|
||||
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4.
|
||||
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты
|
||||
разделяются символом '/') в FAT-формат 8+3. Если это невозможно
|
||||
(больше 8 символов в имени, больше 3 символов в расширении или
|
||||
больше одной точки), возвращается с ошибкой.
|
||||
3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой
|
||||
папки используется процедура из бутсектора. Для остальных папок:
|
||||
a) Проверяет, есть ли такая папка в кэше некорневых папок.
|
||||
(Идентификация папок осуществляется по номеру начального кластера.)
|
||||
Если такой папки ещё нет, добавляет её в кэш; если тот переполняется,
|
||||
выкидывает папку, к которой дольше всего не было обращений. (Для
|
||||
каждого элемента кэша хранится метка от 0 до (размер кэша)-1,
|
||||
определяющая его номер при сортировке по давности последнего обращения.
|
||||
При обращении к какому-то элементу его метка становится нулевой,
|
||||
а те метки, которые меньше старого значения, увеличиваются на единицу.)
|
||||
б) Просматривает в поисках запрошенного имени все элементы из кэша,
|
||||
используя процедуру из бутсектора. Если обнаруживает искомый элемент,
|
||||
переходит к шагу 4. Если обнаруживает конец папки, возвращается из
|
||||
процедуры с ошибкой.
|
||||
в) В цикле считывает папку посекторно. При этом пропускает начальные
|
||||
секторы, которые уже находятся в кэше и уже были просмотрены. Каждый
|
||||
прочитанный сектор копирует в кэш, если там ещё остаётся место,
|
||||
и просматривает в нём все элементы. Работает, пока не случится одно из
|
||||
трёх событий: найден искомый элемент; кончились кластеры (судя по
|
||||
цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце
|
||||
(первый байт нулевой). В двух последних случаях возвращается с ошибкой.
|
||||
4. Проверяет тип найденного элемента (файл/папка): последний элемент в
|
||||
запрошенном имени должен быть файлом, все промежуточные - папками.
|
||||
Если текущий компонент имени - промежуточный, продвигает текущую
|
||||
рассматриваемую папку и возвращается к пункту 2.
|
||||
5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный
|
||||
при вызове буфер последовательными вызовами функции бутсектора;
|
||||
при этом если несколько кластеров файла расположены на диске
|
||||
последовательно, то их чтение объединяется в одну операцию.
|
||||
Следит за тем, чтобы не превысить указанный при вызове процедуры
|
||||
лимит числа секторов для чтения.
|
||||
|
||||
Процедура продолжения загрузки файла (continue_load_file): встроена
|
||||
внутрь шага 5 load_file; загружает в регистры нужные значения (ранее
|
||||
сохранённые из load_file) и продолжает шаг 5.
|
3
kernel/branches/kolibri-cfg/bootloader/fat1x/build.bat
Normal file
3
kernel/branches/kolibri-cfg/bootloader/fat1x/build.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@fasm -m 65535 bootsect.asm bootsect.bin
|
||||
@fasm -m 65535 kordldr.f1x.asm kordldr.f1x
|
||||
@pause
|
688
kernel/branches/kolibri-cfg/bootloader/fat1x/kordldr.f1x.asm
Normal file
688
kernel/branches/kolibri-cfg/bootloader/fat1x/kordldr.f1x.asm
Normal file
@ -0,0 +1,688 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
org 0x7E00
|
||||
; the KordOS FAT12/FAT16 bootsector loads first cluster of this file to 0:7E00 and transfers control to here
|
||||
; ss:bp = 0:7C00
|
||||
virtual at bp
|
||||
rb 3 ; BS_jmpBoot
|
||||
rb 8 ; BS_OEMName, ignored
|
||||
dw ? ; BPB_BytsPerSec
|
||||
BPB_SecsPerClus db ?
|
||||
BPB_RsvdSecCnt dw ?
|
||||
BPB_NumFATs db ?
|
||||
BPB_RootEntCnt dw ?
|
||||
BPB_TotSec16 dw ?
|
||||
db ? ; BPB_Media
|
||||
BPB_FATSz16 dw ?
|
||||
BPB_SecPerTrk dw ?
|
||||
BPB_NumHeads dw ?
|
||||
BPB_HiddSec dd ?
|
||||
BPB_TotSec32 dd ?
|
||||
BS_DrvNum db ?
|
||||
fat_type db ? ; this is BS_Reserved1,
|
||||
; we use it to save FS type: 0=FAT12, 1=FAT16
|
||||
db ? ; BS_BootSig
|
||||
num_sectors dd ? ; BS_VolID
|
||||
; rb 11 ; BS_VolLab
|
||||
; rb 3 ; BS_FilSysType, first 3 bytes
|
||||
read_sectors dw ?
|
||||
read_sectors2 dw ?
|
||||
lookup_in_root_dir dw ?
|
||||
scan_for_filename dw ?
|
||||
err_ dw ?
|
||||
noloader dw ?
|
||||
cachelimit dw ?
|
||||
filesize: ; will be used to save file size
|
||||
rb 5 ; BS_FilSysType, last 5 bytes
|
||||
; following variables are located in the place of starting code;
|
||||
; starting code is no more used at this point
|
||||
sect_per_clus dw ?
|
||||
cur_cluster dw ?
|
||||
next_cluster dw ?
|
||||
flags dw ?
|
||||
cur_delta dd ?
|
||||
end virtual
|
||||
|
||||
; procedures from boot sector
|
||||
; LBA version
|
||||
lba_read_sectors = 7CE2h
|
||||
lba_read_sectors2 = 7CDCh
|
||||
lba_lookup_in_root_dir = 7D4Fh
|
||||
lba_scan_for_filename = 7D2Dh
|
||||
lba_err = 7CB5h
|
||||
lba_noloader = 7CB2h
|
||||
; CHS version
|
||||
chs_read_sectors = 7CDEh
|
||||
chs_read_sectors2 = 7CD8h
|
||||
chs_lookup_in_root_dir = 7D70h
|
||||
chs_scan_for_filename = 7D4Eh
|
||||
chs_err = 7CB1h
|
||||
chs_noloader = 7CAEh
|
||||
|
||||
push ax cx ; save our position on disk
|
||||
push ss
|
||||
pop es
|
||||
; determine version of bootsector (LBA vs CHS)
|
||||
; mov [read_sectors], chs_read_sectors
|
||||
; mov [read_sectors2], chs_read_sectors2
|
||||
; mov [lookup_in_root_dir], chs_lookup_in_root_dir
|
||||
; mov [scan_for_filename], chs_scan_for_filename
|
||||
; mov [err], chs_err
|
||||
; mov [noloader], chs_noloader
|
||||
lea di, [read_sectors]
|
||||
mov si, chs_proc_addresses
|
||||
mov cx, 6*2
|
||||
cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di'
|
||||
jz @f
|
||||
add si, cx
|
||||
; mov [read_sectors], lba_read_sectors
|
||||
; mov [read_sectors2], lba_read_sectors2
|
||||
; mov [lookup_in_root_dir], lba_lookup_in_root_dir
|
||||
; mov [scan_for_filename], lba_scan_for_filename
|
||||
; mov [err], lba_err
|
||||
; mov [noloader], lba_noloader
|
||||
@@:
|
||||
rep movsb
|
||||
mov cl, [BPB_SecsPerClus]
|
||||
mov [sect_per_clus], cx
|
||||
xor bx, bx
|
||||
; determine size of cache for folders
|
||||
int 12h ; ax = size of available base memory in Kb
|
||||
sub ax, 94000h / 1024
|
||||
jae @f
|
||||
nomem:
|
||||
mov si, nomem_str
|
||||
jmp [err_]
|
||||
@@:
|
||||
shr ax, 3
|
||||
mov [cachelimit], ax ; size of cache - 1
|
||||
; get type of file system - FAT12 or FAT16?
|
||||
; calculate number of clusters
|
||||
mov ax, [BPB_TotSec16]
|
||||
xor dx, dx
|
||||
test ax, ax
|
||||
jnz @f
|
||||
mov ax, word [BPB_TotSec32]
|
||||
mov dx, word [BPB_TotSec32+2]
|
||||
@@:
|
||||
sub ax, [bp-8] ; dword [bp-8] = first data sector
|
||||
sbb dx, [bp-6]
|
||||
jb j_noloader
|
||||
div [sect_per_clus]
|
||||
; ax = number of clusters
|
||||
; note: this is loader for FAT12/FAT16, so 'div' does not overflow on correct volumes
|
||||
mov [fat_type], ch
|
||||
cmp ax, 0xFF5
|
||||
jb init_fat12
|
||||
inc [fat_type]
|
||||
init_fat16:
|
||||
; no sectors loaded
|
||||
mov di, 0x8200
|
||||
xor ax, ax
|
||||
mov cx, 0x100/2
|
||||
rep stosw
|
||||
jmp init_fat_done
|
||||
init_fat12:
|
||||
; read FAT
|
||||
push 0x6000
|
||||
pop es
|
||||
mov ax, [BPB_RsvdSecCnt]
|
||||
mov cx, [BPB_FATSz16]
|
||||
cmp cx, 12
|
||||
jb @f
|
||||
mov cx, 12
|
||||
@@:
|
||||
xor dx, dx
|
||||
call [read_sectors]
|
||||
init_fat_done:
|
||||
; if cluster = sector, we need to read second part of our file
|
||||
; (bootsector loads only first cluster of kordldr.f1x)
|
||||
pop cx ax ; restore our position on disk
|
||||
cmp cx, 1
|
||||
ja kordldr_full
|
||||
sub ax, [bp-8]
|
||||
inc ax
|
||||
inc ax ; ax = first cluster of kordldr.f12
|
||||
call get_next_cluster
|
||||
jc @f
|
||||
j_noloader:
|
||||
jmp [noloader]
|
||||
@@:
|
||||
dec ax
|
||||
dec ax
|
||||
push 0x800
|
||||
pop es
|
||||
call [read_sectors2]
|
||||
kordldr_full:
|
||||
; ...continue loading...
|
||||
mov di, secondary_loader_info
|
||||
call load_file
|
||||
test bx, bx
|
||||
mov bx, [err_]
|
||||
jz @f
|
||||
mov si, aKernelNotFound
|
||||
jmp bx
|
||||
@@:
|
||||
; for subsequent calls to callback function, hook error handler
|
||||
; mov byte [bx], 0xE9 ; 'jmp' opcode
|
||||
; mov ax, hooked_err - 3
|
||||
; sub ax, bx
|
||||
; mov word [bx+1], ax
|
||||
; push hooked_err / ret
|
||||
mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8)
|
||||
mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8)
|
||||
; set registers for secondary loader
|
||||
mov ah, [BS_DrvNum]
|
||||
mov al, 'f'
|
||||
test ah, ah
|
||||
jns @f
|
||||
sub ah, 80h
|
||||
mov al, 'h'
|
||||
@@:
|
||||
mov bx, '12'
|
||||
cmp [fat_type], 0
|
||||
jz @f
|
||||
mov bh, '6'
|
||||
@@:
|
||||
mov si, callback ; ds:si = far pointer to callback procedure
|
||||
jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000
|
||||
|
||||
nomem_str db 'No memory',0
|
||||
|
||||
chs_proc_addresses:
|
||||
dw chs_read_sectors
|
||||
dw chs_read_sectors2
|
||||
dw chs_lookup_in_root_dir
|
||||
dw chs_scan_for_filename
|
||||
dw chs_err
|
||||
dw chs_noloader
|
||||
lba_proc_addresses:
|
||||
dw lba_read_sectors
|
||||
dw lba_read_sectors2
|
||||
dw lba_lookup_in_root_dir
|
||||
dw lba_scan_for_filename
|
||||
dw lba_err
|
||||
dw lba_noloader
|
||||
|
||||
get_next_cluster:
|
||||
; in: ax = cluster
|
||||
; out: if there is next cluster: CF=1, ax = next cluster
|
||||
; out: if there is no next cluster: CF=0
|
||||
push si
|
||||
cmp [fat_type], 0
|
||||
jnz gnc16
|
||||
; for FAT12
|
||||
push ds
|
||||
push 0x6000
|
||||
pop ds
|
||||
mov si, ax
|
||||
shr si, 1
|
||||
add si, ax
|
||||
test al, 1
|
||||
lodsw
|
||||
jz @f
|
||||
shr ax, 4
|
||||
@@:
|
||||
and ax, 0xFFF
|
||||
cmp ax, 0xFF7
|
||||
pop ds si
|
||||
ret
|
||||
; for FAT16
|
||||
gnc16:
|
||||
; each sector contains 200h bytes = 100h FAT entries
|
||||
; so ah = # of sector, al = offset in sector
|
||||
mov si, ax
|
||||
mov ah, 0
|
||||
shr si, 8
|
||||
; calculate segment for this sector of FAT table
|
||||
; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si)
|
||||
; segment = 6000 + 20*si, offset = 0
|
||||
push es
|
||||
push si
|
||||
shl si, 5
|
||||
add si, 0x6000
|
||||
mov es, si
|
||||
pop si
|
||||
cmp byte [ss:0x8200+si], ah ; sector already loaded?
|
||||
jnz @f
|
||||
; load corresponding sector
|
||||
pusha
|
||||
push es
|
||||
xor bx, bx
|
||||
mov ax, [BPB_RsvdSecCnt]
|
||||
xor dx, dx
|
||||
add ax, si
|
||||
adc dx, bx
|
||||
mov cx, 1 ; read 1 sector
|
||||
call [read_sectors]
|
||||
pop es
|
||||
popa
|
||||
@@:
|
||||
mov si, ax
|
||||
add si, si
|
||||
; mov ax, [es:si]
|
||||
lods word [es:si]
|
||||
pop es
|
||||
cmp ax, 0xFFF7
|
||||
pop si
|
||||
ret
|
||||
|
||||
if $ > 0x8000
|
||||
error 'get_next_cluster must fit in first sector of kordldr.f1x!'
|
||||
end if
|
||||
|
||||
load_file:
|
||||
; in: ss:bp = 0:7C00
|
||||
; in: ds:di -> information structure
|
||||
; dw:dw address
|
||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
||||
; ASCIIZ name
|
||||
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found
|
||||
; out: dx:ax = file size (0xFFFFFFFF if file not found)
|
||||
xor ax, ax ; start from root directory
|
||||
mov dx, -1
|
||||
mov word [filesize], dx
|
||||
mov word [filesize+2], dx ; initialize file size with invalid value
|
||||
lea si, [di+6]
|
||||
parse_dir_loop:
|
||||
; convert name to FAT name
|
||||
push di
|
||||
push ax
|
||||
push ss
|
||||
pop es
|
||||
; convert ASCIIZ filename to FAT name
|
||||
mov di, filename
|
||||
push di
|
||||
mov cx, 8+3
|
||||
mov al, ' '
|
||||
rep stosb
|
||||
pop di
|
||||
mov cl, 8 ; 8 symbols per name
|
||||
mov bl, 1
|
||||
nameloop:
|
||||
lodsb
|
||||
test al, al
|
||||
jz namedone
|
||||
cmp al, '/'
|
||||
jz namedone
|
||||
cmp al, '.'
|
||||
jz namedot
|
||||
dec cx
|
||||
js badname
|
||||
cmp al, 'a'
|
||||
jb @f
|
||||
cmp al, 'z'
|
||||
ja @f
|
||||
sub al, 'a'-'A'
|
||||
@@:
|
||||
stosb
|
||||
jmp nameloop
|
||||
namedot:
|
||||
inc bx
|
||||
jp badname
|
||||
add di, cx
|
||||
mov cl, 3
|
||||
jmp nameloop
|
||||
badname: ; do not make direct js/jp to notfound_pop:
|
||||
; this generates long forms of conditional jumps and results in longer code
|
||||
jmp notfound_pop
|
||||
namedone:
|
||||
; scan directory
|
||||
pop ax ; ax = cluster of directory or 0 for root
|
||||
push ds
|
||||
push si
|
||||
push es
|
||||
pop ds
|
||||
mov si, filename ; ds:si -> filename in FAT style
|
||||
test ax, ax
|
||||
jnz lookup_in_notroot_dir
|
||||
; for root directory, use the subroutine from bootsector
|
||||
call [lookup_in_root_dir]
|
||||
jmp lookup_done
|
||||
lookup_in_notroot_dir:
|
||||
; for other directories, read a folder sector-by-sector and scan
|
||||
; first, try to use the cache
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
mov bx, [cachelimit]
|
||||
add bx, bx
|
||||
mov di, foldcache_mark
|
||||
@@:
|
||||
mov dx, [foldcache_clus+di-foldcache_mark+bx]
|
||||
cmp dx, ax
|
||||
jz cacheok
|
||||
test dx, dx
|
||||
jz cacheadd ; the cache has place for new entry
|
||||
dec bx
|
||||
dec bx
|
||||
jns @b
|
||||
; the folder is not present in the cache, so add it
|
||||
; the cache is full; find the oldest entry and replace it with the new one
|
||||
mov dx, [cachelimit]
|
||||
@@:
|
||||
inc bx
|
||||
inc bx
|
||||
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
|
||||
jnz @b
|
||||
cacheadd:
|
||||
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
|
||||
mov [foldcache_clus+di-foldcache_mark+bx], ax
|
||||
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
|
||||
cacheok:
|
||||
; update cache marks
|
||||
mov dx, [di+bx]
|
||||
mov cx, [foldcache_size+di-foldcache_mark+bx]
|
||||
mov di, [cachelimit]
|
||||
add di, di
|
||||
cacheupdate:
|
||||
cmp [foldcache_mark+di], dx
|
||||
adc [foldcache_mark+di], 0
|
||||
dec di
|
||||
dec di
|
||||
jns cacheupdate
|
||||
and [foldcache_mark+bx], 0
|
||||
; done, bx contains (position in cache)*2
|
||||
pop ds
|
||||
; mov dx, bx
|
||||
; shl dx, 8 ; dx = (position in cache)*0x2000/0x10
|
||||
; add dx, 0x9200
|
||||
lea dx, [bx+0x92]
|
||||
xchg dl, dh
|
||||
mov es, dx
|
||||
jcxz not_in_cache
|
||||
call [scan_for_filename]
|
||||
jz lookup_done
|
||||
not_in_cache:
|
||||
; cache miss, read folder data from disk
|
||||
mov bx, cx
|
||||
shr bx, 4
|
||||
shl cx, 5
|
||||
mov di, cx ; es:di -> free space in cache entry
|
||||
; external loop: scan clusters
|
||||
folder_next_cluster:
|
||||
; internal loop: scan sectors in cluster
|
||||
mov cx, [sect_per_clus]
|
||||
push ax
|
||||
dec ax
|
||||
dec ax
|
||||
mul cx
|
||||
add ax, [bp-8]
|
||||
adc dx, [bp-6] ; dx:ax = absolute sector
|
||||
folder_next_sector:
|
||||
; skip first bx sectors
|
||||
dec bx
|
||||
jns folder_skip_sector
|
||||
push cx
|
||||
push es di
|
||||
push 0x8000
|
||||
pop es
|
||||
xor bx, bx
|
||||
mov cx, 1
|
||||
push es
|
||||
call [read_sectors]
|
||||
; copy data to the cache...
|
||||
pop ds
|
||||
pop di es
|
||||
cmp di, 0x2000 ; ...if there is free space, of course
|
||||
jae @f
|
||||
push si di
|
||||
mov cx, 0x100
|
||||
xor si, si
|
||||
rep movsw
|
||||
mov di, es
|
||||
shr di, 8
|
||||
add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache
|
||||
pop di si
|
||||
@@:
|
||||
push es
|
||||
push 0x8000
|
||||
pop es
|
||||
push cs
|
||||
pop ds
|
||||
mov cx, 0x10
|
||||
call [scan_for_filename]
|
||||
pop es
|
||||
pop cx
|
||||
jz lookup_done_pop
|
||||
folder_skip_sector:
|
||||
inc ax
|
||||
jnz @f
|
||||
inc dx
|
||||
@@:
|
||||
loop folder_next_sector
|
||||
pop ax ; ax = current cluster
|
||||
call get_next_cluster
|
||||
jc folder_next_cluster
|
||||
stc
|
||||
push ax
|
||||
lookup_done_pop:
|
||||
pop ax
|
||||
lookup_done:
|
||||
pop si
|
||||
pop ds
|
||||
; CF=1 <=> failed
|
||||
jnc found
|
||||
notfound:
|
||||
pop di
|
||||
mov bx, 2 ; file not found
|
||||
mov ax, 0xFFFF
|
||||
mov dx, ax ; invalid file size
|
||||
ret
|
||||
notfound_pop:
|
||||
pop ax
|
||||
jmp notfound
|
||||
found:
|
||||
mov ax, [es:di+26] ; get cluster
|
||||
test byte [es:di+11], 10h ; directory?
|
||||
jz regular_file
|
||||
cmp byte [si-1], 0
|
||||
jz notfound ; don't read directories as a regular files
|
||||
; ok, we have found a directory and the caller requested a file into it
|
||||
pop di
|
||||
jmp parse_dir_loop ; restart with new cluster in ax
|
||||
regular_file:
|
||||
cmp byte [si-1], 0
|
||||
jnz notfound ; file does not contain another files
|
||||
; ok, we have found a regular file and the caller requested it
|
||||
; save file size
|
||||
mov dx, [es:di+28]
|
||||
mov [filesize], dx
|
||||
mov dx, [es:di+30]
|
||||
mov [filesize+2], dx
|
||||
pop di
|
||||
mov si, [di+4]
|
||||
shl si, 3
|
||||
push si ; [ds:di+4] = limit in 4K blocks
|
||||
les bx, [di] ; es:bx -> buffer
|
||||
clusloop:
|
||||
; ax = first cluster, top of stack contains limit in sectors
|
||||
mov si, ax ; remember current cluster
|
||||
xor cx, cx ; cx will contain number of consecutive clusters
|
||||
mov word [cur_delta], cx
|
||||
mov word [cur_delta+2], cx
|
||||
mov di, ax
|
||||
clusfind:
|
||||
inc di
|
||||
inc cx
|
||||
call get_next_cluster
|
||||
jnc clusread
|
||||
cmp ax, di
|
||||
jz clusfind
|
||||
stc
|
||||
clusread:
|
||||
pop di ; limit in sectors
|
||||
push ax ; save next cluster
|
||||
pushf ; save flags
|
||||
; read cx clusters, starting from si
|
||||
; calculate number of sectors
|
||||
xchg ax, cx
|
||||
mul [sect_per_clus]
|
||||
; dx:ax = number of sectors; compare with limit
|
||||
mov word [num_sectors], ax
|
||||
mov word [num_sectors+2], dx
|
||||
jmp @f
|
||||
continue_load_file:
|
||||
les bx, [di] ; es:bx -> buffer
|
||||
mov di, [di+4] ; ds:di = limit in 4K blocks
|
||||
shl di, 3 ; now di = limit in sectors
|
||||
mov ax, word [num_sectors]
|
||||
mov dx, word [num_sectors+2]
|
||||
mov si, [cur_cluster]
|
||||
push [next_cluster]
|
||||
push [flags]
|
||||
or ax, dx
|
||||
jz nextclus
|
||||
@@:
|
||||
test dx, dx
|
||||
jnz clusdecrease
|
||||
push dx ; limit was not exceeded
|
||||
cmp ax, di
|
||||
jbe @f
|
||||
pop ax
|
||||
clusdecrease:
|
||||
push 1 ; limit was exceeded
|
||||
mov ax, di
|
||||
@@:
|
||||
sub di, ax ; calculate new limit
|
||||
sub word [num_sectors], ax
|
||||
sbb word [num_sectors+2], 0
|
||||
readloop:
|
||||
push ax
|
||||
; buffer should not cross a 64K boundary
|
||||
push bx
|
||||
shr bx, 4
|
||||
mov cx, es
|
||||
add bx, cx
|
||||
neg bx
|
||||
and bh, 0xF
|
||||
shr bx, 5
|
||||
jnz @f
|
||||
mov bl, 0x80
|
||||
@@:
|
||||
cmp ax, bx
|
||||
jbe @f
|
||||
xchg ax, bx
|
||||
@@:
|
||||
pop bx
|
||||
xchg ax, cx
|
||||
; calculate starting sector
|
||||
lea ax, [si-2]
|
||||
mul [sect_per_clus]
|
||||
add ax, word [cur_delta]
|
||||
adc dx, word [cur_delta+2]
|
||||
add word [cur_delta], cx
|
||||
adc word [cur_delta+2], 0
|
||||
; read
|
||||
call [read_sectors2]
|
||||
pop ax
|
||||
sub ax, cx
|
||||
jnz readloop
|
||||
pop dx
|
||||
; next cluster?
|
||||
nextclus:
|
||||
popf
|
||||
pop ax
|
||||
mov [cur_cluster], si
|
||||
mov [next_cluster], ax
|
||||
pushf
|
||||
pop [flags]
|
||||
jnc @f ; no next cluster => return
|
||||
mov dl, 1 ; dh=0 in any case
|
||||
test di, di
|
||||
jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded
|
||||
push di
|
||||
jmp clusloop ; all is ok, continue
|
||||
hooked_err:
|
||||
mov sp, 7C00h-12-2 ; restore stack
|
||||
mov dx, 3 ; return: read error
|
||||
@@:
|
||||
mov bx, dx
|
||||
mov ax, [filesize]
|
||||
mov dx, [filesize+2]
|
||||
ret
|
||||
|
||||
; Callback function for secondary loader
|
||||
callback:
|
||||
; in: ax = function number; only functions 1 and 2 are defined for now
|
||||
; save caller's stack
|
||||
mov dx, ss
|
||||
mov cx, sp
|
||||
; set our stack (required because we need ss=0)
|
||||
xor si, si
|
||||
mov ss, si
|
||||
mov sp, 7C00h-8
|
||||
mov bp, 7C00h
|
||||
push dx
|
||||
push cx
|
||||
; call our function
|
||||
stc ; unsupported function
|
||||
dec ax
|
||||
jz callback_readfile
|
||||
dec ax
|
||||
jnz callback_ret
|
||||
; function 2: continue loading file
|
||||
; can be called only after function 1 returned value bx=1 (only part of file was loaded)
|
||||
; in: ds:di -> information structure
|
||||
; dw:dw address
|
||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
||||
; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error
|
||||
; out: dx:ax = file size
|
||||
call continue_load_file
|
||||
jmp callback_ret_succ
|
||||
callback_readfile:
|
||||
; function 1: read file
|
||||
; in: ds:di -> information structure
|
||||
; dw:dw address
|
||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
||||
; ASCIIZ name
|
||||
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
|
||||
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
|
||||
call load_file
|
||||
callback_ret_succ:
|
||||
clc ; function is supported
|
||||
callback_ret:
|
||||
; restore caller's stack
|
||||
pop cx
|
||||
pop ss
|
||||
mov sp, cx
|
||||
; return to caller
|
||||
retf
|
||||
|
||||
secondary_loader_info:
|
||||
dw 0, 0x1000
|
||||
dw 0x30000 / 0x1000
|
||||
db 'kernel.mnt',0
|
||||
aKernelNotFound db 'Fatal error: cannot load the kernel',0
|
||||
|
||||
foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache
|
||||
foldcache_mark rw 7
|
||||
foldcache_size rw 7
|
||||
filename rb 11
|
||||
if $ > 0x8200
|
||||
error: table overwritten
|
||||
end if
|
358
kernel/branches/kolibri-cfg/bootloader/fat32/bootsect.asm
Normal file
358
kernel/branches/kolibri-cfg/bootloader/fat32/bootsect.asm
Normal file
@ -0,0 +1,358 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
use_lba = 0
|
||||
org 0x7C00
|
||||
jmp start
|
||||
nop
|
||||
; FAT parameters, BPB
|
||||
; they must be changed at install, replaced with real values
|
||||
rb 8 ; BS_OEMName, ignored
|
||||
dw 200h ; BPB_BytsPerSec
|
||||
BPB_SecsPerClus db ?
|
||||
BPB_RsvdSecCnt dw ?
|
||||
BPB_NumFATs db ?
|
||||
BPB_RootEntCnt dw ?
|
||||
dw ? ; BPB_TotSec16
|
||||
db ? ; BPB_Media
|
||||
dw ? ; BPB_FATSz16 = 0 for FAT32
|
||||
BPB_SecPerTrk dw ?
|
||||
BPB_NumHeads dw ?
|
||||
BPB_HiddSec dd ?
|
||||
dd ? ; BPB_TotSec32
|
||||
BPB_FATSz32 dd ?
|
||||
BPB_ExtFlags dw ?
|
||||
dw ? ; BPB_FSVer
|
||||
BPB_RootClus dd ?
|
||||
dw ? ; BPB_FSInfo
|
||||
BPB_BkBootSec dw ?
|
||||
rb 12 ; BPB_Reserved
|
||||
BS_DrvNum db ?
|
||||
db ? ; BS_Reserved1
|
||||
db ? ; BS_BootSig
|
||||
dd ? ; BS_VolID
|
||||
rb 11 ; BS_VolLab
|
||||
rb 8 ;
|
||||
|
||||
curseg dw 0x8000
|
||||
|
||||
start:
|
||||
xor ax, ax
|
||||
mov ss, ax
|
||||
mov sp, 0x7C00
|
||||
mov ds, ax
|
||||
mov bp, sp
|
||||
cld
|
||||
sti
|
||||
push dx ; byte [bp-2] = boot drive
|
||||
if use_lba
|
||||
mov ah, 41h
|
||||
mov bx, 55AAh
|
||||
int 13h
|
||||
mov si, aNoLBA
|
||||
jc err_
|
||||
cmp bx, 0AA55h
|
||||
jnz err_
|
||||
test cl, 1
|
||||
jz err_
|
||||
else
|
||||
mov ah, 8
|
||||
int 13h
|
||||
jc @f
|
||||
movzx ax, dh
|
||||
inc ax
|
||||
mov [bp+BPB_NumHeads-0x7C00], ax
|
||||
and cx, 3Fh
|
||||
mov [bp+BPB_SecPerTrk-0x7C00], cx
|
||||
@@:
|
||||
end if
|
||||
; get FAT parameters
|
||||
xor bx, bx
|
||||
movzx eax, [bp+BPB_NumFATs-0x7C00]
|
||||
mul [bp+BPB_FATSz32-0x7C00]
|
||||
movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00]
|
||||
push ecx ; FAT start = dword [bp-6]
|
||||
add eax, ecx
|
||||
push eax ; data start = dword [bp-10]
|
||||
;push dword -1 ; dword [bp-14] = current sector for FAT cache
|
||||
db 66h
|
||||
push -1 ; dword [bp-14] = current sector for FAT cache
|
||||
mov eax, [bp+BPB_RootClus-0x7C00]
|
||||
mov si, main_loader
|
||||
call lookup_in_dir
|
||||
jnc kordldr_ok
|
||||
noloader:
|
||||
mov si, aLoaderNotFound
|
||||
err_:
|
||||
call out_string
|
||||
mov si, aPressAnyKey
|
||||
call out_string
|
||||
xor ax, ax
|
||||
int 16h
|
||||
int 18h
|
||||
jmp $
|
||||
kordldr_ok:
|
||||
mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster)
|
||||
mov ax, [es:di+26] ; loword(eax) = loword(cluster)
|
||||
mov es, bx ; es = 0
|
||||
mov bx, 0x7E00
|
||||
push bx ; save return address: bx = 7E00
|
||||
; fall through - 'ret' in read_cluster will return to 7E00
|
||||
|
||||
read_cluster:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; eax = cluster
|
||||
sub eax, 2
|
||||
movzx ecx, [bp+BPB_SecsPerClus-0x7C00]
|
||||
mul ecx
|
||||
|
||||
read_sectors2:
|
||||
; same as read_sectors32, but eax is relative to start of data
|
||||
add eax, [bp-10]
|
||||
read_sectors32:
|
||||
; ss:bp = 0:7C00
|
||||
; es:bx = pointer to data
|
||||
; eax = first sector
|
||||
; cx = number of sectors
|
||||
; some high words of 32-bit registers are destroyed!
|
||||
pusha
|
||||
add eax, [bp+BPB_HiddSec-0x7C00]
|
||||
if use_lba
|
||||
push ds
|
||||
do_read_sectors:
|
||||
push ax
|
||||
push cx
|
||||
cmp cx, 0x7F
|
||||
jbe @f
|
||||
mov cx, 0x7F
|
||||
@@:
|
||||
; create disk address packet on the stack
|
||||
; dq starting LBA
|
||||
push 0
|
||||
push 0
|
||||
push eax
|
||||
; dd buffer
|
||||
push es
|
||||
push bx
|
||||
; dw number of blocks to transfer (no more than 0x7F)
|
||||
push cx
|
||||
; dw packet size in bytes
|
||||
push 10h
|
||||
; issue BIOS call
|
||||
push ss
|
||||
pop ds
|
||||
mov si, sp
|
||||
mov dl, [bp-2]
|
||||
mov ah, 42h
|
||||
int 13h
|
||||
mov si, aReadError
|
||||
jc err_
|
||||
; restore stack
|
||||
add sp, 10h
|
||||
; increase current sector & buffer; decrease number of sectors
|
||||
movzx esi, cx
|
||||
mov ax, es
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
pop cx
|
||||
pop ax
|
||||
add eax, esi
|
||||
sub cx, si
|
||||
jnz do_read_sectors
|
||||
pop ds
|
||||
popa
|
||||
ret
|
||||
else
|
||||
do_read_sectors:
|
||||
pusha
|
||||
pop edi ; loword(edi) = di, hiword(edi) = si
|
||||
push bx
|
||||
|
||||
; eax / (SectorsPerTrack) -> eax, remainder bx
|
||||
movzx esi, [bp+BPB_SecPerTrk-0x7C00]
|
||||
xor edx, edx
|
||||
div esi
|
||||
mov bx, dx ; bx=sector-1
|
||||
|
||||
; eax -> dx:ax
|
||||
push eax
|
||||
pop ax
|
||||
pop dx
|
||||
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
|
||||
div [bp+BPB_NumHeads-0x7C00]
|
||||
|
||||
; number of sectors: read no more than to end of track
|
||||
sub si, bx
|
||||
cmp cx, si
|
||||
jbe @f
|
||||
mov cx, si
|
||||
@@:
|
||||
|
||||
inc bx
|
||||
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
|
||||
movzx edi, cx
|
||||
mov dh, dl
|
||||
mov dl, [bp-2]
|
||||
shl ah, 6
|
||||
mov ch, al
|
||||
mov al, cl
|
||||
mov cl, bl
|
||||
or cl, ah
|
||||
pop bx
|
||||
mov si, 3
|
||||
mov ah, 2
|
||||
@@:
|
||||
push ax
|
||||
int 13h
|
||||
jnc @f
|
||||
xor ax, ax
|
||||
int 13h ; reset drive
|
||||
pop ax
|
||||
dec si
|
||||
jnz @b
|
||||
mov si, aReadError
|
||||
jmp err_
|
||||
@@:
|
||||
pop ax
|
||||
mov ax, es
|
||||
mov cx, di
|
||||
shl cx, 5
|
||||
add ax, cx
|
||||
mov es, ax
|
||||
push edi
|
||||
popa
|
||||
add eax, edi
|
||||
sub cx, di
|
||||
jnz do_read_sectors
|
||||
popa
|
||||
ret
|
||||
end if
|
||||
|
||||
lookup_in_dir:
|
||||
; in: ds:si -> 11-bytes FAT name
|
||||
; in: eax = cluster
|
||||
; in: bx = 0
|
||||
; out: if found: CF=0, es:di -> directory entry
|
||||
; out: if not found: CF=1
|
||||
; push 0x8000
|
||||
; pop es
|
||||
; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000
|
||||
mov es, [bp-7C00h + curseg]
|
||||
push es
|
||||
push eax
|
||||
call read_cluster
|
||||
mov ax, es
|
||||
cmp ah, 82h
|
||||
jb @f
|
||||
mov ax, 8200h
|
||||
@@:
|
||||
mov [bp-7C00h + curseg], ax
|
||||
pop eax
|
||||
pop es
|
||||
; scan for filename
|
||||
shl cx, 4
|
||||
xor di, di
|
||||
sloop:
|
||||
cmp byte [es:di], bl
|
||||
jz snotfound
|
||||
test byte [es:di+11], 8 ; volume label?
|
||||
jnz scont ; ignore volume labels
|
||||
pusha
|
||||
mov cx, 11
|
||||
repz cmpsb
|
||||
popa
|
||||
jz sdone
|
||||
scont:
|
||||
add di, 0x20
|
||||
loop sloop
|
||||
; next cluster
|
||||
push 0x6000
|
||||
pop es
|
||||
push es ax
|
||||
shr eax, 7
|
||||
cmp eax, [bp-14]
|
||||
mov [bp-14], eax
|
||||
jz @f
|
||||
add eax, [bp-6]
|
||||
mov cx, 1
|
||||
call read_sectors32
|
||||
@@:
|
||||
pop di es
|
||||
and di, 0x7F
|
||||
shl di, 2
|
||||
and byte [es:di+3], 0x0F
|
||||
mov eax, [es:di]
|
||||
;and eax, 0x0FFFFFFF
|
||||
cmp eax, 0x0FFFFFF7
|
||||
jb lookup_in_dir
|
||||
snotfound:
|
||||
stc
|
||||
sdone:
|
||||
ret
|
||||
|
||||
out_string:
|
||||
; in: ds:si -> ASCIIZ string
|
||||
lodsb
|
||||
test al, al
|
||||
jz sdone
|
||||
mov ah, 0Eh
|
||||
mov bx, 7
|
||||
int 10h
|
||||
jmp out_string
|
||||
|
||||
aReadError db 'Read error',0
|
||||
if use_lba
|
||||
aNoLBA db 'The drive does not support LBA!',0
|
||||
end if
|
||||
aLoaderNotFound db 'Loader not found',0
|
||||
aPressAnyKey db 13,10,'Press any key...',13,10,0
|
||||
main_loader db 'KORDLDR F32'
|
||||
|
||||
db 56h
|
||||
; just to make file 512 bytes long :)
|
||||
db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
|
||||
|
||||
; bootsector signature
|
||||
dw 0xAA55
|
||||
|
||||
; display offsets of all procedures used by kordldr.f12.asm
|
||||
macro show [procedure]
|
||||
{
|
||||
bits = 16
|
||||
display `procedure,' = '
|
||||
repeat bits/4
|
||||
d = '0' + procedure shr (bits - %*4) and 0Fh
|
||||
if d > '9'
|
||||
d = d + 'A'-'9'-1
|
||||
end if
|
||||
display d
|
||||
end repeat
|
||||
display 13,10
|
||||
}
|
||||
|
||||
show read_sectors32, read_sectors2, err_, noloader
|
333
kernel/branches/kolibri-cfg/bootloader/fat32/bootsect.txt
Normal file
333
kernel/branches/kolibri-cfg/bootloader/fat32/bootsect.txt
Normal file
@ -0,0 +1,333 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
Читай между строк - там никогда не бывает опечаток.
|
||||
|
||||
Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Есть две версии в зависимости от того, поддерживает ли носитель LBA,
|
||||
выбор осуществляется установкой константы use_lba в первой строке исходника.
|
||||
Требования для работы:
|
||||
1) Сам бутсектор, первая копия FAT и все используемые файлы
|
||||
должны быть читабельны. (Если дело происходит на носителе с разбиением на
|
||||
разделы и загрузочный код в MBR достаточно умный, то читабельности резервной
|
||||
копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности
|
||||
самого бутсектора).
|
||||
2) Минимальный процессор - 80386.
|
||||
3) В системе должно быть как минимум 584K свободной базовой памяти.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Документация в тему (ссылки проверялись на валидность 15.05.2008):
|
||||
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
||||
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
|
||||
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip
|
||||
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
|
||||
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
|
||||
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
|
||||
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
|
||||
|
||||
=====================================================================
|
||||
|
||||
Схема используемой памяти:
|
||||
...-7C00 стек
|
||||
7C00-7E00 код бутсектора
|
||||
7E00-8200 вспомогательный файл загрузчика (kordldr.f32)
|
||||
8400-8C00 информация о кэше для таблицы FAT: 100h входов по 8
|
||||
байт: 4 байта (две ссылки - вперёд и назад) для
|
||||
организации L2-списка всех прочитанных секторов в
|
||||
порядке возрастания последнего времени использования
|
||||
+ 4 байта для номера сектора; при переполнении кэша
|
||||
выкидывается элемент из головы списка, то есть тот,
|
||||
к которому дольше всех не было обращений
|
||||
60000-80000 кэш для таблицы FAT (100h секторов)
|
||||
80000-90000 текущий кластер текущей рассматриваемой папки
|
||||
90000-... кэш для содержимого папок (каждой папке отводится
|
||||
2000h байт = 100h входов, одновременно в кэше
|
||||
может находиться не более 8 папок;
|
||||
точный размер определяется размером доступной
|
||||
физической памяти - как правило, непосредственно
|
||||
перед A0000 размещается EBDA, Extended BIOS Data Area)
|
||||
|
||||
=====================================================================
|
||||
|
||||
Основной процесс загрузки.
|
||||
Точка входа (start): получает управление от BIOS при загрузке, при этом
|
||||
dl содержит идентификатор диска, с которого идёт загрузка
|
||||
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед
|
||||
кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало
|
||||
бутсектора (в дальнейшем данные будут адресоваться через [bp+N] -
|
||||
это освобождает ds и экономит на размере кода). Сохраняет в стеке
|
||||
идентификатор загрузочного диска для последующего обращения
|
||||
через byte [bp-2].
|
||||
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h
|
||||
прерывания 13h. Если нет, переходит на код обработки ошибок с
|
||||
сообщением об отсутствии LBA.
|
||||
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и
|
||||
записывает полученные данные поверх BPB. Если вызов завершился ошибкой,
|
||||
предполагает уже существующие данные корректными.
|
||||
3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего
|
||||
обращения через dword [bp-10]. В процессе вычисления узнаёт начало
|
||||
первой FAT, сохраняет и его в стек для последующего обращения через
|
||||
dword [bp-6].
|
||||
4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1
|
||||
для последующего обращения через dword [bp-14] - инициализация
|
||||
переменной, содержащей текущий сектор, находящийся в кэше FAT
|
||||
(-1 не является валидным значением для номера сектора FAT).
|
||||
5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на
|
||||
код обработки ошибок с сообщением о ненайденном загрузчике.
|
||||
Замечание: на этом этапе загрузки искать можно только в корневой
|
||||
папке и только имена, заданные в формате файловой системе FAT
|
||||
(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны
|
||||
быть заглавными, при необходимости имя и расширение дополняются
|
||||
пробелами, разделяющей точки нет, завершающего нуля нет).
|
||||
6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт
|
||||
ему управление. При этом в регистре eax оказывается абсолютный
|
||||
номер первого сектора kordldr.f32, а в cx - число считанных секторов
|
||||
(равное размеру кластера).
|
||||
|
||||
Вспомогательные процедуры бутсектора.
|
||||
Код обработки ошибок (err):
|
||||
1. Выводит строку с сообщением об ошибке.
|
||||
2. Выводит строку "Press any key...".
|
||||
3. Ждёт нажатия any key.
|
||||
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё.
|
||||
5. Для подстраховки зацикливается.
|
||||
|
||||
Процедура чтения кластера (read_cluster):
|
||||
на входе должно быть установлено:
|
||||
ss:bp = 0:7C00
|
||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
||||
eax = номер кластера
|
||||
на выходе: ecx = число прочитанных секторов (размер кластера),
|
||||
es:bx указывает на конец буфера, в который были прочитаны данные,
|
||||
eax и старшие слова других 32-битных регистров разрушаются
|
||||
Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора
|
||||
и переходит к следующей процедуре.
|
||||
|
||||
Процедура чтения секторов (read_sectors32 и read_sectors2):
|
||||
на входе должно быть установлено:
|
||||
ss:bp = 0:7C00
|
||||
es:bx = указатель на начало буфера, куда будут прочитаны данные
|
||||
eax = стартовый сектор (относительно начала логического диска
|
||||
для read_sectors32, относительно начала данных
|
||||
для read_sectors2)
|
||||
cx = число секторов (должно быть больше нуля)
|
||||
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные
|
||||
старшие слова 32-битных регистров могут разрушиться
|
||||
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора
|
||||
в номер относительно начала логического диска, прибавляя номер сектора
|
||||
начала данных, хранящийся в стеке как [bp-10].
|
||||
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на
|
||||
устройстве, прибавляя значение соответствующего поля из BPB.
|
||||
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации
|
||||
CHS-версия: все читаемые секторы были на одной дорожке.
|
||||
LBA-версия: число читаемых секторов не превосходило 7Fh (требование
|
||||
спецификации EDD BIOS).
|
||||
CHS-версия:
|
||||
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как
|
||||
единица плюс остаток от деления абсолютного номера на число секторов
|
||||
на дорожке; дорожка рассчитывается как остаток от деления частного,
|
||||
полученного на предыдущем шаге, на число дорожек, а цилиндр - как
|
||||
частное от этого же деления. Если число секторов для чтения больше,
|
||||
чем число секторов до конца дорожки, уменьшает число секторов для
|
||||
чтения.
|
||||
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов,
|
||||
dh=головка, (младшие 6 бит cl)=сектор,
|
||||
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер).
|
||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска
|
||||
и повторяет попытку чтения, всего делается не более трёх попыток
|
||||
(несколько попыток нужно в случае дискеты для гарантии того, что
|
||||
мотор раскрутился). Если все три раза происходит ошибка чтения,
|
||||
переходит на код обработки ошибок с сообщением "Read error".
|
||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
||||
работу, иначе возвращается на шаг 3.
|
||||
LBA-версия:
|
||||
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей
|
||||
итерации) до 7Fh.
|
||||
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами
|
||||
push, причём в обратном порядке: стек - структура LIFO, и данные в
|
||||
стеке хранятся в обратном порядке по отношению к тому, как их туда
|
||||
клали).
|
||||
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки
|
||||
ошибок с сообщением "Read error". Очищает стек от пакета,
|
||||
сформированного на предыдущем шаге.
|
||||
6. В соответствии с числом прочитанных на текущей итерации секторов
|
||||
корректирует текущий сектор, число оставшихся секторов и указатель на
|
||||
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает
|
||||
работу, иначе возвращается на шаг 3.
|
||||
|
||||
Процедура поиска элемента в папке (lookup_in_dir):
|
||||
на входе должно быть установлено:
|
||||
ss:bp = 0:7C00
|
||||
ds:si = указатель на имя файла в формате FAT (см. выше)
|
||||
eax = начальный кластер папки
|
||||
bx = 0
|
||||
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то
|
||||
CF сброшен и es:di указывает на элемент папки
|
||||
В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных
|
||||
данных. Для чтения кластера использует уже описанную процедуру read_clusters,
|
||||
для продвижения по цепочке кластеров - описанную далее процедуру
|
||||
get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса
|
||||
8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше,
|
||||
если чтение прервётся раньше) не перекрываются последующими чтениями
|
||||
(это будет использовано позднее, в системе кэширования из kordldr.f32).
|
||||
Выход осуществляется в любом из следующих случаев: найден запрошенный элемент;
|
||||
кончились элементы в папке (первый байт очередного элемента нулевой);
|
||||
кончились данные папки в соответствии с цепочкой кластеров из FAT.
|
||||
|
||||
Процедура вывода на экран ASCIIZ-строки (out_string):
|
||||
на входе: ds:si -> строка
|
||||
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Работа вспомогательного загрузчика kordldr.f32:
|
||||
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора.
|
||||
В зависимости от этого устанавливает смещения используемых процедур
|
||||
бутсектора. Критерий проверки: в CHS-версии по адресу err находится
|
||||
байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу
|
||||
находится байт 0x14, а адрес процедуры err другой.
|
||||
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска
|
||||
адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с
|
||||
ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента
|
||||
место должно быть, отсюда ограничение в 592 Kb (94000h байт).
|
||||
Замечание: этот размер не может превосходить 0A0000h байт и
|
||||
на практике оказывается немного (на 1-2 килобайта) меньшим из-за
|
||||
наличия дополнительной области данных BIOS "вверху" базовой памяти.
|
||||
3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть
|
||||
данных корневой папки; копирует загруженные данные в кэш и запоминает,
|
||||
что в кэше есть корневая папка.
|
||||
4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только
|
||||
том случае, когда ему приходится загружать данные корневой папки,
|
||||
не поместившиеся в один кластер. В этом случае в памяти присутствует
|
||||
один сектор FAT (если было несколько обращений - последний из
|
||||
использованных).
|
||||
5. Если кластер равен сектору, то бутсектор загрузил только часть файла
|
||||
kordldr.f32, и загрузчик подгружает вторую свою часть, используя
|
||||
значения регистров на входе в kordldr.f32.
|
||||
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не
|
||||
найден, или оказался папкой, или оказался слишком большим, то переходит
|
||||
на код обработки ошибок из бутсектора с сообщением
|
||||
"Fatal error: cannot load the secondary loader".
|
||||
Замечание: на этом этапе имя файла уже можно указывать вместе с путём
|
||||
и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов
|
||||
по-прежнему нет.
|
||||
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err.
|
||||
Это нужно, чтобы последующие обращения к коду бутсектора в случае
|
||||
ошибок чтения не выводил соответствующее сообщение с последующей
|
||||
перезагрузкой, а рапортовал об ошибке чтения, которую могло бы
|
||||
как-нибудь обработать ядро.
|
||||
8. Если загрузочный диск имеет идентификатор меньше 0x80,
|
||||
то устанавливает al='f' ("floppy"), ah=идентификатор диска,
|
||||
иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска).
|
||||
(Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но
|
||||
уверены ли Вы, что нет загрузочных устройств, подобных дискетам,
|
||||
но большего размера, и для которых BIOS-идентификатор меньше 0x80?)
|
||||
Устанавливает bx='32' (тип файловой системы - FAT32).
|
||||
Устанавливает si=смещение функции обратного вызова. Поскольку в этот
|
||||
момент ds=0, то ds:si образуют полный адрес.
|
||||
9. Передаёт управление по адресу 1000:0000.
|
||||
|
||||
Функция обратного вызова для вторичного загрузчика:
|
||||
предоставляет возможность чтения файла.
|
||||
Вход и выход описаны в спецификации на загрузчик.
|
||||
1. Сохраняет стек вызывающего кода и устанавливает свой стек:
|
||||
ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным
|
||||
кодом должна указывать на 0:7C00, а -10 берётся от того, что
|
||||
инициализирующий код бутсектора уже поместил в стек 10 байт параметров,
|
||||
и они должны сохраняться в неизменности. (Значение [ebp-14],
|
||||
"текущий сектор, находящийся в кэше FAT", не используется после
|
||||
инициализации кэширования в kordldr.f32.)
|
||||
2. Разбирает переданные параметры и вызывает нужную из вспомогательных
|
||||
процедур (загрузки файла либо продолжения загрузки файла).
|
||||
3. Восстанавливает стек вызывающего кода и возвращает управление.
|
||||
|
||||
Вспомогательные процедуры kordldr.f32.
|
||||
Процедура получения следующего кластера в FAT (get_next_cluster):
|
||||
1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент.
|
||||
(В секторе 0x200 байт, каждый вход занимает 4 байта.)
|
||||
2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4.
|
||||
3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен,
|
||||
выделяет очередной элемент в конце кэша. Если заполнен, удаляет
|
||||
самый старый элемент (тот, к которому дольше всего не было обращений);
|
||||
для того, чтобы отслеживать порядок элементов по времени последнего
|
||||
обращения, все (выделенные) элементы кэша связаны в двусвязный список,
|
||||
в котором первым элементом является самый старый, а ссылки вперёд
|
||||
указывают на следующий по времени последнего обращения.
|
||||
4. Читает соответствующий сектор FAT с диска.
|
||||
5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции,
|
||||
где он находится, и добавляется в конец. (В случае со свежедобавленными
|
||||
в кэш элементами удаления не делается, поскольку их в списке ещё нет.)
|
||||
6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита.
|
||||
7. Сравнивает прочитанное значение с пределом: если оно строго меньше
|
||||
0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке;
|
||||
в противном случае цепочка закончилась.
|
||||
|
||||
Процедура загрузки файла (load_file):
|
||||
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4.
|
||||
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты
|
||||
разделяются символом '/') в FAT-формат 8+3. Если это невозможно
|
||||
(больше 8 символов в имени, больше 3 символов в расширении или
|
||||
больше одной точки), возвращается с ошибкой.
|
||||
3. Ищет элемент с таким именем в текущей рассматриваемой папке.
|
||||
а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок
|
||||
осуществляется по номеру начального кластера.) Если такой папки ещё
|
||||
нет, добавляет её в кэш; если тот переполняется, выкидывает папку,
|
||||
к которой дольше всего не было обращений. (Для каждого элемента кэша
|
||||
хранится метка от 0 до (размер кэша)-1, определяющая его номер при
|
||||
сортировке по давности последнего обращения. При обращении к какому-то
|
||||
элементу его метка становится нулевой, а те метки, которые меньше
|
||||
старого значения, увеличиваются на единицу.)
|
||||
б) Просматривает в поисках запрошенного имени все элементы из кэша,
|
||||
используя процедуру из бутсектора. Если обнаруживает искомый элемент,
|
||||
переходит к шагу 4. Если обнаруживает конец папки, возвращается из
|
||||
процедуры с ошибкой.
|
||||
в) В цикле считывает папку посекторно. При этом пропускает начальные
|
||||
секторы, которые уже находятся в кэше и уже были просмотрены. Каждый
|
||||
прочитанный сектор копирует в кэш, если там ещё остаётся место,
|
||||
и просматривает в нём все элементы. Работает, пока не случится одно из
|
||||
трёх событий: найден искомый элемент; кончились кластеры (судя по
|
||||
цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце
|
||||
(первый байт нулевой). В двух последних случаях возвращается с ошибкой.
|
||||
4. Проверяет тип найденного элемента (файл/папка): последний элемент в
|
||||
запрошенном имени должен быть файлом, все промежуточные - папками.
|
||||
Если текущий компонент имени - промежуточный, продвигает текущую
|
||||
рассматриваемую папку и возвращается к пункту 2.
|
||||
5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный
|
||||
при вызове буфер последовательными вызовами функции бутсектора;
|
||||
при этом если несколько кластеров файла расположены на диске
|
||||
последовательно, то их чтение объединяется в одну операцию.
|
||||
Следит за тем, чтобы не превысить указанный при вызове процедуры
|
||||
лимит числа секторов для чтения.
|
||||
|
||||
Процедура продолжения загрузки файла (continue_load_file): встроена
|
||||
внутрь шага 5 load_file; загружает в регистры нужные значения (ранее
|
||||
сохранённые из load_file) и продолжает шаг 5.
|
3
kernel/branches/kolibri-cfg/bootloader/fat32/build.bat
Normal file
3
kernel/branches/kolibri-cfg/bootloader/fat32/build.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@fasm -m 65535 bootsect.asm bootsect.bin
|
||||
@fasm -m 65535 kordldr.f32.asm kordldr.f32
|
||||
@pause
|
672
kernel/branches/kolibri-cfg/bootloader/fat32/kordldr.f32.asm
Normal file
672
kernel/branches/kolibri-cfg/bootloader/fat32/kordldr.f32.asm
Normal file
@ -0,0 +1,672 @@
|
||||
; Copyright (c) 2008-2009, diamond
|
||||
; All rights reserved.
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; * Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; * Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; * Neither the name of the <organization> nor the
|
||||
; names of its contributors may be used to endorse or promote products
|
||||
; derived from this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
|
||||
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*****************************************************************************
|
||||
|
||||
org 0x7E00
|
||||
; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here
|
||||
; ss:bp = 0:7C00
|
||||
; ds = 0
|
||||
virtual at bp
|
||||
rb 3 ; BS_jmpBoot
|
||||
rb 8 ; BS_OEMName, ignored
|
||||
dw ? ; BPB_BytsPerSec
|
||||
BPB_SecsPerClus db ?
|
||||
BPB_RsvdSecCnt dw ?
|
||||
BPB_NumFATs db ?
|
||||
BPB_RootEntCnt dw ?
|
||||
dw ? ; BPB_TotSec16
|
||||
db ? ; BPB_Media
|
||||
dw ? ; BPB_FATSz16 = 0 for FAT32
|
||||
BPB_SecPerTrk dw ?
|
||||
BPB_NumHeads dw ?
|
||||
BPB_HiddSec dd ?
|
||||
dd ? ; BPB_TotSec32
|
||||
BPB_FATSz32 dd ?
|
||||
BPB_ExtFlags dw ?
|
||||
dw ? ; BPB_FSVer
|
||||
BPB_RootClus dd ?
|
||||
filesize:
|
||||
dw ? ; BPB_FSInfo
|
||||
dw ? ; BPB_BkBootSec
|
||||
rb 12 ; BPB_Reserved
|
||||
BS_DrvNum db ?
|
||||
db ? ; BS_Reserved1
|
||||
db ? ; BS_BootSig
|
||||
dd ? ; BS_VolID
|
||||
; rb 11 ; BS_VolLab
|
||||
; rb 5 ; BS_FilSysType, first 5 bytes
|
||||
read_sectors32 dw ?
|
||||
read_sectors2 dw ?
|
||||
err_ dw ?
|
||||
noloader dw ?
|
||||
cachelimit dw ?
|
||||
fatcachehead rw 2
|
||||
fatcacheend dw ?
|
||||
rb 3 ; BS_FilSysType, last 3 bytes
|
||||
curseg dw ?
|
||||
num_sectors dd ?
|
||||
cur_cluster dd ?
|
||||
next_cluster dd ?
|
||||
flags dw ?
|
||||
cur_delta dd ?
|
||||
end virtual
|
||||
|
||||
; procedures from boot sector
|
||||
; LBA version
|
||||
lba_read_sectors2 = 7CD6h
|
||||
lba_err = 7CAAh
|
||||
lba_noloader = 7CA7h ; = lba_err - 3
|
||||
; CHS version
|
||||
chs_read_sectors2 = 7CD2h
|
||||
chs_err = 7CA6h
|
||||
chs_noloader = 7CA3h ; = chs_err - 3
|
||||
|
||||
push eax cx ; save our position on disk
|
||||
; determine version of bootsector (LBA vs CHS)
|
||||
mov [read_sectors2], chs_read_sectors2
|
||||
mov bx, chs_err
|
||||
mov [err_], bx
|
||||
; mov [noloader], chs_noloader
|
||||
cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version
|
||||
jz @f
|
||||
add [read_sectors2], lba_read_sectors2 - chs_read_sectors2
|
||||
add [err_], lba_err - chs_err
|
||||
; mov [noloader], lba_noloader
|
||||
@@:
|
||||
xor bx, bx
|
||||
; determine size of cache for folders
|
||||
int 12h ; ax = size of available base memory in Kb
|
||||
sub ax, 92000h / 1024
|
||||
jae @f
|
||||
nomem:
|
||||
mov si, nomem_str
|
||||
jmp [err_]
|
||||
@@:
|
||||
shr ax, 3
|
||||
mov [cachelimit], ax ; size of cache - 1
|
||||
mov es, bx
|
||||
; no folders in cache yet
|
||||
mov di, foldcache_clus
|
||||
mov cx, 8*4/2 + 1
|
||||
xor ax, ax
|
||||
rep stosw
|
||||
; bootsector code caches one FAT sector, [bp-14], in 6000:0000
|
||||
; initialize our (more advanced) FAT caching from this
|
||||
mov di, 8400h
|
||||
mov cx, di
|
||||
lea si, [fatcachehead]
|
||||
mov [si], si ; no sectors in cache:
|
||||
mov [si+2], si ; 'prev' & 'next' links point to self
|
||||
mov [fatcacheend], di ; first free item = 8400h
|
||||
stosw ; 'next cached sector' link
|
||||
stosw ; 'prev cached sector' link
|
||||
mov eax, [bp-14]
|
||||
stosd ; first sector number in cache
|
||||
test eax, eax
|
||||
js @f
|
||||
mov [si], cx ; 'first cached sector' link = 8400h
|
||||
mov [si+2], cx ; 'next cached sector' link = 8400h
|
||||
mov [fatcacheend], di ; first free item = 8406h
|
||||
@@:
|
||||
; if cluster = sector, we need to read second part of our file
|
||||
; (bootsector loads only first cluster of kordldr.f32)
|
||||
pop cx eax ; restore our position on disk
|
||||
cmp cx, 1
|
||||
ja kordldr_full
|
||||
sub eax, [bp-10]
|
||||
inc eax
|
||||
inc eax ; eax = first cluster of kordldr.f32
|
||||
call get_next_cluster
|
||||
jc @f
|
||||
; jmp [noloader]
|
||||
mov ax, [err_]
|
||||
sub ax, 3
|
||||
jmp ax
|
||||
@@:
|
||||
dec eax
|
||||
dec eax
|
||||
push 0x800
|
||||
pop es
|
||||
call [read_sectors2]
|
||||
kordldr_full:
|
||||
; bootsector code has read some data of root directory to 8000:0000
|
||||
; initialize our folder caching from this
|
||||
mov eax, [BPB_RootClus]
|
||||
mov [foldcache_clus], eax
|
||||
mov cx, [curseg]
|
||||
mov ax, 8000h
|
||||
sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes)
|
||||
shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes)
|
||||
mov [foldcache_size], cx
|
||||
shl cx, 4
|
||||
push ds
|
||||
mov ds, ax
|
||||
push 0x9000
|
||||
pop es
|
||||
xor si, si
|
||||
xor di, di
|
||||
rep movsw
|
||||
pop ds
|
||||
; ...continue loading...
|
||||
mov di, secondary_loader_info
|
||||
call load_file
|
||||
test bx, bx
|
||||
mov bx, [err_]
|
||||
jz @f
|
||||
mov si, aKernelNotFound
|
||||
jmp bx
|
||||
@@:
|
||||
; for subsequent calls to callback function, hook error handler
|
||||
; push hooked_err / ret
|
||||
mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24)
|
||||
; set registers for secondary loader
|
||||
mov ah, [bp-2] ; drive id
|
||||
mov al, 'f'
|
||||
btr ax, 15
|
||||
jnc @f
|
||||
mov al, 'h'
|
||||
@@:
|
||||
mov bx, '32'
|
||||
mov si, callback
|
||||
jmp far [si+secondary_loader_info-callback]
|
||||
|
||||
nomem_str db 'No memory',0
|
||||
|
||||
cluster2sector:
|
||||
sub eax, 2
|
||||
clustersz2sectorsz:
|
||||
movzx ecx, [BPB_SecsPerClus]
|
||||
mul ecx
|
||||
ret
|
||||
|
||||
get_next_cluster:
|
||||
; in: eax = cluster
|
||||
; out: if there is next cluster: CF=1, eax = next cluster
|
||||
; out: if there is no next cluster: CF=0
|
||||
push di bx
|
||||
push ds
|
||||
push ss
|
||||
pop ds
|
||||
push ax
|
||||
shr eax, 7
|
||||
; eax = FAT sector number; look in cache
|
||||
mov di, 8400h
|
||||
.cache_lookup:
|
||||
cmp di, [fatcacheend]
|
||||
jae .not_in_cache
|
||||
scasd
|
||||
scasd
|
||||
jnz .cache_lookup
|
||||
.in_cache:
|
||||
sub di, 8
|
||||
; delete this sector from the list
|
||||
push si
|
||||
mov si, [di]
|
||||
mov bx, [di+2]
|
||||
mov [si+2], bx
|
||||
mov [bx], si
|
||||
pop si
|
||||
jmp @f
|
||||
.not_in_cache:
|
||||
; cache miss
|
||||
; cache is full?
|
||||
mov di, [fatcacheend]
|
||||
cmp di, 8C00h
|
||||
jnz .cache_not_full
|
||||
; yes, delete the oldest entry
|
||||
mov di, [fatcachehead]
|
||||
mov bx, [di]
|
||||
mov [fatcachehead], bx
|
||||
push word [di+2]
|
||||
pop word [bx+2]
|
||||
jmp .cache_append
|
||||
.cache_not_full:
|
||||
; no, allocate new sector
|
||||
add [fatcacheend], 8
|
||||
.cache_append:
|
||||
; read FAT
|
||||
mov [di+4], eax
|
||||
push es
|
||||
pushad
|
||||
lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] ; +0x10000 - for FASM
|
||||
shl cx, 9-3
|
||||
mov es, cx
|
||||
xor bx, bx
|
||||
mov cx, 1
|
||||
add eax, [bp-6] ; FAT start
|
||||
sub eax, [bp-10]
|
||||
call [read_sectors2]
|
||||
popad
|
||||
pop es
|
||||
@@:
|
||||
; add new sector to the end of list
|
||||
mov bx, di
|
||||
xchg bx, [fatcachehead+2]
|
||||
push word [bx]
|
||||
pop word [di]
|
||||
mov [bx], di
|
||||
mov [di+2], bx
|
||||
; get requested item
|
||||
lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))]
|
||||
pop di
|
||||
and di, 0x7F
|
||||
shl di, 2
|
||||
shl ax, 9-3
|
||||
mov ds, ax
|
||||
and byte [di+3], 0x0F
|
||||
mov eax, [di]
|
||||
pop ds
|
||||
pop bx di
|
||||
;and eax, 0x0FFFFFFF
|
||||
cmp eax, 0x0FFFFFF7
|
||||
ret
|
||||
|
||||
if $ > 0x8000
|
||||
error 'get_next_cluster must fit in first sector of kordldr.f32!'
|
||||
end if
|
||||
|
||||
load_file:
|
||||
; in: ss:bp = 0:7C00
|
||||
; in: ds:di -> information structure
|
||||
; dw:dw address
|
||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
||||
; ASCIIZ name
|
||||
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found
|
||||
; out: dx:ax = file size (0xFFFFFFFF if file not found)
|
||||
mov eax, [BPB_RootClus] ; start from root directory
|
||||
or dword [filesize], -1 ; initialize file size with invalid value
|
||||
lea si, [di+6]
|
||||
parse_dir_loop:
|
||||
; convert name to FAT name
|
||||
push di
|
||||
push ax
|
||||
push ss
|
||||
pop es
|
||||
; convert ASCIIZ filename to FAT name
|
||||
filename equ bp
|
||||
mov di, filename
|
||||
push di
|
||||
mov cx, 8+3
|
||||
mov al, ' '
|
||||
rep stosb
|
||||
pop di
|
||||
mov cl, 8 ; 8 symbols per name
|
||||
mov bl, 1
|
||||
nameloop:
|
||||
lodsb
|
||||
test al, al
|
||||
jz namedone
|
||||
cmp al, '/'
|
||||
jz namedone
|
||||
cmp al, '.'
|
||||
jz namedot
|
||||
dec cx
|
||||
js badname
|
||||
cmp al, 'a'
|
||||
jb @f
|
||||
cmp al, 'z'
|
||||
ja @f
|
||||
sub al, 'a'-'A'
|
||||
@@:
|
||||
stosb
|
||||
jmp nameloop
|
||||
namedot:
|
||||
inc bx
|
||||
jp badname
|
||||
add di, cx
|
||||
mov cl, 3
|
||||
jmp nameloop
|
||||
badname: ; do not make direct js/jp to notfound_pop:
|
||||
; this generates long forms of conditional jumps and results in longer code
|
||||
jmp notfound_pop
|
||||
namedone:
|
||||
; scan directory
|
||||
pop ax ; eax = cluster of directory
|
||||
; high word of eax is preserved by operations above
|
||||
push ds
|
||||
push si
|
||||
; read a folder sector-by-sector and scan
|
||||
; first, try to use the cache
|
||||
push ss
|
||||
pop ds
|
||||
mov di, foldcache_mark
|
||||
xor bx, bx
|
||||
mov cx, [cachelimit]
|
||||
@@:
|
||||
lea si, [di+bx]
|
||||
mov edx, dword [foldcache_clus+si-foldcache_mark+bx]
|
||||
cmp edx, eax
|
||||
jz cacheok
|
||||
test edx, edx
|
||||
jz cacheadd ; the cache has place for new entry
|
||||
inc bx
|
||||
inc bx
|
||||
dec cx
|
||||
jns @b
|
||||
; the folder is not present in the cache, so add it
|
||||
; the cache is full; find the oldest entry and replace it with the new one
|
||||
mov bx, -2
|
||||
mov dx, [cachelimit]
|
||||
@@:
|
||||
inc bx
|
||||
inc bx
|
||||
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
|
||||
jnz @b
|
||||
lea si, [di+bx]
|
||||
cacheadd:
|
||||
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
|
||||
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
|
||||
mov dword [foldcache_clus+si-foldcache_mark+bx], eax
|
||||
cacheok:
|
||||
; update cache marks
|
||||
mov dx, [di+bx]
|
||||
mov cx, [foldcache_size+di-foldcache_mark+bx]
|
||||
mov di, [cachelimit]
|
||||
add di, di
|
||||
cacheupdate:
|
||||
cmp [foldcache_mark+di], dx
|
||||
adc [foldcache_mark+di], 0
|
||||
dec di
|
||||
dec di
|
||||
jns cacheupdate
|
||||
and [foldcache_mark+bx], 0
|
||||
; done, bx contains (position in cache)*2
|
||||
;mov dx, bx
|
||||
;shl dx, 8 ; dx = (position in cache)*0x2000/0x10
|
||||
;add dx, 0x9000
|
||||
lea dx, [bx + 0x90]
|
||||
xchg dl, dh
|
||||
mov ds, dx
|
||||
mov si, filename ; ss:si -> filename in FAT style
|
||||
call scan_for_filename
|
||||
jz lookup_done
|
||||
; cache miss, read folder data from disk
|
||||
mov bx, cx
|
||||
shr bx, 4
|
||||
shl cx, 5
|
||||
mov di, cx ; es:di -> free space in cache entry
|
||||
; external loop: scan clusters
|
||||
folder_next_cluster:
|
||||
; internal loop: scan sectors in cluster
|
||||
push eax
|
||||
call cluster2sector
|
||||
folder_next_sector:
|
||||
; skip first bx sectors
|
||||
dec bx
|
||||
jns folder_skip_sector
|
||||
push cx
|
||||
push es di
|
||||
push 0x8000
|
||||
pop es
|
||||
xor bx, bx
|
||||
mov cx, 1
|
||||
push es
|
||||
push eax
|
||||
call [read_sectors2]
|
||||
pop eax
|
||||
; copy data to the cache...
|
||||
pop ds
|
||||
pop di es
|
||||
cmp di, 0x2000 ; ...if there is free space, of course
|
||||
jae @f
|
||||
pusha
|
||||
mov cx, 0x100
|
||||
xor si, si
|
||||
rep movsw
|
||||
mov di, es
|
||||
shr di, 8
|
||||
add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache
|
||||
popa
|
||||
@@:
|
||||
push es
|
||||
mov cl, 0x10 ; ch=0 at this point
|
||||
call scan_for_filename
|
||||
pop es
|
||||
pop cx
|
||||
jz lookup_done_pop
|
||||
folder_skip_sector:
|
||||
inc eax
|
||||
loop folder_next_sector
|
||||
pop eax ; eax = current cluster
|
||||
call get_next_cluster
|
||||
jc folder_next_cluster
|
||||
stc
|
||||
push eax
|
||||
lookup_done_pop:
|
||||
pop eax
|
||||
lookup_done:
|
||||
pop si
|
||||
; CF=1 <=> failed
|
||||
jnc found
|
||||
pop ds
|
||||
notfound:
|
||||
pop di
|
||||
notfound2:
|
||||
mov bx, 2 ; file not found
|
||||
mov ax, 0xFFFF
|
||||
mov dx, ax ; invalid file size
|
||||
ret
|
||||
notfound_pop:
|
||||
pop ax
|
||||
jmp notfound
|
||||
found:
|
||||
mov eax, [di+20-2]
|
||||
mov edx, [di+28]
|
||||
mov ax, [di+26] ; get cluster
|
||||
test byte [di+11], 10h ; directory?
|
||||
pop ds
|
||||
pop di
|
||||
jz regular_file
|
||||
cmp byte [si-1], 0
|
||||
jz notfound2 ; don't read directories as regular files
|
||||
; ok, we have found a directory and the caller requested a file into it
|
||||
jmp parse_dir_loop ; restart with new cluster in ax
|
||||
regular_file:
|
||||
cmp byte [si-1], 0
|
||||
jnz notfound2 ; file does not contain another files
|
||||
; ok, we have found a regular file and the caller requested it
|
||||
; save file size
|
||||
mov [filesize], edx
|
||||
mov si, [di+4] ; [ds:di+4] = limit in 4K blocks
|
||||
shl si, 3
|
||||
push si
|
||||
les bx, [di] ; es:bx -> buffer
|
||||
clusloop:
|
||||
; eax = first cluster, top of stack contains limit in sectors
|
||||
mov esi, eax ; remember current cluster
|
||||
xor ecx, ecx ; ecx will contain number of consecutive clusters
|
||||
mov [cur_delta], ecx
|
||||
mov edi, eax
|
||||
clusfind:
|
||||
inc edi
|
||||
inc ecx
|
||||
call get_next_cluster
|
||||
jnc clusread
|
||||
cmp eax, edi
|
||||
jz clusfind
|
||||
stc
|
||||
clusread:
|
||||
pop di ; limit in sectors
|
||||
movzx edi, di
|
||||
push eax ; save next cluster
|
||||
pushf ; save flags
|
||||
; read cx clusters, starting from si
|
||||
; calculate number of sectors
|
||||
xchg eax, ecx
|
||||
call clustersz2sectorsz
|
||||
mov [num_sectors], eax
|
||||
jmp @f
|
||||
continue_load_file:
|
||||
les bx, [di] ; es:bx -> buffer
|
||||
movzx edi, word [di+4] ; di = limit in 4K blocks
|
||||
shl di, 3 ; now di = limit in sectors
|
||||
mov eax, [num_sectors]
|
||||
mov esi, [cur_cluster]
|
||||
push [next_cluster]
|
||||
push [flags]
|
||||
test eax, eax
|
||||
jz nextclus
|
||||
@@:
|
||||
; eax = number of sectors; compare with limit
|
||||
cmp eax, edi
|
||||
seta dl
|
||||
push dx ; limit was exceeded?
|
||||
jbe @f
|
||||
mov eax, edi
|
||||
@@:
|
||||
sub di, ax ; calculate new limit
|
||||
sub [num_sectors], eax
|
||||
mov [cur_cluster], esi
|
||||
; calculate starting sector
|
||||
push ax
|
||||
xchg eax, esi
|
||||
call cluster2sector
|
||||
pop cx
|
||||
add eax, [cur_delta]
|
||||
add [cur_delta], ecx
|
||||
; read
|
||||
call [read_sectors2]
|
||||
pop dx
|
||||
; next cluster?
|
||||
nextclus:
|
||||
popf
|
||||
pop eax
|
||||
mov [next_cluster], eax
|
||||
pushf
|
||||
pop [flags]
|
||||
jnc @f ; no next cluster => return
|
||||
mov dl, 1 ; dh=0 in any case
|
||||
test di, di
|
||||
jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded
|
||||
push di
|
||||
jmp clusloop ; all is ok, continue
|
||||
hooked_err:
|
||||
mov sp, 7C00h-14-2 ; restore stack
|
||||
mov dx, 3 ; return: read error
|
||||
@@:
|
||||
mov bx, dx
|
||||
mov ax, [filesize]
|
||||
mov dx, [filesize+2]
|
||||
ret
|
||||
|
||||
scan_for_filename:
|
||||
; in: ss:si -> 11-bytes FAT name
|
||||
; in: ds:0 -> part of directory data
|
||||
; in: cx = number of entries
|
||||
; in: bh = 0
|
||||
; out: if found: CF=0, ZF=1, es:di -> directory entry
|
||||
; out: if not found, but continue required: CF=1 and ZF=0
|
||||
; out: if not found and zero item reached: CF=1 and ZF=1
|
||||
push ds
|
||||
pop es
|
||||
xor di, di
|
||||
push cx
|
||||
jcxz snoent
|
||||
sloop:
|
||||
cmp byte [di], bh
|
||||
jz snotfound
|
||||
test byte [di+11], 8 ; volume label?
|
||||
jnz scont ; ignore volume labels
|
||||
pusha
|
||||
mov cx, 11
|
||||
repz cmps byte [ss:si], byte [es:di]
|
||||
popa
|
||||
jz sdone
|
||||
scont:
|
||||
add di, 0x20
|
||||
loop sloop
|
||||
snoent:
|
||||
inc cx ; clear ZF flag
|
||||
snotfound:
|
||||
stc
|
||||
sdone:
|
||||
pop cx
|
||||
lrdret:
|
||||
ret
|
||||
|
||||
; Callback function for secondary loader
|
||||
callback:
|
||||
; in: ax = function number; only functions 1 and 2 are defined for now
|
||||
; save caller's stack
|
||||
mov dx, ss
|
||||
mov cx, sp
|
||||
; set our stack (required because we need ss=0)
|
||||
xor si, si
|
||||
mov ss, si
|
||||
mov sp, 7C00h-10
|
||||
mov bp, 7C00h
|
||||
push dx
|
||||
push cx
|
||||
; call our function
|
||||
stc ; unsupported function
|
||||
dec ax
|
||||
jz callback_readfile
|
||||
dec ax
|
||||
jnz callback_ret
|
||||
; function 2: continue loading file
|
||||
; can be called only after function 1 returned value bx=1 (only part of file was loaded)
|
||||
; in: ds:di -> information structure
|
||||
; dw:dw address
|
||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
||||
; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error
|
||||
; out: dx:ax = file size
|
||||
call continue_load_file
|
||||
jmp callback_ret_succ
|
||||
callback_readfile:
|
||||
; function 1: read file
|
||||
; in: ds:di -> information structure
|
||||
; dw:dw address
|
||||
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
|
||||
; ASCIIZ name
|
||||
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
|
||||
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
|
||||
call load_file
|
||||
callback_ret_succ:
|
||||
clc ; function is supported
|
||||
callback_ret:
|
||||
; restore caller's stack
|
||||
pop cx
|
||||
pop ss
|
||||
mov sp, cx
|
||||
; return to caller
|
||||
retf
|
||||
|
||||
secondary_loader_info:
|
||||
dw 0, 0x1000
|
||||
dw 0x30000 / 0x1000
|
||||
db 'kord/loader',0
|
||||
aKernelNotFound db 'Fatal error: cannot load the secondary loader',0
|
||||
|
||||
;if $ > 0x8200
|
||||
;error 'total size of kordldr.f32 must not exceed 1024 bytes!'
|
||||
;end if
|
||||
|
||||
;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache
|
||||
;foldcache_mark dw 0
|
||||
; rw 7
|
||||
;foldcache_size rw 8
|
||||
foldcache_clus rd 8
|
||||
foldcache_mark rw 8
|
||||
foldcache_size rw 8
|
142
kernel/branches/kolibri-cfg/build.bat
Normal file
142
kernel/branches/kolibri-cfg/build.bat
Normal file
@ -0,0 +1,142 @@
|
||||
@echo off
|
||||
cls
|
||||
set languages=en ru ge et
|
||||
set drivers=com_mouse emu10k1x ensoniq fm801 infinity sis sound uart viasound vmode vt823x
|
||||
set targets=all kernel drivers skins clean
|
||||
|
||||
call :Check_Target %1
|
||||
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2
|
||||
call :Target_%target%
|
||||
|
||||
if ERRORLEVEL 0 goto Exit_OK
|
||||
|
||||
echo There was an error executing script.
|
||||
echo For any help, please send a report.
|
||||
pause
|
||||
goto :eof
|
||||
|
||||
|
||||
|
||||
|
||||
:Check_Lang
|
||||
set res=%1
|
||||
:Check_Lang_loop
|
||||
for %%a in (%languages%) do if %%a==%res% set lang=%res%
|
||||
if defined lang goto :eof
|
||||
|
||||
echo Language '%res%' is incorrect
|
||||
echo Enter valid language [ %languages% ]:
|
||||
|
||||
set /P res=">
|
||||
goto Check_Lang_loop
|
||||
goto :eof
|
||||
|
||||
:Check_Target
|
||||
set res=%1
|
||||
:Check_Target_loop
|
||||
for %%a in (%targets%) do if %%a==%res% set target=%res%
|
||||
if defined target goto :eof
|
||||
|
||||
echo Target '%res%' is incorrect
|
||||
echo Enter valid target [ %targets% ]:
|
||||
|
||||
set /P res=">
|
||||
goto Check_Target_loop
|
||||
goto :eof
|
||||
|
||||
|
||||
:Target_kernel
|
||||
echo *** building kernel with language '%lang%' ...
|
||||
|
||||
if not exist bin mkdir bin
|
||||
echo lang fix %lang% > lang.inc
|
||||
fasm -m 65536 kernel.asm bin\kernel.mnt
|
||||
if not %errorlevel%==0 goto :Error_FasmFailed
|
||||
erase lang.inc
|
||||
goto :eof
|
||||
|
||||
|
||||
:Target_all
|
||||
call :Target_kernel
|
||||
call :Target_drivers
|
||||
call :Target_skins
|
||||
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 ..
|
||||
move bin\drivers\vmode.obj bin\drivers\vmode.mdr
|
||||
|
||||
|
||||
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_skins
|
||||
echo *** building skins ...
|
||||
|
||||
if not exist bin\skins mkdir bin\skins
|
||||
cd skin
|
||||
fasm -m 65536 default.asm ..\bin\skins\default.skn
|
||||
if not %errorlevel%==0 goto :Error_FasmFailed
|
||||
cd ..
|
||||
goto :eof
|
||||
|
||||
:Target_clean
|
||||
echo *** cleaning ...
|
||||
rmdir /S /Q bin
|
||||
goto :Exit_OK
|
||||
|
||||
|
||||
:Error_FasmFailed
|
||||
echo error: fasm execution failed
|
||||
erase lang.inc >nul 2>&1
|
||||
echo.
|
||||
pause
|
||||
exit 1
|
||||
|
||||
:Error_KpackFailed
|
||||
echo *** NOTICE ***
|
||||
echo If you want to pack all applications you may
|
||||
echo place "kpack" in accessible directory or system %PATH%.
|
||||
echo You can get this tool from KolibriOS distribution kit.
|
||||
pause
|
||||
exit 1
|
||||
|
||||
:Exit_OK
|
||||
echo.
|
||||
echo all operations have been done
|
||||
pause
|
||||
exit 0
|
119
kernel/branches/kolibri-cfg/bus/pci/PCIe.inc
Normal file
119
kernel/branches/kolibri-cfg/bus/pci/PCIe.inc
Normal file
@ -0,0 +1,119 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) 2010 KolibriOS team. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; ;;
|
||||
;; PCIe.INC ;;
|
||||
;; ;;
|
||||
;; Extended PCI express services ;;
|
||||
;; ;;
|
||||
;; art_zh <artem@jerdev.co.uk> ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision: 1463 $
|
||||
|
||||
;***************************************************************************
|
||||
; Function
|
||||
; pci_ext_config:
|
||||
;
|
||||
; Description
|
||||
; PCIe extended (memory-mapped) config space detection
|
||||
;
|
||||
; WARNINGs:
|
||||
; 1) Very Experimental!
|
||||
; 2) direct HT-detection (no ACPI or BIOS service used)
|
||||
; 3) Only AMD/HT processors currently supported
|
||||
;
|
||||
;***************************************************************************
|
||||
|
||||
PCIe_CONFIG_SPACE equ 0xF0000000 ; to be moved to const.inc
|
||||
mmio_pcie_cfg_addr dd 0x0 ; intel pcie space may be defined here
|
||||
mmio_pcie_cfg_lim dd 0x0 ; upper pcie space address
|
||||
|
||||
|
||||
align 4
|
||||
|
||||
pci_ext_config:
|
||||
|
||||
mov ebx, [mmio_pcie_cfg_addr]
|
||||
or ebx,ebx
|
||||
jz @f
|
||||
or ebx, 0x7FFFFFFF ; required by PCI-SIG standards
|
||||
jnz .pcie_failed
|
||||
add ebx, 0x0FFFFC
|
||||
cmp ebx, [mmio_pcie_cfg_lim]; is the space limit correct?
|
||||
ja .pcie_failed
|
||||
jmp .pcie_cfg_mapped
|
||||
@@:
|
||||
mov ebx, [cpu_vendor]
|
||||
cmp ebx, dword [AMD_str]
|
||||
jne .pcie_failed
|
||||
mov bx, 0xC184 ; dev = 24, fn = 01, reg = 84h
|
||||
|
||||
.check_HT_mmio:
|
||||
mov cx, bx
|
||||
mov ax, 0x0002 ; bus = 0, 1dword to read
|
||||
call pci_read_reg
|
||||
mov bx, cx
|
||||
sub bl, 4
|
||||
and al, 0x80 ; check the NP bit
|
||||
jz .no_pcie_cfg
|
||||
shl eax, 8 ; bus:[27..20], dev:[19:15]
|
||||
or eax, 0x00007FFC ; fun:[14..12], reg:[11:2]
|
||||
mov [mmio_pcie_cfg_lim], eax
|
||||
mov cl, bl
|
||||
mov ax, 0x0002 ; bus = 0, 1dword to read
|
||||
call pci_read_reg
|
||||
mov bx, cx
|
||||
test al, 0x03 ; MMIO Base RW enabled?
|
||||
jz .no_pcie_cfg
|
||||
test al, 0x0C ; MMIO Base locked?
|
||||
jnz .no_pcie_cfg
|
||||
xor al, al
|
||||
shl eax, 8
|
||||
test eax, 0x000F0000 ; MMIO Base must be bus0-aligned
|
||||
jnz .no_pcie_cfg
|
||||
mov [mmio_pcie_cfg_addr], eax
|
||||
add eax, 0x000FFFFC
|
||||
sub eax,[mmio_pcie_cfg_lim] ; MMIO must cover at least one bus
|
||||
ja .no_pcie_cfg
|
||||
|
||||
; -- it looks like a true PCIe config space;
|
||||
mov eax,[mmio_pcie_cfg_addr] ; physical address
|
||||
or eax, (PG_SHARED + PG_LARGE + PG_USER)
|
||||
mov ebx, PCIe_CONFIG_SPACE ; linear address
|
||||
mov ecx, ebx
|
||||
shr ebx, 20
|
||||
add ebx, sys_pgdir ; PgDir entry @
|
||||
@@:
|
||||
mov dword[ebx], eax ; map 4 buses
|
||||
invlpg [ecx]
|
||||
cmp bl, 4
|
||||
jz .pcie_cfg_mapped ; fix it later
|
||||
add bl, 4 ; next PgDir entry
|
||||
add eax, 0x400000 ; eax += 4M
|
||||
add ecx, 0x400000
|
||||
jmp @b
|
||||
|
||||
.pcie_cfg_mapped:
|
||||
|
||||
; -- glad to have the extended PCIe config field found
|
||||
; mov esi, boot_pcie_ok
|
||||
; call boot_log
|
||||
ret ; <<<<<<<<<<< OK >>>>>>>>>>>
|
||||
|
||||
.no_pcie_cfg:
|
||||
|
||||
xor eax, eax
|
||||
mov [mmio_pcie_cfg_addr], eax
|
||||
mov [mmio_pcie_cfg_lim], eax
|
||||
add bl, 12
|
||||
cmp bl, 0xC0 ; MMIO regs lay below this offset
|
||||
jb .check_HT_mmio
|
||||
.pcie_failed:
|
||||
; mov esi, boot_pcie_fail
|
||||
; call boot_log
|
||||
ret ; <<<<<<<<< FAILURE >>>>>>>>>
|
||||
|
51
kernel/branches/kolibri-cfg/bus/pci/pci16.inc
Normal file
51
kernel/branches/kolibri-cfg/bus/pci/pci16.inc
Normal file
@ -0,0 +1,51 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; PCI16.INC ;;
|
||||
;; ;;
|
||||
;; 16 bit PCI driver code ;;
|
||||
;; ;;
|
||||
;; Version 0.2 December 21st, 2002 ;;
|
||||
;; ;;
|
||||
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
|
||||
;; ;;
|
||||
;; See file COPYING for details ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
init_pci_16:
|
||||
|
||||
pushad
|
||||
|
||||
xor ax,ax
|
||||
mov es,ax
|
||||
mov byte [es:0x9020],1 ;default mechanism:1
|
||||
mov ax,0xb101
|
||||
int 0x1a
|
||||
or ah,ah
|
||||
jnz pci16skip
|
||||
|
||||
mov [es:0x9021],cl ;last PCI bus in system
|
||||
mov [es:0x9022],bx
|
||||
mov [es:0x9024],edi
|
||||
|
||||
; we have a PCI BIOS, so check which configuration mechanism(s)
|
||||
; it supports
|
||||
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2)
|
||||
test al,1
|
||||
jnz pci16skip
|
||||
test al,2
|
||||
jz pci16skip
|
||||
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2
|
||||
|
||||
pci16skip:
|
||||
|
||||
mov ax,0x1000
|
||||
mov es,ax
|
||||
|
||||
popad
|
654
kernel/branches/kolibri-cfg/bus/pci/pci32.inc
Normal file
654
kernel/branches/kolibri-cfg/bus/pci/pci32.inc
Normal file
@ -0,0 +1,654 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; ;;
|
||||
;; PCI32.INC ;;
|
||||
;; ;;
|
||||
;; 32 bit PCI driver code ;;
|
||||
;; ;;
|
||||
;; Version 0.3 April 9, 2007 ;;
|
||||
;; Version 0.2 December 21st, 2002 ;;
|
||||
;; ;;
|
||||
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
|
||||
;; Mihailov Ilia, ghost.nsk@gmail.com ;;
|
||||
;; Credits: ;;
|
||||
;; Ralf Brown ;;
|
||||
;; Mike Hibbett, mikeh@oceanfree.net ;;
|
||||
;; ;;
|
||||
;; See file COPYING for details ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
;***************************************************************************
|
||||
; Function
|
||||
; pci_api:
|
||||
;
|
||||
; Description
|
||||
; entry point for system PCI calls
|
||||
;***************************************************************************
|
||||
;mmio_pci_addr equ 0x400 ; set actual PCI address here to activate user-MMIO
|
||||
|
||||
iglobal
|
||||
align 4
|
||||
f62call:
|
||||
dd pci_fn_0
|
||||
dd pci_fn_1
|
||||
dd pci_fn_2
|
||||
dd pci_service_not_supported ;3
|
||||
dd pci_read_reg ;4 byte
|
||||
dd pci_read_reg ;5 word
|
||||
dd pci_read_reg ;6 dword
|
||||
dd pci_service_not_supported ;7
|
||||
dd pci_write_reg ;8 byte
|
||||
dd pci_write_reg ;9 word
|
||||
dd pci_write_reg ;10 dword
|
||||
if defined mmio_pci_addr
|
||||
dd pci_mmio_init ;11
|
||||
dd pci_mmio_map ;12
|
||||
dd pci_mmio_unmap ;13
|
||||
end if
|
||||
|
||||
endg
|
||||
|
||||
align 4
|
||||
|
||||
pci_api:
|
||||
|
||||
;cross
|
||||
mov eax,ebx
|
||||
mov ebx,ecx
|
||||
mov ecx,edx
|
||||
|
||||
cmp [pci_access_enabled],1
|
||||
jne pci_service_not_supported
|
||||
|
||||
movzx edx, al
|
||||
|
||||
if defined mmio_pci_addr
|
||||
cmp al, 13
|
||||
ja pci_service_not_supported
|
||||
else
|
||||
cmp al, 10
|
||||
ja pci_service_not_supported
|
||||
end if
|
||||
|
||||
call dword [f62call+edx*4]
|
||||
mov dword [esp+32],eax
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
pci_api_drv:
|
||||
|
||||
cmp [pci_access_enabled],1
|
||||
jne .fail
|
||||
|
||||
cmp eax, 2
|
||||
ja .fail
|
||||
|
||||
jmp dword [f62call+eax*4]
|
||||
|
||||
.fail:
|
||||
or eax,-1
|
||||
ret
|
||||
|
||||
|
||||
;; ============================================
|
||||
|
||||
pci_fn_0:
|
||||
; PCI function 0: get pci version (AH.AL)
|
||||
movzx eax,word [BOOT_VAR+0x9022]
|
||||
ret
|
||||
|
||||
pci_fn_1:
|
||||
; PCI function 1: get last bus in AL
|
||||
mov al,[BOOT_VAR+0x9021]
|
||||
ret
|
||||
|
||||
pci_fn_2:
|
||||
; PCI function 2: get pci access mechanism
|
||||
mov al,[BOOT_VAR+0x9020]
|
||||
ret
|
||||
|
||||
pci_service_not_supported:
|
||||
or eax,-1
|
||||
mov dword [esp+32],eax
|
||||
ret
|
||||
|
||||
;***************************************************************************
|
||||
; Function
|
||||
; pci_make_config_cmd
|
||||
;
|
||||
; Description
|
||||
; creates a command dword for use with the PCI bus
|
||||
; bus # in ah
|
||||
; device+func in bh (dddddfff)
|
||||
; register in bl
|
||||
;
|
||||
; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
|
||||
;***************************************************************************
|
||||
|
||||
align 4
|
||||
|
||||
pci_make_config_cmd:
|
||||
shl eax,8 ; move bus to bits 16-23
|
||||
mov ax,bx ; combine all
|
||||
and eax,0xffffff
|
||||
or eax,0x80000000
|
||||
ret
|
||||
|
||||
;***************************************************************************
|
||||
; Function
|
||||
; pci_read_reg:
|
||||
;
|
||||
; Description
|
||||
; read a register from the PCI config space into EAX/AX/AL
|
||||
; IN: ah=bus,device+func=bh,register address=bl
|
||||
; number of bytes to read (1,2,4) coded into AL, bits 0-1
|
||||
; (0 - byte, 1 - word, 2 - dword)
|
||||
;***************************************************************************
|
||||
|
||||
align 4
|
||||
|
||||
pci_read_reg:
|
||||
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
|
||||
je pci_read_reg_2
|
||||
|
||||
; mechanism 1
|
||||
push esi ; save register size into ESI
|
||||
mov esi,eax
|
||||
and esi,3
|
||||
|
||||
call pci_make_config_cmd
|
||||
mov ebx,eax
|
||||
; get current state
|
||||
mov dx,0xcf8
|
||||
in eax, dx
|
||||
push eax
|
||||
; set up addressing to config data
|
||||
mov eax,ebx
|
||||
and al,0xfc ; make address dword-aligned
|
||||
out dx,eax
|
||||
; get requested DWORD of config data
|
||||
mov dl,0xfc
|
||||
and bl,3
|
||||
or dl,bl ; add to port address first 2 bits of register address
|
||||
|
||||
or esi,esi
|
||||
jz pci_read_byte1
|
||||
cmp esi,1
|
||||
jz pci_read_word1
|
||||
cmp esi,2
|
||||
jz pci_read_dword1
|
||||
jmp pci_fin_read1
|
||||
|
||||
pci_read_byte1:
|
||||
in al,dx
|
||||
jmp pci_fin_read1
|
||||
pci_read_word1:
|
||||
in ax,dx
|
||||
jmp pci_fin_read1
|
||||
pci_read_dword1:
|
||||
in eax,dx
|
||||
jmp pci_fin_read1
|
||||
pci_fin_read1:
|
||||
; restore configuration control
|
||||
xchg eax,[esp]
|
||||
mov dx,0xcf8
|
||||
out dx,eax
|
||||
|
||||
pop eax
|
||||
pop esi
|
||||
ret
|
||||
pci_read_reg_2:
|
||||
|
||||
test bh,128 ;mech#2 only supports 16 devices per bus
|
||||
jnz pci_read_reg_err
|
||||
|
||||
push esi ; save register size into ESI
|
||||
mov esi,eax
|
||||
and esi,3
|
||||
|
||||
push eax
|
||||
;store current state of config space
|
||||
mov dx,0xcf8
|
||||
in al,dx
|
||||
mov ah,al
|
||||
mov dl,0xfa
|
||||
in al,dx
|
||||
|
||||
xchg eax,[esp]
|
||||
; out 0xcfa,bus
|
||||
mov al,ah
|
||||
out dx,al
|
||||
; out 0xcf8,0x80
|
||||
mov dl,0xf8
|
||||
mov al,0x80
|
||||
out dx,al
|
||||
; compute addr
|
||||
shr bh,3 ; func is ignored in mechanism 2
|
||||
or bh,0xc0
|
||||
mov dx,bx
|
||||
|
||||
or esi,esi
|
||||
jz pci_read_byte2
|
||||
cmp esi,1
|
||||
jz pci_read_word2
|
||||
cmp esi,2
|
||||
jz pci_read_dword2
|
||||
jmp pci_fin_read2
|
||||
|
||||
pci_read_byte2:
|
||||
in al,dx
|
||||
jmp pci_fin_read2
|
||||
pci_read_word2:
|
||||
in ax,dx
|
||||
jmp pci_fin_read2
|
||||
pci_read_dword2:
|
||||
in eax,dx
|
||||
; jmp pci_fin_read2
|
||||
pci_fin_read2:
|
||||
|
||||
; restore configuration space
|
||||
xchg eax,[esp]
|
||||
mov dx,0xcfa
|
||||
out dx,al
|
||||
mov dl,0xf8
|
||||
mov al,ah
|
||||
out dx,al
|
||||
|
||||
pop eax
|
||||
pop esi
|
||||
ret
|
||||
|
||||
pci_read_reg_err:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
ret
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
; Function
|
||||
; pci_write_reg:
|
||||
;
|
||||
; Description
|
||||
; write a register from ECX/CX/CL into the PCI config space
|
||||
; IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
|
||||
; value to write in ecx
|
||||
; number of bytes to write (1,2,4) coded into AL, bits 0-1
|
||||
; (0 - byte, 1 - word, 2 - dword)
|
||||
;***************************************************************************
|
||||
|
||||
align 4
|
||||
|
||||
pci_write_reg:
|
||||
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
|
||||
je pci_write_reg_2
|
||||
|
||||
; mechanism 1
|
||||
push esi ; save register size into ESI
|
||||
mov esi,eax
|
||||
and esi,3
|
||||
|
||||
call pci_make_config_cmd
|
||||
mov ebx,eax
|
||||
; get current state into ecx
|
||||
mov dx,0xcf8
|
||||
in eax, dx
|
||||
push eax
|
||||
; set up addressing to config data
|
||||
mov eax,ebx
|
||||
and al,0xfc ; make address dword-aligned
|
||||
out dx,eax
|
||||
; write DWORD of config data
|
||||
mov dl,0xfc
|
||||
and bl,3
|
||||
or dl,bl
|
||||
mov eax,ecx
|
||||
|
||||
or esi,esi
|
||||
jz pci_write_byte1
|
||||
cmp esi,1
|
||||
jz pci_write_word1
|
||||
cmp esi,2
|
||||
jz pci_write_dword1
|
||||
jmp pci_fin_write1
|
||||
|
||||
pci_write_byte1:
|
||||
out dx,al
|
||||
jmp pci_fin_write1
|
||||
pci_write_word1:
|
||||
out dx,ax
|
||||
jmp pci_fin_write1
|
||||
pci_write_dword1:
|
||||
out dx,eax
|
||||
jmp pci_fin_write1
|
||||
pci_fin_write1:
|
||||
|
||||
; restore configuration control
|
||||
pop eax
|
||||
mov dl,0xf8
|
||||
out dx,eax
|
||||
|
||||
xor eax,eax
|
||||
pop esi
|
||||
|
||||
ret
|
||||
pci_write_reg_2:
|
||||
|
||||
test bh,128 ;mech#2 only supports 16 devices per bus
|
||||
jnz pci_write_reg_err
|
||||
|
||||
|
||||
push esi ; save register size into ESI
|
||||
mov esi,eax
|
||||
and esi,3
|
||||
|
||||
push eax
|
||||
;store current state of config space
|
||||
mov dx,0xcf8
|
||||
in al,dx
|
||||
mov ah,al
|
||||
mov dl,0xfa
|
||||
in al,dx
|
||||
xchg eax,[esp]
|
||||
; out 0xcfa,bus
|
||||
mov al,ah
|
||||
out dx,al
|
||||
; out 0xcf8,0x80
|
||||
mov dl,0xf8
|
||||
mov al,0x80
|
||||
out dx,al
|
||||
; compute addr
|
||||
shr bh,3 ; func is ignored in mechanism 2
|
||||
or bh,0xc0
|
||||
mov dx,bx
|
||||
; write register
|
||||
mov eax,ecx
|
||||
|
||||
or esi,esi
|
||||
jz pci_write_byte2
|
||||
cmp esi,1
|
||||
jz pci_write_word2
|
||||
cmp esi,2
|
||||
jz pci_write_dword2
|
||||
jmp pci_fin_write2
|
||||
|
||||
pci_write_byte2:
|
||||
out dx,al
|
||||
jmp pci_fin_write2
|
||||
pci_write_word2:
|
||||
out dx,ax
|
||||
jmp pci_fin_write2
|
||||
pci_write_dword2:
|
||||
out dx,eax
|
||||
jmp pci_fin_write2
|
||||
pci_fin_write2:
|
||||
; restore configuration space
|
||||
pop eax
|
||||
mov dx,0xcfa
|
||||
out dx,al
|
||||
mov dl,0xf8
|
||||
mov al,ah
|
||||
out dx,al
|
||||
|
||||
xor eax,eax
|
||||
pop esi
|
||||
ret
|
||||
|
||||
pci_write_reg_err:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
ret
|
||||
|
||||
if defined mmio_pci_addr ; must be set above
|
||||
;***************************************************************************
|
||||
; Function
|
||||
; pci_mmio_init
|
||||
;
|
||||
; Description
|
||||
; IN: bx = device's PCI bus address (bbbbbbbbdddddfff)
|
||||
; Returns eax = user heap space available (bytes)
|
||||
; Error codes
|
||||
; eax = -1 : PCI user access blocked,
|
||||
; eax = -2 : device not registered for uMMIO service
|
||||
; eax = -3 : user heap initialization failure
|
||||
;***************************************************************************
|
||||
pci_mmio_init:
|
||||
cmp bx, mmio_pci_addr
|
||||
jz @f
|
||||
mov eax,-2
|
||||
ret
|
||||
@@:
|
||||
call init_heap ; (if not initialized yet)
|
||||
or eax,eax
|
||||
jz @f
|
||||
ret
|
||||
@@:
|
||||
mov eax,-3
|
||||
ret
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
; Function
|
||||
; pci_mmio_map
|
||||
;
|
||||
; Description
|
||||
; maps a block of PCI memory to user-accessible linear address
|
||||
;
|
||||
; WARNING! This VERY EXPERIMENTAL service is for one chosen PCI device only!
|
||||
; The target device address should be set in kernel var mmio_pci_addr
|
||||
;
|
||||
; IN: ah = BAR#;
|
||||
; IN: ebx = block size (bytes);
|
||||
; IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
|
||||
;
|
||||
; Returns eax = MMIO block's linear address in the userspace (if no error)
|
||||
;
|
||||
;
|
||||
; Error codes
|
||||
; eax = -1 : user access to PCI blocked,
|
||||
; eax = -2 : an invalid BAR register referred
|
||||
; eax = -3 : no i/o space on that BAR
|
||||
; eax = -4 : a port i/o BAR register referred
|
||||
; eax = -5 : dynamic userspace allocation problem
|
||||
;***************************************************************************
|
||||
|
||||
pci_mmio_map:
|
||||
and edx,0x0ffff
|
||||
cmp ah,6
|
||||
jc .bar_0_5
|
||||
jz .bar_rom
|
||||
mov eax,-2
|
||||
ret
|
||||
.bar_rom:
|
||||
mov ah, 8 ; bar6 = Expansion ROM base address
|
||||
.bar_0_5:
|
||||
push ecx
|
||||
add ebx, 4095
|
||||
and ebx,-4096
|
||||
push ebx
|
||||
mov bl, ah ; bl = BAR# (0..5), however bl=8 for BAR6
|
||||
shl bl, 1
|
||||
shl bl, 1
|
||||
add bl, 0x10 ; now bl = BAR offset in PCI config. space
|
||||
mov ax, mmio_pci_addr
|
||||
mov bh, al ; bh = dddddfff
|
||||
mov al, 2 ; al : DW to read
|
||||
call pci_read_reg
|
||||
or eax, eax
|
||||
jnz @f
|
||||
mov eax,-3 ; empty I/O space
|
||||
jmp mmio_ret_fail
|
||||
@@:
|
||||
test eax, 1
|
||||
jz @f
|
||||
mov eax,-4 ; damned ports (not MMIO space)
|
||||
jmp mmio_ret_fail
|
||||
@@:
|
||||
pop ecx ; ecx = block size, bytes (expanded to whole page)
|
||||
mov ebx, ecx ; user_alloc destroys eax, ecx, edx, but saves ebx
|
||||
and eax, 0xFFFFFFF0
|
||||
push eax ; store MMIO physical address + keep 2DWords in the stack
|
||||
stdcall user_alloc, ecx
|
||||
or eax, eax
|
||||
jnz mmio_map_over
|
||||
mov eax,-5 ; problem with page allocation
|
||||
|
||||
mmio_ret_fail:
|
||||
pop ecx
|
||||
pop edx
|
||||
ret
|
||||
|
||||
mmio_map_over:
|
||||
mov ecx, ebx ; ecx = size (bytes, expanded to whole page)
|
||||
shr ecx, 12 ; ecx = number of pages
|
||||
mov ebx, eax ; ebx = linear address
|
||||
pop eax ; eax = MMIO start
|
||||
pop edx ; edx = MMIO shift (pages)
|
||||
shl edx, 12 ; edx = MMIO shift (bytes)
|
||||
add eax, edx ; eax = uMMIO physical address
|
||||
or eax, PG_SHARED
|
||||
or eax, PG_UW
|
||||
or eax, PG_NOCACHE
|
||||
mov edi, ebx
|
||||
call commit_pages
|
||||
mov eax, edi
|
||||
ret
|
||||
|
||||
;***************************************************************************
|
||||
; Function
|
||||
; pci_mmio_unmap_page
|
||||
;
|
||||
; Description
|
||||
; unmaps the linear space previously tied to a PCI memory block
|
||||
;
|
||||
; IN: ebx = linear address of space previously allocated by pci_mmio_map
|
||||
; returns eax = 1 if successfully unmapped
|
||||
;
|
||||
; Error codes
|
||||
; eax = -1 if no user PCI access allowed,
|
||||
; eax = 0 if unmapping failed
|
||||
;***************************************************************************
|
||||
|
||||
pci_mmio_unmap:
|
||||
stdcall user_free, ebx
|
||||
ret
|
||||
|
||||
end if
|
||||
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
uglobal
|
||||
align 4
|
||||
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
|
||||
pci_emu_dat: times 30*10 db 0
|
||||
endg
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
align 4
|
||||
sys_pcibios:
|
||||
cmp [pci_access_enabled], 1
|
||||
jne .unsupported_func
|
||||
cmp [pci_bios_entry], 0
|
||||
jz .emulate_bios
|
||||
|
||||
push ds
|
||||
mov ax, pci_data_sel
|
||||
mov ds, ax
|
||||
mov eax, ebp
|
||||
mov ah, 0B1h
|
||||
call pword [cs:pci_bios_entry]
|
||||
pop ds
|
||||
|
||||
jmp .return
|
||||
;-=-=-=-=-=-=-=-=
|
||||
.emulate_bios:
|
||||
cmp ebp, 1 ; PCI_FUNCTION_ID
|
||||
jnz .not_PCI_BIOS_PRESENT
|
||||
mov edx, 'PCI '
|
||||
mov al, [OS_BASE+0x2F0000 + 0x9020]
|
||||
mov bx, [OS_BASE+0x2F0000 + 0x9022]
|
||||
mov cl, [OS_BASE+0x2F0000 + 0x9021]
|
||||
xor ah, ah
|
||||
jmp .return_abcd
|
||||
|
||||
.not_PCI_BIOS_PRESENT:
|
||||
cmp ebp, 2 ; FIND_PCI_DEVICE
|
||||
jne .not_FIND_PCI_DEVICE
|
||||
mov ebx, pci_emu_dat
|
||||
..nxt: cmp [ebx], dx
|
||||
jne ..no
|
||||
cmp [ebx + 2], cx
|
||||
jne ..no
|
||||
dec si
|
||||
jns ..no
|
||||
mov bx, [ebx + 4]
|
||||
xor ah, ah
|
||||
jmp .return_ab
|
||||
..no: cmp word[ebx], 0
|
||||
je ..dev_not_found
|
||||
add ebx, 10
|
||||
jmp ..nxt
|
||||
..dev_not_found:
|
||||
mov ah, 0x86 ; DEVICE_NOT_FOUND
|
||||
jmp .return_a
|
||||
|
||||
.not_FIND_PCI_DEVICE:
|
||||
cmp ebp, 3 ; FIND_PCI_CLASS_CODE
|
||||
jne .not_FIND_PCI_CLASS_CODE
|
||||
mov esi, pci_emu_dat
|
||||
shl ecx, 8
|
||||
..nxt2: cmp [esi], ecx
|
||||
jne ..no2
|
||||
mov bx, [esi]
|
||||
xor ah, ah
|
||||
jmp .return_ab
|
||||
..no2: cmp dword[esi], 0
|
||||
je ..dev_not_found
|
||||
add esi, 10
|
||||
jmp ..nxt2
|
||||
|
||||
.not_FIND_PCI_CLASS_CODE:
|
||||
cmp ebp, 8 ; READ_CONFIG_*
|
||||
jb .not_READ_CONFIG
|
||||
cmp ebp, 0x0A
|
||||
ja .not_READ_CONFIG
|
||||
mov eax, ebp
|
||||
mov ah, bh
|
||||
mov edx, edi
|
||||
mov bh, bl
|
||||
mov bl, dl
|
||||
call pci_read_reg
|
||||
mov ecx, eax
|
||||
xor ah, ah ; SUCCESSFUL
|
||||
jmp .return_abc
|
||||
.not_READ_CONFIG:
|
||||
cmp ebp, 0x0B ; WRITE_CONFIG_*
|
||||
jb .not_WRITE_CONFIG
|
||||
cmp ebp, 0x0D
|
||||
ja .not_WRITE_CONFIG
|
||||
lea eax, [ebp+1]
|
||||
mov ah, bh
|
||||
mov edx, edi
|
||||
mov bh, bl
|
||||
mov bl, dl
|
||||
call pci_write_reg
|
||||
xor ah, ah ; SUCCESSFUL
|
||||
jmp .return_abc
|
||||
.not_WRITE_CONFIG:
|
||||
.unsupported_func:
|
||||
mov ah, 0x81 ; FUNC_NOT_SUPPORTED
|
||||
.return:mov dword[esp + 4 ], edi
|
||||
mov dword[esp + 8], esi
|
||||
.return_abcd:
|
||||
mov dword[esp + 24], edx
|
||||
.return_abc:
|
||||
mov dword[esp + 28], ecx
|
||||
.return_ab:
|
||||
mov dword[esp + 20], ebx
|
||||
.return_a:
|
||||
mov dword[esp + 32], eax
|
||||
ret
|
770
kernel/branches/kolibri-cfg/const.inc
Normal file
770
kernel/branches/kolibri-cfg/const.inc
Normal file
@ -0,0 +1,770 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
dpl0 equ 10010000b ; data read dpl0
|
||||
drw0 equ 10010010b ; data read/write dpl0
|
||||
drw3 equ 11110010b ; data read/write dpl3
|
||||
cpl0 equ 10011010b ; code read dpl0
|
||||
cpl3 equ 11111010b ; code read dpl3
|
||||
|
||||
D32 equ 01000000b ; 32bit segment
|
||||
G32 equ 10000000b ; page gran
|
||||
|
||||
|
||||
;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;;
|
||||
|
||||
CPU_386 equ 3
|
||||
CPU_486 equ 4
|
||||
CPU_PENTIUM equ 5
|
||||
CPU_P6 equ 6
|
||||
CPU_PENTIUM4 equ 0x0F
|
||||
|
||||
CAPS_FPU equ 00 ;on-chip x87 floating point unit
|
||||
CAPS_VME equ 01 ;virtual-mode enhancements
|
||||
CAPS_DE equ 02 ;debugging extensions
|
||||
CAPS_PSE equ 03 ;page-size extensions
|
||||
CAPS_TSC equ 04 ;time stamp counter
|
||||
CAPS_MSR equ 05 ;model-specific registers
|
||||
CAPS_PAE equ 06 ;physical-address extensions
|
||||
CAPS_MCE equ 07 ;machine check exception
|
||||
CAPS_CX8 equ 08 ;CMPXCHG8B instruction
|
||||
CAPS_APIC equ 09 ;on-chip advanced programmable
|
||||
; interrupt controller
|
||||
; 10 ;unused
|
||||
CAPS_SEP equ 11 ;SYSENTER and SYSEXIT instructions
|
||||
CAPS_MTRR equ 12 ;memory-type range registers
|
||||
CAPS_PGE equ 13 ;page global extension
|
||||
CAPS_MCA equ 14 ;machine check architecture
|
||||
CAPS_CMOV equ 15 ;conditional move instructions
|
||||
CAPS_PAT equ 16 ;page attribute table
|
||||
|
||||
CAPS_PSE36 equ 17 ;page-size extensions
|
||||
CAPS_PSN equ 18 ;processor serial number
|
||||
CAPS_CLFLUSH equ 19 ;CLFUSH instruction
|
||||
|
||||
CAPS_DS equ 21 ;debug store
|
||||
CAPS_ACPI equ 22 ;thermal monitor and software
|
||||
;controlled clock supported
|
||||
CAPS_MMX equ 23 ;MMX instructions
|
||||
CAPS_FXSR equ 24 ;FXSAVE and FXRSTOR instructions
|
||||
CAPS_SSE equ 25 ;SSE instructions
|
||||
CAPS_SSE2 equ 26 ;SSE2 instructions
|
||||
CAPS_SS equ 27 ;self-snoop
|
||||
CAPS_HTT equ 28 ;hyper-threading technology
|
||||
CAPS_TM equ 29 ;thermal monitor supported
|
||||
CAPS_IA64 equ 30 ;IA64 capabilities
|
||||
CAPS_PBE equ 31 ;pending break enable
|
||||
|
||||
;ecx
|
||||
CAPS_SSE3 equ 32 ;SSE3 instructions
|
||||
; 33
|
||||
; 34
|
||||
CAPS_MONITOR equ 35 ;MONITOR/MWAIT instructions
|
||||
CAPS_DS_CPL equ 36 ;
|
||||
CAPS_VMX equ 37 ;virtual mode extensions
|
||||
; 38 ;
|
||||
CAPS_EST equ 39 ;enhansed speed step
|
||||
CAPS_TM2 equ 40 ;thermal monitor2 supported
|
||||
; 41
|
||||
CAPS_CID equ 42 ;
|
||||
; 43
|
||||
; 44
|
||||
CAPS_CX16 equ 45 ;CMPXCHG16B instruction
|
||||
CAPS_xTPR equ 46 ;
|
||||
;
|
||||
;reserved
|
||||
;
|
||||
;ext edx /ecx
|
||||
CAPS_SYSCAL equ 64 ;
|
||||
CAPS_XD equ 65 ;execution disable
|
||||
CAPS_FFXSR equ 66 ;
|
||||
CAPS_RDTSCP equ 67 ;
|
||||
CAPS_X64 equ 68 ;
|
||||
CAPS_3DNOW equ 69 ;
|
||||
CAPS_3DNOWEXT equ 70 ;
|
||||
CAPS_LAHF equ 71 ;
|
||||
CAPS_CMP_LEG equ 72 ;
|
||||
CAPS_SVM equ 73 ;secure virual machine
|
||||
CAPS_ALTMOVCR8 equ 74 ;
|
||||
|
||||
; CPU MSR names
|
||||
MSR_SYSENTER_CS equ 0x174
|
||||
MSR_SYSENTER_ESP equ 0x175
|
||||
MSR_SYSENTER_EIP equ 0x176
|
||||
MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register
|
||||
MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register
|
||||
|
||||
CR0_PE equ 0x00000001 ;protected mode
|
||||
CR0_MP equ 0x00000002 ;monitor fpu
|
||||
CR0_EM equ 0x00000004 ;fpu emulation
|
||||
CR0_TS equ 0x00000008 ;task switch
|
||||
CR0_ET equ 0x00000010 ;extension type hardcoded to 1
|
||||
CR0_NE equ 0x00000020 ;numeric error
|
||||
CR0_WP equ 0x00010000 ;write protect
|
||||
CR0_AM equ 0x00040000 ;alignment check
|
||||
CR0_NW equ 0x20000000 ;not write-through
|
||||
CR0_CD equ 0x40000000 ;cache disable
|
||||
CR0_PG equ 0x80000000 ;paging
|
||||
|
||||
|
||||
CR4_VME equ 0x0001
|
||||
CR4_PVI equ 0x0002
|
||||
CR4_TSD equ 0x0004
|
||||
CR4_DE equ 0x0008
|
||||
CR4_PSE equ 0x0010
|
||||
CR4_PAE equ 0x0020
|
||||
CR4_MCE equ 0x0040
|
||||
CR4_PGE equ 0x0080
|
||||
CR4_PCE equ 0x0100
|
||||
CR4_OSFXSR equ 0x0200
|
||||
CR4_OSXMMEXPT equ 0x0400
|
||||
|
||||
SSE_IE equ 0x0001
|
||||
SSE_DE equ 0x0002
|
||||
SSE_ZE equ 0x0004
|
||||
SSE_OE equ 0x0008
|
||||
SSE_UE equ 0x0010
|
||||
SSE_PE equ 0x0020
|
||||
SSE_DAZ equ 0x0040
|
||||
SSE_IM equ 0x0080
|
||||
SSE_DM equ 0x0100
|
||||
SSE_ZM equ 0x0200
|
||||
SSE_OM equ 0x0400
|
||||
SSE_UM equ 0x0800
|
||||
SSE_PM equ 0x1000
|
||||
SSE_FZ equ 0x8000
|
||||
|
||||
SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM)
|
||||
|
||||
|
||||
struc TSS
|
||||
{
|
||||
._back rw 2
|
||||
._esp0 rd 1
|
||||
._ss0 rw 2
|
||||
._esp1 rd 1
|
||||
._ss1 rw 2
|
||||
._esp2 rd 1
|
||||
._ss2 rw 2
|
||||
._cr3 rd 1
|
||||
._eip rd 1
|
||||
._eflags rd 1
|
||||
._eax rd 1
|
||||
._ecx rd 1
|
||||
._edx rd 1
|
||||
._ebx rd 1
|
||||
._esp rd 1
|
||||
._ebp rd 1
|
||||
._esi rd 1
|
||||
._edi rd 1
|
||||
._es rw 2
|
||||
._cs rw 2
|
||||
._ss rw 2
|
||||
._ds rw 2
|
||||
._fs rw 2
|
||||
._gs rw 2
|
||||
._ldt rw 2
|
||||
._trap rw 1
|
||||
._io rw 1
|
||||
rb 24
|
||||
._io_map_0 rb 4096
|
||||
._io_map_1 rb 4096
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
TSS TSS
|
||||
end virtual
|
||||
|
||||
TSS_SIZE equ (128+8192)
|
||||
|
||||
OS_BASE equ 0x80000000
|
||||
|
||||
window_data equ (OS_BASE+0x0001000)
|
||||
|
||||
CURRENT_TASK equ (OS_BASE+0x0003000)
|
||||
TASK_COUNT equ (OS_BASE+0x0003004)
|
||||
TASK_BASE equ (OS_BASE+0x0003010)
|
||||
TASK_DATA equ (OS_BASE+0x0003020)
|
||||
TASK_EVENT equ (OS_BASE+0x0003020)
|
||||
|
||||
mouseunder equ (OS_BASE+0x0006900)
|
||||
CDDataBuf equ (OS_BASE+0x0007000)
|
||||
FLOPPY_BUFF equ (OS_BASE+0x0008000)
|
||||
ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused
|
||||
idts equ (OS_BASE+0x000B100)
|
||||
WIN_STACK equ (OS_BASE+0x000C000)
|
||||
WIN_POS equ (OS_BASE+0x000C400)
|
||||
FDD_BUFF equ (OS_BASE+0x000D000)
|
||||
|
||||
;unused ? only one reference
|
||||
ENABLE_TASKSWITCH equ (OS_BASE+0x000E000)
|
||||
|
||||
PUTPIXEL equ (OS_BASE+0x000E020)
|
||||
GETPIXEL equ (OS_BASE+0x000E024)
|
||||
|
||||
;unused ? only one reference
|
||||
BANK_SWITCH equ (OS_BASE+0x000E030)
|
||||
|
||||
;unused ? store mousepointer
|
||||
MOUSE_PICTURE equ (OS_BASE+0x000F200)
|
||||
|
||||
MOUSE_VISIBLE equ (OS_BASE+0x000F204)
|
||||
WIN_TEMP_XY equ (OS_BASE+0x000F300)
|
||||
KEY_COUNT equ (OS_BASE+0x000F400)
|
||||
KEY_BUFF equ (OS_BASE+0x000F401)
|
||||
|
||||
BTN_COUNT equ (OS_BASE+0x000F500)
|
||||
BTN_BUFF equ (OS_BASE+0x000F501)
|
||||
|
||||
CPU_FREQ equ (OS_BASE+0x000F600)
|
||||
|
||||
;unused ? no active references
|
||||
MOUSE_PORT equ (OS_BASE+0x000F604)
|
||||
|
||||
;unused
|
||||
PS2_CHUNK equ (OS_BASE+0x000FB00)
|
||||
|
||||
MOUSE_SCROLL_H equ (OS_BASE+0x000FB08)
|
||||
MOUSE_X equ (OS_BASE+0x000FB0A)
|
||||
MOUSE_Y equ (OS_BASE+0x000FB0C)
|
||||
MOUSE_SCROLL_V equ (OS_BASE+0x000FB0E)
|
||||
|
||||
MOUSE_COLOR_MEM equ (OS_BASE+0x000FB10)
|
||||
COLOR_TEMP equ (OS_BASE+0x000FB30)
|
||||
BTN_DOWN equ (OS_BASE+0x000FB40)
|
||||
MOUSE_DOWN equ (OS_BASE+0x000FB44)
|
||||
X_UNDER equ (OS_BASE+0x000FB4A)
|
||||
Y_UNDER equ (OS_BASE+0x000FB4C)
|
||||
ScreenBPP equ (OS_BASE+0x000FBF1)
|
||||
|
||||
;unused ? only one reference
|
||||
MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF)
|
||||
|
||||
Screen_Max_X equ (OS_BASE+0x000FE00)
|
||||
Screen_Max_Y equ (OS_BASE+0x000FE04)
|
||||
BytesPerScanLine equ (OS_BASE+0x000FE08)
|
||||
SCR_MODE equ (OS_BASE+0x000FE0C)
|
||||
|
||||
LFBAddress equ (OS_BASE+0x000FE80)
|
||||
BTN_ADDR equ (OS_BASE+0x000FE88)
|
||||
MEM_AMOUNT equ (OS_BASE+0x000FE8C)
|
||||
|
||||
SYS_SHUTDOWN equ (OS_BASE+0x000FF00)
|
||||
TASK_ACTIVATE equ (OS_BASE+0x000FF01)
|
||||
|
||||
REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0)
|
||||
BACKGROUND_CHANGED equ (OS_BASE+0x000FFF1)
|
||||
BANK_RW equ (OS_BASE+0x000FFF2)
|
||||
MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4)
|
||||
DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5)
|
||||
DONT_SWITCH equ (OS_BASE+0x000FFFF)
|
||||
|
||||
TMP_STACK_TOP equ 0x006CC00
|
||||
|
||||
FONT_II equ (OS_BASE+0x006DC00)
|
||||
FONT_I equ (OS_BASE+0x006E600)
|
||||
|
||||
sys_pgdir equ (OS_BASE+0x006F000)
|
||||
|
||||
DRIVE_DATA equ (OS_BASE+0x0070000)
|
||||
|
||||
SLOT_BASE equ (OS_BASE+0x0080000)
|
||||
|
||||
;unused
|
||||
TMP_BUFF equ (OS_BASE+0x0090000)
|
||||
|
||||
VGABasePtr equ (OS_BASE+0x00A0000)
|
||||
|
||||
RAMDISK equ (OS_BASE+0x0100000)
|
||||
RAMDISK_FAT equ (OS_BASE+0x0280000)
|
||||
FLOPPY_FAT equ (OS_BASE+0x0282000)
|
||||
|
||||
IDE_DMA equ 0x284000
|
||||
|
||||
BgrAuxTable equ (OS_BASE+0x0298000)
|
||||
; unused?
|
||||
SB16Buffer equ (OS_BASE+0x2A0000)
|
||||
SB16_Status equ (OS_BASE+0x02B0000)
|
||||
|
||||
BUTTON_INFO equ (OS_BASE+0x02C0000)
|
||||
RESERVED_PORTS equ (OS_BASE+0x02D0000)
|
||||
IRQ_SAVE equ (OS_BASE+0x02E0000)
|
||||
BOOT_VAR equ (OS_BASE+0x02f0000)
|
||||
|
||||
stack_data_start equ (OS_BASE+0x0300000)
|
||||
eth_data_start equ (OS_BASE+0x0300000)
|
||||
stack_data equ (OS_BASE+0x0304000)
|
||||
stack_data_end equ (OS_BASE+0x031ffff)
|
||||
resendQ equ (OS_BASE+0x0320000)
|
||||
VMODE_BASE equ (OS_BASE+0x0328000)
|
||||
skin_data equ (OS_BASE+0x0330000)
|
||||
draw_data equ (OS_BASE+0x0338000);
|
||||
|
||||
BgrDrawMode equ (OS_BASE+0x033BFF4)
|
||||
BgrDataWidth equ (OS_BASE+0x033BFF8)
|
||||
BgrDataHeight equ (OS_BASE+0x033BFFC)
|
||||
|
||||
sys_pgmap equ (OS_BASE+0x033C000)
|
||||
|
||||
UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000)
|
||||
|
||||
virtual at (OS_BASE+0x05FFF80)
|
||||
tss TSS
|
||||
end virtual
|
||||
|
||||
HEAP_BASE equ (OS_BASE+0x0800000)
|
||||
HEAP_MIN_SIZE equ 0x01000000
|
||||
|
||||
page_tabs equ 0xFDC00000
|
||||
app_page_tabs equ 0xFDC00000
|
||||
kernel_tabs equ (page_tabs+ (OS_BASE shr 10)) ;0xFDE00000
|
||||
master_tab equ (page_tabs+ (page_tabs shr 10)) ;0xFDFF70000
|
||||
|
||||
LFB_BASE equ 0xFE000000
|
||||
|
||||
|
||||
new_app_base equ 0;
|
||||
|
||||
twdw equ 0x2000 ;(CURRENT_TASK-window_data)
|
||||
|
||||
std_application_base_address equ new_app_base
|
||||
RING0_STACK_SIZE equ (0x2000 - 512) ;512 áàéò äëÿ êîíòåêñòà FPU
|
||||
|
||||
REG_SS equ (RING0_STACK_SIZE-4)
|
||||
REG_APP_ESP equ (RING0_STACK_SIZE-8)
|
||||
REG_EFLAGS equ (RING0_STACK_SIZE-12)
|
||||
REG_CS equ (RING0_STACK_SIZE-16)
|
||||
REG_EIP equ (RING0_STACK_SIZE-20)
|
||||
REG_EAX equ (RING0_STACK_SIZE-24)
|
||||
REG_ECX equ (RING0_STACK_SIZE-28)
|
||||
REG_EDX equ (RING0_STACK_SIZE-32)
|
||||
REG_EBX equ (RING0_STACK_SIZE-36)
|
||||
REG_ESP equ (RING0_STACK_SIZE-40) ;RING0_STACK_SIZE-20
|
||||
REG_EBP equ (RING0_STACK_SIZE-44)
|
||||
REG_ESI equ (RING0_STACK_SIZE-48)
|
||||
REG_EDI equ (RING0_STACK_SIZE-52)
|
||||
REG_RET equ (RING0_STACK_SIZE-56) ;irq0.return
|
||||
|
||||
|
||||
PG_UNMAP equ 0x000
|
||||
PG_MAP equ 0x001
|
||||
PG_WRITE equ 0x002
|
||||
PG_SW equ 0x003
|
||||
PG_USER equ 0x005
|
||||
PG_UW equ 0x007
|
||||
PG_NOCACHE equ 0x018
|
||||
PG_LARGE equ 0x080
|
||||
PG_GLOBAL equ 0x100
|
||||
|
||||
PG_SHARED equ 0x200
|
||||
|
||||
;;;;;;;;;;;boot time variables
|
||||
|
||||
;BOOT_BPP equ 0x9000 ;byte bits per pixel
|
||||
BOOT_SCANLINE equ 0x9001 ;word scanline length
|
||||
BOOT_VESA_MODE equ 0x9008 ;word vesa video mode
|
||||
;;BOOT_X_RES equ 0x900A ;word X res
|
||||
;;BOOT_Y_RES equ 0x900C ;word Y res
|
||||
;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used
|
||||
BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch
|
||||
BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address
|
||||
BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration
|
||||
BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display)
|
||||
BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled
|
||||
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data
|
||||
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no
|
||||
BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr
|
||||
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount
|
||||
|
||||
TMP_FILE_NAME equ 0
|
||||
TMP_CMD_LINE equ 1024
|
||||
TMP_ICON_OFFS equ 1280
|
||||
|
||||
|
||||
EVENT_REDRAW equ 0x00000001
|
||||
EVENT_KEY equ 0x00000002
|
||||
EVENT_BUTTON equ 0x00000004
|
||||
EVENT_BACKGROUND equ 0x00000010
|
||||
EVENT_MOUSE equ 0x00000020
|
||||
EVENT_IPC equ 0x00000040
|
||||
EVENT_NETWORK equ 0x00000080
|
||||
EVENT_DEBUG equ 0x00000100
|
||||
EVENT_EXTENDED equ 0x00000200
|
||||
|
||||
EV_INTR equ 1
|
||||
|
||||
struc THR_DATA
|
||||
{
|
||||
rb (8192-512)
|
||||
.pl0_stack:
|
||||
.fpu_state rb 512
|
||||
.tls_page rb 4096
|
||||
.pdbr rb 4096
|
||||
}
|
||||
|
||||
THR_DATA_SIZE equ 4096*4
|
||||
|
||||
virtual at (OS_BASE-THR_DATA_SIZE)
|
||||
thr_data THR_DATA
|
||||
end virtual
|
||||
|
||||
struc SYS_VARS
|
||||
{ .bpp dd ?
|
||||
.scanline dd ?
|
||||
.vesa_mode dd ?
|
||||
.x_res dd ?
|
||||
.y_res dd ?
|
||||
}
|
||||
|
||||
struc APPOBJ ;common object header
|
||||
{
|
||||
.magic dd ? ;
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
};
|
||||
|
||||
virtual at 0
|
||||
APPOBJ APPOBJ
|
||||
end virtual
|
||||
|
||||
APP_OBJ_OFFSET equ 48
|
||||
APP_EV_OFFSET equ 40
|
||||
|
||||
struc CURSOR
|
||||
{
|
||||
;common object header
|
||||
.magic dd ? ;'CURS'
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
|
||||
;cursor data
|
||||
.base dd ? ;allocated memory
|
||||
.hot_x dd ? ;hotspot coords
|
||||
.hot_y dd ?
|
||||
|
||||
.list_next dd ? ;next cursor in cursor list
|
||||
.list_prev dd ? ;prev cursor in cursor list
|
||||
.dev_obj dd ? ;device depended data
|
||||
|
||||
.sizeof:
|
||||
}
|
||||
virtual at 0
|
||||
CURSOR CURSOR
|
||||
end virtual
|
||||
|
||||
|
||||
struc EVENT
|
||||
{
|
||||
.magic dd ? ;'EVNT'
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
|
||||
.id dd ? ;event uid
|
||||
.state dd ? ;internal flags
|
||||
.code dd ?
|
||||
rd 5
|
||||
.size = $ - .magic
|
||||
.codesize = $ - .code
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
EVENT EVENT
|
||||
end virtual
|
||||
|
||||
|
||||
struc SMEM
|
||||
{
|
||||
.bk dd ?
|
||||
.fd dd ? ;+4
|
||||
.base dd ? ;+8
|
||||
.size dd ? ;+12
|
||||
.access dd ? ;+16
|
||||
.refcount dd ? ;+20
|
||||
.name rb 32 ;+24
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
struc SMAP
|
||||
{
|
||||
.magic dd ? ; SMAP
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
|
||||
.base dd ? ;mapped base
|
||||
.parent dd ? ;SMEM
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
SMEM SMEM
|
||||
end virtual
|
||||
|
||||
virtual at 0
|
||||
SMAP SMAP
|
||||
end virtual
|
||||
|
||||
struc DLLDESCR
|
||||
{
|
||||
.bk dd ?
|
||||
.fd dd ? ;+4
|
||||
.data dd ? ;+8
|
||||
.size dd ? ;+12
|
||||
.timestamp dq ?
|
||||
.refcount dd ?
|
||||
.defaultbase dd ?
|
||||
.coff_hdr dd ?
|
||||
.symbols_ptr dd ?
|
||||
.symbols_num dd ?
|
||||
.symbols_lim dd ?
|
||||
.exports dd ? ;export table
|
||||
.name:
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
struc HDLL
|
||||
{
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
|
||||
.base dd ? ;mapped base
|
||||
.size dd ? ;mapped size
|
||||
.refcount dd ? ;reference counter for this process and this lib
|
||||
.parent dd ? ;DLLDESCR
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
DLLDESCR DLLDESCR
|
||||
end virtual
|
||||
|
||||
virtual at 0
|
||||
HDLL HDLL
|
||||
end virtual
|
||||
|
||||
struc display_t
|
||||
{
|
||||
.x dd ?
|
||||
.y dd ?
|
||||
.width dd ?
|
||||
.height dd ?
|
||||
.bpp dd ?
|
||||
.vrefresh dd ?
|
||||
.pitch dd ?
|
||||
.lfb dd ?
|
||||
|
||||
.modes dd ?
|
||||
.ddev dd ?
|
||||
.connector dd ?
|
||||
.crtc dd ?
|
||||
|
||||
.cr_list.next dd ?
|
||||
.cr_list.prev dd ?
|
||||
|
||||
.cursor dd ?
|
||||
|
||||
.init_cursor dd ?
|
||||
.select_cursor dd ?
|
||||
.show_cursor dd ?
|
||||
.move_cursor dd ?
|
||||
.restore_cursor dd ?
|
||||
.disable_mouse dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
display_t display_t
|
||||
end virtual
|
||||
|
||||
struc HEAP_DATA
|
||||
{
|
||||
.mutex rd 1
|
||||
.refcount rd 1
|
||||
.heap_base rd 1
|
||||
.heap_top rd 1
|
||||
.app_mem rd 1
|
||||
}
|
||||
|
||||
HEAP_DATA_SIZE equ 20
|
||||
virtual at 0
|
||||
HEAP_DATA HEAP_DATA
|
||||
end virtual
|
||||
|
||||
struc BOOT_DATA
|
||||
{ .bpp dd ?
|
||||
.scanline dd ?
|
||||
.vesa_mode dd ?
|
||||
.x_res dd ?
|
||||
.y_res dd ?
|
||||
.mouse_port dd ?
|
||||
.bank_switch dd ?
|
||||
.lfb dd ?
|
||||
.vesa_mem dd ?
|
||||
.log dd ?
|
||||
.direct_lfb dd ?
|
||||
.pci_data dd ?
|
||||
; dd ?
|
||||
.vrr dd ?
|
||||
.ide_base dd ?
|
||||
.mem_amount dd ?
|
||||
.pages_count dd ?
|
||||
.pagemap_size dd ?
|
||||
.kernel_max dd ?
|
||||
.kernel_pages dd ?
|
||||
.kernel_tables dd ?
|
||||
|
||||
.cpu_vendor dd ?
|
||||
dd ?
|
||||
dd ?
|
||||
.cpu_sign dd ?
|
||||
.cpu_info dd ?
|
||||
.cpu_caps dd ?
|
||||
dd ?
|
||||
dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
BOOT_DATA BOOT_DATA
|
||||
end virtual
|
||||
|
||||
struc MEM_STATE
|
||||
{ .mutex rd 1
|
||||
.smallmap rd 1
|
||||
.treemap rd 1
|
||||
.topsize rd 1
|
||||
.top rd 1
|
||||
.smallbins rd 4*32
|
||||
.treebins rd 32
|
||||
}
|
||||
|
||||
struc PG_DATA
|
||||
{ .mem_amount dd ?
|
||||
.vesa_mem dd ?
|
||||
.pages_count dd ?
|
||||
.pages_free dd ?
|
||||
.pages_faults dd ?
|
||||
.pagemap_size dd ?
|
||||
.kernel_pages dd ?
|
||||
.kernel_tables dd ?
|
||||
.sys_page_dir dd ?
|
||||
.pg_mutex dd ?
|
||||
}
|
||||
|
||||
;struc LIB
|
||||
;{ .lib_name rb 16
|
||||
; .lib_base dd ?
|
||||
; .lib_start dd ?
|
||||
; .export dd ?
|
||||
; .import dd ?
|
||||
;}
|
||||
|
||||
struc SRV
|
||||
{
|
||||
.srv_name rb 16 ;ASCIIZ string
|
||||
.magic dd ? ;+0x10 ;'SRV '
|
||||
.size dd ? ;+0x14 ;size of structure SRV
|
||||
.fd dd ? ;+0x18 ;next SRV descriptor
|
||||
.bk dd ? ;+0x1C ;prev SRV descriptor
|
||||
.base dd ? ;+0x20 ;service base address
|
||||
.entry dd ? ;+0x24 ;service START function
|
||||
.srv_proc dd ? ;+0x28 ;user mode service handler
|
||||
.srv_proc_ex dd ? ;+0x2C ;kernel mode service handler
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
SRV_FD_OFFSET equ 0x18
|
||||
|
||||
DRV_ENTRY equ 1
|
||||
DRV_EXIT equ -1
|
||||
|
||||
struc COFF_HEADER
|
||||
{ .machine dw ?
|
||||
.nSections dw ?
|
||||
.DataTime dd ?
|
||||
.pSymTable dd ?
|
||||
.nSymbols dd ?
|
||||
.optHeader dw ?
|
||||
.flags dw ?
|
||||
};
|
||||
|
||||
|
||||
struc COFF_SECTION
|
||||
{ .Name rb 8
|
||||
.VirtualSize dd ?
|
||||
.VirtualAddress dd ?
|
||||
.SizeOfRawData dd ?
|
||||
.PtrRawData dd ?
|
||||
.PtrReloc dd ?
|
||||
.PtrLinenumbers dd ?
|
||||
.NumReloc dw ?
|
||||
.NumLinenum dw ?
|
||||
.Characteristics dd ?
|
||||
}
|
||||
COFF_SECTION_SIZE equ 40
|
||||
|
||||
struc COFF_RELOC
|
||||
{ .VirtualAddress dd ?
|
||||
.SymIndex dd ?
|
||||
.Type dw ?
|
||||
}
|
||||
|
||||
struc COFF_SYM
|
||||
{ .Name rb 8
|
||||
.Value dd ?
|
||||
.SectionNumber dw ?
|
||||
.Type dw ?
|
||||
.StorageClass db ?
|
||||
.NumAuxSymbols db ?
|
||||
}
|
||||
CSYM_SIZE equ 18
|
||||
|
||||
struc IOCTL
|
||||
{ .handle dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
IOCTL IOCTL
|
||||
end virtual
|
||||
|
||||
;virtual at 0
|
||||
; LIB LIB
|
||||
;end virtual
|
||||
|
||||
virtual at 0
|
||||
SRV SRV
|
||||
end virtual
|
||||
|
||||
virtual at 0
|
||||
CFH COFF_HEADER
|
||||
end virtual
|
||||
|
||||
virtual at 0
|
||||
CFS COFF_SECTION
|
||||
end virtual
|
||||
|
||||
virtual at 0
|
||||
CRELOC COFF_RELOC
|
||||
end virtual
|
||||
|
||||
virtual at 0
|
||||
CSYM COFF_SYM
|
||||
end virtual
|
297
kernel/branches/kolibri-cfg/core/conf_lib.inc
Normal file
297
kernel/branches/kolibri-cfg/core/conf_lib.inc
Normal file
@ -0,0 +1,297 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
;Loading configuration from ini file
|
||||
; {SPraid.simba}
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
$Revision$
|
||||
|
||||
iglobal
|
||||
conf_path_sect: db 'path',0
|
||||
|
||||
conf_fname db '/sys/sys.conf',0
|
||||
endg
|
||||
; set soke kernel configuration
|
||||
proc set_kernel_conf
|
||||
locals
|
||||
par db 30 dup(?)
|
||||
endl
|
||||
|
||||
pushad
|
||||
;[gui]
|
||||
;mouse_speed
|
||||
|
||||
lea eax,[par]
|
||||
push eax
|
||||
invoke ini.get_str,conf_fname, ugui, ugui_mouse_speed,\
|
||||
eax,30, ugui_mouse_speed_def
|
||||
pop eax
|
||||
stdcall strtoint,eax
|
||||
mov [mouse_speed_factor], ax
|
||||
|
||||
;mouse_delay
|
||||
lea eax,[par]
|
||||
push eax
|
||||
invoke ini.get_str,conf_fname, ugui, ugui_mouse_delay,\
|
||||
eax,30, ugui_mouse_delay_def
|
||||
pop eax
|
||||
stdcall strtoint,eax
|
||||
mov [mouse_delay], eax
|
||||
|
||||
|
||||
;midibase
|
||||
lea eax,[par]
|
||||
push eax
|
||||
invoke ini.get_str,conf_fname, udev, udev_midibase, eax,30, udev_midibase_def
|
||||
pop eax
|
||||
stdcall strtoint,eax
|
||||
|
||||
cmp eax, 0x100
|
||||
jb @f
|
||||
cmp eax, 0x10000
|
||||
jae @f
|
||||
mov [midi_base], ax
|
||||
mov [mididp], eax
|
||||
inc eax
|
||||
mov [midisp], eax
|
||||
@@:
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
iglobal
|
||||
ugui db 'gui',0
|
||||
ugui_mouse_speed db 'mouse_speed',0
|
||||
ugui_mouse_speed_def db '2',0
|
||||
ugui_mouse_delay db 'mouse_delay',0
|
||||
ugui_mouse_delay_def db '0x00A',0
|
||||
|
||||
udev db 'dev',0
|
||||
udev_midibase db 'midibase',0
|
||||
udev_midibase_def db '0x320',0
|
||||
endg
|
||||
;set up netvork configuration
|
||||
proc set_network_conf
|
||||
locals
|
||||
par db 30 dup(?)
|
||||
endl
|
||||
pushad
|
||||
|
||||
;[net]
|
||||
;active
|
||||
lea eax,[par]
|
||||
invoke ini.get_int,conf_fname, unet, unet_active, 0
|
||||
or eax,eax
|
||||
jz .do_not_set_net
|
||||
mov eax, [stack_config]
|
||||
and eax, 0xFFFFFF80
|
||||
add eax, 3
|
||||
mov [stack_config], eax
|
||||
call ash_eth_enable
|
||||
|
||||
;addr
|
||||
lea eax,[par]
|
||||
push eax
|
||||
invoke ini.get_str,conf_fname, unet, unet_addr, eax,30, unet_def
|
||||
pop eax
|
||||
stdcall do_inet_adr,eax
|
||||
mov [stack_ip], eax
|
||||
|
||||
;mask
|
||||
lea eax,[par]
|
||||
push eax
|
||||
invoke ini.get_str,conf_fname, unet, unet_mask, eax,30, unet_def
|
||||
pop eax
|
||||
stdcall do_inet_adr,eax
|
||||
mov [subnet_mask], eax
|
||||
|
||||
;gate
|
||||
lea eax,[par]
|
||||
push eax
|
||||
invoke ini.get_str,conf_fname, unet, unet_gate, eax,30, unet_def
|
||||
pop eax
|
||||
stdcall do_inet_adr,eax
|
||||
mov [gateway_ip], eax
|
||||
.do_not_set_net:
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
endp
|
||||
iglobal
|
||||
unet db 'net',0
|
||||
unet_active db 'active',0
|
||||
unet_addr db 'addr',0
|
||||
unet_mask db 'mask',0
|
||||
unet_gate db 'gate',0
|
||||
unet_def db 0
|
||||
endg
|
||||
; convert string to DWord
|
||||
proc strtoint stdcall,strs
|
||||
pushad
|
||||
|
||||
mov eax,[strs]
|
||||
inc eax
|
||||
mov bl,[eax]
|
||||
cmp bl,'x'
|
||||
je .hex
|
||||
cmp bl,'X'
|
||||
je .hex
|
||||
jmp .dec
|
||||
.hex:
|
||||
inc eax
|
||||
stdcall strtoint_hex,eax
|
||||
jmp .exit
|
||||
.dec:
|
||||
dec eax
|
||||
stdcall strtoint_dec,eax
|
||||
.exit:
|
||||
mov [esp+28],eax
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
; convert string to DWord for decimal value
|
||||
proc strtoint_dec stdcall,strs
|
||||
pushad
|
||||
xor edx,edx
|
||||
; ¯®¨áª ª®æ
|
||||
mov esi,[strs]
|
||||
@@:
|
||||
lodsb
|
||||
or al,al
|
||||
jnz @b
|
||||
mov ebx,esi
|
||||
mov esi,[strs]
|
||||
dec ebx
|
||||
sub ebx,esi
|
||||
mov ecx,1
|
||||
|
||||
@@:
|
||||
dec ebx
|
||||
or ebx,ebx
|
||||
jz @f
|
||||
imul ecx,ecx,10 ; ¯®à冷ª
|
||||
jmp @b
|
||||
@@:
|
||||
|
||||
xchg ebx,ecx
|
||||
|
||||
|
||||
xor ecx,ecx
|
||||
|
||||
|
||||
@@:
|
||||
xor eax,eax
|
||||
lodsb
|
||||
cmp al,0
|
||||
je .eend
|
||||
|
||||
sub al,30h
|
||||
imul ebx
|
||||
add ecx,eax
|
||||
push ecx
|
||||
xchg eax,ebx
|
||||
mov ecx,10
|
||||
div ecx
|
||||
xchg eax,ebx
|
||||
pop ecx
|
||||
jmp @b
|
||||
|
||||
.eend:
|
||||
mov [esp+28],ecx
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
;convert string to DWord for hex value
|
||||
proc strtoint_hex stdcall,strs
|
||||
pushad
|
||||
xor edx,edx
|
||||
|
||||
mov esi,[strs]
|
||||
mov ebx,1
|
||||
add esi,1
|
||||
|
||||
@@:
|
||||
lodsb
|
||||
or al,al
|
||||
jz @f
|
||||
shl ebx,4
|
||||
jmp @b
|
||||
@@:
|
||||
xor ecx,ecx
|
||||
mov esi,[strs]
|
||||
|
||||
@@:
|
||||
xor eax,eax
|
||||
lodsb
|
||||
cmp al,0
|
||||
je .eend
|
||||
|
||||
cmp al,'a'
|
||||
jae .bm
|
||||
cmp al,'A'
|
||||
jae .bb
|
||||
jmp .cc
|
||||
.bm: ; 57h
|
||||
sub al,57h
|
||||
jmp .do
|
||||
|
||||
.bb: ; 37h
|
||||
sub al,37h
|
||||
jmp .do
|
||||
|
||||
.cc: ; 30h
|
||||
sub al,30h
|
||||
|
||||
.do:
|
||||
imul ebx
|
||||
add ecx,eax
|
||||
shr ebx,4
|
||||
|
||||
jmp @b
|
||||
|
||||
.eend:
|
||||
mov [esp+28],ecx
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
; convert string to DWord for IP addres
|
||||
proc do_inet_adr stdcall,strs
|
||||
pushad
|
||||
|
||||
mov esi,[strs]
|
||||
mov ebx,0
|
||||
.next:
|
||||
push esi
|
||||
@@:
|
||||
lodsb
|
||||
or al,al
|
||||
jz @f
|
||||
cmp al,'.'
|
||||
jz @f
|
||||
jmp @b
|
||||
@@:
|
||||
mov cl, al
|
||||
mov [esi-1],byte 0
|
||||
;pop eax
|
||||
call strtoint_dec
|
||||
rol eax,24
|
||||
ror ebx,8
|
||||
add ebx,eax
|
||||
or cl,cl
|
||||
jz @f
|
||||
jmp .next
|
||||
@@:
|
||||
mov [esp+28],ebx
|
||||
popad
|
||||
ret
|
||||
endp
|
429
kernel/branches/kolibri-cfg/core/debug.inc
Normal file
429
kernel/branches/kolibri-cfg/core/debug.inc
Normal file
@ -0,0 +1,429 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
; diamond, 2006
|
||||
sys_debug_services:
|
||||
cmp ebx, 9
|
||||
ja @f
|
||||
jmp dword [sys_debug_services_table+ebx*4]
|
||||
@@: ret
|
||||
iglobal
|
||||
align 4
|
||||
sys_debug_services_table:
|
||||
dd debug_set_event_data
|
||||
dd debug_getcontext
|
||||
dd debug_setcontext
|
||||
dd debug_detach
|
||||
dd debug_suspend
|
||||
dd debug_resume
|
||||
dd debug_read_process_memory
|
||||
dd debug_write_process_memory
|
||||
dd debug_terminate
|
||||
dd debug_set_drx
|
||||
endg
|
||||
debug_set_event_data:
|
||||
; in: ecx = pointer
|
||||
; destroys eax
|
||||
mov eax, [current_slot]
|
||||
mov [eax+APPDATA.dbg_event_mem], ecx
|
||||
ret
|
||||
|
||||
get_debuggee_slot:
|
||||
; in: ecx=PID
|
||||
; out: CF=1 if error
|
||||
; CF=0 and eax=slot*0x20 if ok
|
||||
; out: interrupts disabled
|
||||
cli
|
||||
mov eax, ecx
|
||||
call pid_to_slot
|
||||
test eax, eax
|
||||
jz .ret_bad
|
||||
shl eax, 5
|
||||
push ebx
|
||||
mov ebx, [CURRENT_TASK]
|
||||
cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx
|
||||
pop ebx
|
||||
jnz .ret_bad
|
||||
; clc ; automatically
|
||||
ret
|
||||
.ret_bad:
|
||||
stc
|
||||
ret
|
||||
|
||||
debug_detach:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ebx
|
||||
call get_debuggee_slot
|
||||
jc .ret
|
||||
and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0
|
||||
call do_resume
|
||||
.ret:
|
||||
sti
|
||||
ret
|
||||
|
||||
debug_terminate:
|
||||
; in: ecx=pid
|
||||
call get_debuggee_slot
|
||||
jc debug_detach.ret
|
||||
mov ecx, eax
|
||||
shr ecx, 5
|
||||
; push 2
|
||||
; pop ebx
|
||||
mov edx,esi
|
||||
jmp sysfn_terminate
|
||||
|
||||
debug_suspend:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ecx
|
||||
cli
|
||||
mov eax, ecx
|
||||
call pid_to_slot
|
||||
shl eax, 5
|
||||
jz .ret
|
||||
mov cl, [CURRENT_TASK+eax+TASKDATA.state] ; process state
|
||||
test cl, cl
|
||||
jz .1
|
||||
cmp cl, 5
|
||||
jnz .ret
|
||||
mov cl, 2
|
||||
.2: mov [CURRENT_TASK+eax+TASKDATA.state], cl
|
||||
.ret:
|
||||
sti
|
||||
ret
|
||||
.1:
|
||||
inc ecx
|
||||
jmp .2
|
||||
|
||||
do_resume:
|
||||
mov cl, [CURRENT_TASK+eax+TASKDATA.state]
|
||||
cmp cl, 1
|
||||
jz .1
|
||||
cmp cl, 2
|
||||
jnz .ret
|
||||
mov cl, 5
|
||||
.2: mov [CURRENT_TASK+eax+TASKDATA.state], cl
|
||||
.ret: ret
|
||||
.1: dec ecx
|
||||
jmp .2
|
||||
|
||||
debug_resume:
|
||||
; in: ecx=pid
|
||||
; destroys eax,ebx
|
||||
cli
|
||||
mov eax, ecx
|
||||
call pid_to_slot
|
||||
shl eax, 5
|
||||
jz .ret
|
||||
call do_resume
|
||||
.ret: sti
|
||||
ret
|
||||
|
||||
debug_getcontext:
|
||||
; in:
|
||||
; ecx=pid
|
||||
; edx=sizeof(CONTEXT)
|
||||
; esi->CONTEXT
|
||||
; destroys eax,ecx,edx,esi,edi
|
||||
cmp edx, 28h
|
||||
jnz .ret
|
||||
; push ecx
|
||||
; mov ecx, esi
|
||||
call check_region
|
||||
; pop ecx
|
||||
dec eax
|
||||
jnz .ret
|
||||
call get_debuggee_slot
|
||||
jc .ret
|
||||
mov edi, esi
|
||||
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
|
||||
lea esi, [eax+RING0_STACK_SIZE]
|
||||
|
||||
.ring0:
|
||||
; note that following code assumes that all interrupt/exception handlers
|
||||
; saves ring-3 context by pushad in this order
|
||||
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), pushad
|
||||
sub esi, 8+12+20h
|
||||
lodsd ;edi
|
||||
mov [edi+24h], eax
|
||||
lodsd ;esi
|
||||
mov [edi+20h], eax
|
||||
lodsd ; ebp
|
||||
mov [edi+1Ch], eax
|
||||
lodsd ;esp
|
||||
lodsd ;ebx
|
||||
mov [edi+14h], eax
|
||||
lodsd ;edx
|
||||
mov [edi+10h], eax
|
||||
lodsd ;ecx
|
||||
mov [edi+0Ch], eax
|
||||
lodsd ;eax
|
||||
mov [edi+8], eax
|
||||
lodsd ;eip
|
||||
mov [edi], eax
|
||||
lodsd ;cs
|
||||
lodsd ;eflags
|
||||
mov [edi+4], eax
|
||||
lodsd ;esp
|
||||
mov [edi+18h], eax
|
||||
.ret:
|
||||
sti
|
||||
ret
|
||||
|
||||
debug_setcontext:
|
||||
; in:
|
||||
; ecx=pid
|
||||
; edx=sizeof(CONTEXT)
|
||||
; esi->CONTEXT
|
||||
; destroys eax,ecx,edx,esi,edi
|
||||
cmp edx, 28h
|
||||
jnz .ret
|
||||
; push ebx
|
||||
; mov ebx, edx
|
||||
call check_region
|
||||
; pop ebx
|
||||
dec eax
|
||||
jnz .ret
|
||||
call get_debuggee_slot
|
||||
jc .stiret
|
||||
; mov esi, edx
|
||||
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
|
||||
lea edi, [eax+RING0_STACK_SIZE]
|
||||
|
||||
.ring0:
|
||||
sub edi, 8+12+20h
|
||||
mov eax, [esi+24h] ;edi
|
||||
stosd
|
||||
mov eax, [esi+20h] ;esi
|
||||
stosd
|
||||
mov eax, [esi+1Ch] ;ebp
|
||||
stosd
|
||||
scasd
|
||||
mov eax, [esi+14h] ;ebx
|
||||
stosd
|
||||
mov eax, [esi+10h] ;edx
|
||||
stosd
|
||||
mov eax, [esi+0Ch] ;ecx
|
||||
stosd
|
||||
mov eax, [esi+8] ;eax
|
||||
stosd
|
||||
mov eax, [esi] ;eip
|
||||
stosd
|
||||
scasd
|
||||
mov eax, [esi+4] ;eflags
|
||||
stosd
|
||||
mov eax, [esi+18h] ;esp
|
||||
stosd
|
||||
.stiret:
|
||||
sti
|
||||
.ret:
|
||||
ret
|
||||
|
||||
debug_set_drx:
|
||||
call get_debuggee_slot
|
||||
jc .errret
|
||||
mov ebp, eax
|
||||
lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs]
|
||||
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
|
||||
; [eax+10]=dr7
|
||||
cmp esi, OS_BASE
|
||||
jae .errret
|
||||
cmp dl, 3
|
||||
ja .errret
|
||||
mov ecx, dr7
|
||||
;fix me
|
||||
xchg ecx,edx
|
||||
shr edx, cl
|
||||
shr edx, cl
|
||||
xchg ecx,edx
|
||||
|
||||
test ecx, 2 ; bit 1+2*index = G0..G3, global break enable
|
||||
jnz .errret2
|
||||
test dh, dh
|
||||
jns .new
|
||||
; clear breakpoint
|
||||
movzx edx, dl
|
||||
add edx, edx
|
||||
and dword [eax+edx*2], 0 ; clear DR<i>
|
||||
btr dword [eax+10h], edx ; clear L<i> bit
|
||||
test byte [eax+10h], 55h
|
||||
jnz .okret
|
||||
; imul eax, ebp, tss_step/32
|
||||
; and byte [eax + tss_data + TSS._trap], not 1
|
||||
and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], not 1
|
||||
.okret:
|
||||
and dword [esp+32], 0
|
||||
sti
|
||||
ret
|
||||
.errret:
|
||||
sti
|
||||
mov dword [esp+32], 1
|
||||
ret
|
||||
.errret2:
|
||||
sti
|
||||
mov dword [esp+32], 2
|
||||
ret
|
||||
.new:
|
||||
; add new breakpoint
|
||||
; dl=index; dh=flags; esi=address
|
||||
test dh, 0xF0
|
||||
jnz .errret
|
||||
mov cl, dh
|
||||
and cl, 3
|
||||
cmp cl, 2
|
||||
jz .errret
|
||||
mov cl, dh
|
||||
shr cl, 2
|
||||
cmp cl, 2
|
||||
jz .errret
|
||||
|
||||
mov ebx,esi
|
||||
test bl, dl
|
||||
|
||||
jnz .errret
|
||||
or byte [eax+10h+1], 3 ; set GE and LE flags
|
||||
|
||||
movzx edx, dh
|
||||
movzx ecx, dl
|
||||
add ecx, ecx
|
||||
bts dword [eax+10h], ecx ; set L<i> flag
|
||||
add ecx, ecx
|
||||
mov [eax+ecx], ebx;esi ; set DR<i>
|
||||
shl edx, cl
|
||||
mov ebx, 0xF
|
||||
shl ebx, cl
|
||||
not ebx
|
||||
and [eax+10h+2], bx
|
||||
or [eax+10h+2], dx ; set R/W and LEN fields
|
||||
; imul eax, ebp, tss_step/32
|
||||
; or byte [eax + tss_data + TSS._trap], 1
|
||||
or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 1
|
||||
jmp .okret
|
||||
|
||||
debug_read_process_memory:
|
||||
; in:
|
||||
; ecx=pid
|
||||
; edx=length
|
||||
; edi->buffer in debugger
|
||||
; esi=address in debuggee
|
||||
; out: [esp+36]=sizeof(read)
|
||||
; destroys all
|
||||
; push ebx
|
||||
; mov ebx, esi
|
||||
call check_region
|
||||
; pop ebx
|
||||
dec eax
|
||||
jnz .err
|
||||
call get_debuggee_slot
|
||||
jc .err
|
||||
shr eax, 5
|
||||
mov ecx, edi
|
||||
call read_process_memory
|
||||
sti
|
||||
mov dword [esp+32], eax
|
||||
ret
|
||||
.err:
|
||||
or dword [esp+32], -1
|
||||
ret
|
||||
|
||||
debug_write_process_memory:
|
||||
; in:
|
||||
; ecx=pid
|
||||
; edx=length
|
||||
; edi->buffer in debugger
|
||||
; esi=address in debuggee
|
||||
; out: [esp+36]=sizeof(write)
|
||||
; destroys all
|
||||
; push ebx
|
||||
; mov ebx, esi
|
||||
call check_region
|
||||
; pop ebx
|
||||
dec eax
|
||||
jnz debug_read_process_memory.err
|
||||
call get_debuggee_slot
|
||||
jc debug_read_process_memory.err
|
||||
shr eax, 5
|
||||
mov ecx, edi
|
||||
call write_process_memory
|
||||
sti
|
||||
mov [esp+32], eax
|
||||
ret
|
||||
|
||||
debugger_notify:
|
||||
; in: eax=debugger slot
|
||||
; ecx=size of debug message
|
||||
; [esp+4]..[esp+4+ecx]=message
|
||||
; interrupts must be disabled!
|
||||
; destroys all general registers
|
||||
; interrupts remain disabled
|
||||
xchg ebp, eax
|
||||
mov edi, [timer_ticks]
|
||||
add edi, 500 ; 5 sec timeout
|
||||
.1:
|
||||
mov eax, ebp
|
||||
shl eax, 8
|
||||
mov esi, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
|
||||
test esi, esi
|
||||
jz .ret
|
||||
; read buffer header
|
||||
push ecx
|
||||
push eax
|
||||
push eax
|
||||
mov eax, ebp
|
||||
mov ecx, esp
|
||||
mov edx, 8
|
||||
call read_process_memory
|
||||
cmp eax, edx
|
||||
jz @f
|
||||
add esp, 12
|
||||
jmp .ret
|
||||
@@:
|
||||
cmp dword [ecx], 0
|
||||
jg @f
|
||||
.2:
|
||||
pop ecx
|
||||
pop ecx
|
||||
pop ecx
|
||||
cmp dword [CURRENT_TASK], 1
|
||||
jnz .notos
|
||||
cmp [timer_ticks], edi
|
||||
jae .ret
|
||||
.notos:
|
||||
sti
|
||||
call change_task
|
||||
cli
|
||||
jmp .1
|
||||
@@:
|
||||
mov edx, [ecx+8]
|
||||
add edx, [ecx+4]
|
||||
cmp edx, [ecx]
|
||||
ja .2
|
||||
; advance buffer position
|
||||
push edx
|
||||
mov edx, 4
|
||||
sub ecx, edx
|
||||
mov eax, ebp
|
||||
add esi, edx
|
||||
call write_process_memory
|
||||
pop eax
|
||||
; write message
|
||||
mov eax, ebp
|
||||
add esi, edx
|
||||
add esi, [ecx+8]
|
||||
add ecx, 20
|
||||
pop edx
|
||||
pop edx
|
||||
pop edx
|
||||
call write_process_memory
|
||||
; new debug event
|
||||
mov eax, ebp
|
||||
shl eax, 8
|
||||
or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h
|
||||
.ret:
|
||||
ret
|
1689
kernel/branches/kolibri-cfg/core/dll.inc
Normal file
1689
kernel/branches/kolibri-cfg/core/dll.inc
Normal file
File diff suppressed because it is too large
Load Diff
39
kernel/branches/kolibri-cfg/core/export.inc
Normal file
39
kernel/branches/kolibri-cfg/core/export.inc
Normal file
@ -0,0 +1,39 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
; Macroinstruction for making export section
|
||||
|
||||
|
||||
macro export dllname,[label,string]
|
||||
{ common
|
||||
local module,addresses,names,ordinal,count
|
||||
count = 0
|
||||
forward
|
||||
count = count+1
|
||||
common
|
||||
dd 0,0,0, (module-OS_BASE) , 1
|
||||
dd count,count,(addresses-OS_BASE),(names-OS_BASE),(ordinal-OS_BASE)
|
||||
addresses:
|
||||
forward
|
||||
dd (label-OS_BASE)
|
||||
common
|
||||
names:
|
||||
forward
|
||||
local name
|
||||
dd (name-OS_BASE)
|
||||
common
|
||||
ordinal: count = 0
|
||||
forward
|
||||
dw count
|
||||
count = count+1
|
||||
common
|
||||
module db dllname,0
|
||||
forward
|
||||
name db string,0
|
||||
}
|
167
kernel/branches/kolibri-cfg/core/exports.inc
Normal file
167
kernel/branches/kolibri-cfg/core/exports.inc
Normal file
@ -0,0 +1,167 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
iglobal
|
||||
szKernel db 'KERNEL', 0
|
||||
szVersion db 'version',0
|
||||
|
||||
szRegService db 'RegService',0
|
||||
szGetService db 'GetService',0
|
||||
szServiceHandler db 'ServiceHandler',0
|
||||
szAttachIntHandler db 'AttachIntHandler',0
|
||||
szGetIntHandler db 'GetIntHandler', 0
|
||||
szFpuSave db 'FpuSave',0
|
||||
szFpuRestore db 'FpuRestore',0
|
||||
szReservePortArea db 'ReservePortArea',0
|
||||
szBoot_Log db 'Boot_Log',0
|
||||
|
||||
szMutexInit db 'MutexInit',0
|
||||
szMutexLock db 'MutexLock',0
|
||||
szMutexUnlock db 'MutexUnlock',0
|
||||
|
||||
szPciApi db 'PciApi', 0
|
||||
szPciRead32 db 'PciRead32', 0
|
||||
szPciRead16 db 'PciRead16', 0
|
||||
szPciRead8 db 'PciRead8', 0
|
||||
szPciWrite8 db 'PciWrite8',0
|
||||
szPciWrite16 db 'PciWrite16',0
|
||||
szPciWrite32 db 'PciWrite32',0
|
||||
|
||||
szAllocPage db 'AllocPage',0
|
||||
szAllocPages db 'AllocPages',0
|
||||
szFreePage db 'FreePage',0
|
||||
szGetPgAddr db 'GetPgAddr',0
|
||||
szMapPage db 'MapPage',0
|
||||
szMapSpace db 'MapSpace',0
|
||||
szMapIoMem db 'MapIoMem',0
|
||||
szCommitPages db 'CommitPages',0
|
||||
szReleasePages db 'ReleasePages',0
|
||||
|
||||
szAllocKernelSpace db 'AllocKernelSpace',0
|
||||
szFreeKernelSpace db 'FreeKernelSpace',0
|
||||
szKernelAlloc db 'KernelAlloc',0
|
||||
szKernelFree db 'KernelFree',0
|
||||
szUserAlloc db 'UserAlloc',0
|
||||
szUserFree db 'UserFree',0
|
||||
szKmalloc db 'Kmalloc',0
|
||||
szKfree db 'Kfree',0
|
||||
szCreateRingBuffer db 'CreateRingBuffer',0
|
||||
|
||||
szGetPid db 'GetPid',0
|
||||
szCreateObject db 'CreateObject',0
|
||||
szDestroyObject db 'DestroyObject',0
|
||||
szCreateEvent db 'CreateEvent',0
|
||||
szRaiseEvent db 'RaiseEvent',0
|
||||
szWaitEvent db 'WaitEvent',0
|
||||
szDestroyEvent db 'DestroyEvent',0
|
||||
szClearEvent db 'ClearEvent',0
|
||||
|
||||
szLoadCursor db 'LoadCursor',0
|
||||
|
||||
szSysMsgBoardStr db 'SysMsgBoardStr', 0
|
||||
szSysMsgBoardChar db 'SysMsgBoardChar', 0
|
||||
szGetCurrentTask db 'GetCurrentTask',0
|
||||
szLFBAddress db 'LFBAddress',0
|
||||
szLoadFile db 'LoadFile',0
|
||||
szSendEvent db 'SendEvent',0
|
||||
szSetMouseData db 'SetMouseData',0
|
||||
szSleep db 'Sleep',0
|
||||
szGetTimerTicks db 'GetTimerTicks',0
|
||||
|
||||
szGetDisplay db 'GetDisplay',0
|
||||
szSetScreen db 'SetScreen',0
|
||||
|
||||
szStrncat db 'strncat',0
|
||||
szStrncpy db 'strncpy',0
|
||||
szstrncmp db 'strncmp',0
|
||||
szStrnlen db 'strnlen',0
|
||||
szStrchr db 'strchr',0
|
||||
szStrrchr db 'strrchr',0
|
||||
|
||||
|
||||
align 16
|
||||
kernel_export:
|
||||
dd szRegService , reg_service
|
||||
dd szGetService , get_service
|
||||
dd szServiceHandler , srv_handler
|
||||
dd szAttachIntHandler, attach_int_handler
|
||||
dd szGetIntHandler , get_int_handler
|
||||
dd szFpuSave , fpu_save
|
||||
dd szFpuRestore , fpu_restore
|
||||
dd szReservePortArea , r_f_port_area
|
||||
dd szBoot_Log , boot_log
|
||||
|
||||
dd szMutexInit , mutex_init ;gcc fastcall
|
||||
dd szMutexLock , mutex_lock ;gcc fastcall
|
||||
dd szMutexUnlock , mutex_unlock ;gcc fastcall
|
||||
|
||||
dd szPciApi , pci_api_drv
|
||||
dd szPciRead32 , pci_read32
|
||||
dd szPciRead16 , pci_read16
|
||||
dd szPciRead8 , pci_read8
|
||||
dd szPciWrite8 , pci_write8
|
||||
dd szPciWrite16 , pci_write16
|
||||
dd szPciWrite32 , pci_write32
|
||||
|
||||
dd szAllocPage , alloc_page ;stdcall
|
||||
dd szAllocPages , alloc_pages ;stdcall
|
||||
dd szFreePage , free_page
|
||||
dd szMapPage , map_page ;stdcall
|
||||
dd szMapSpace , map_space
|
||||
dd szMapIoMem , map_io_mem ;stdcall
|
||||
dd szGetPgAddr , get_pg_addr
|
||||
dd szCommitPages , commit_pages ;not implemented
|
||||
dd szReleasePages , release_pages
|
||||
|
||||
dd szAllocKernelSpace, alloc_kernel_space ;stdcall
|
||||
dd szFreeKernelSpace , free_kernel_space ;stdcall
|
||||
dd szKernelAlloc , kernel_alloc ;stdcall
|
||||
dd szKernelFree , kernel_free ;stdcall
|
||||
dd szUserAlloc , user_alloc ;stdcall
|
||||
dd szUserFree , user_free ;stdcall
|
||||
dd szKmalloc , malloc
|
||||
dd szKfree , free
|
||||
dd szCreateRingBuffer, create_ring_buffer ;stdcall
|
||||
|
||||
dd szGetPid , get_pid
|
||||
dd szCreateObject , create_kernel_object
|
||||
dd szDestroyObject , destroy_kernel_object
|
||||
dd szCreateEvent , create_event ;see EVENT.inc for specification
|
||||
dd szRaiseEvent , raise_event ;see EVENT.inc for specification
|
||||
dd szWaitEvent , wait_event ;see EVENT.inc for specification
|
||||
dd szDestroyEvent , destroy_event ;see EVENT.inc for specification
|
||||
dd szClearEvent , clear_event ;see EVENT.inc for specification
|
||||
|
||||
dd szLoadCursor , load_cursor ;stdcall
|
||||
|
||||
dd szSysMsgBoardStr , sys_msg_board_str
|
||||
dd szSysMsgBoardChar , sys_msg_board
|
||||
dd szGetCurrentTask , get_curr_task
|
||||
dd szLoadFile , load_file ;retval eax, ebx
|
||||
dd szSendEvent , send_event ;see EVENT.inc for specification
|
||||
dd szSetMouseData , set_mouse_data ;stdcall
|
||||
dd szSleep , delay_ms
|
||||
dd szGetTimerTicks , get_timer_ticks
|
||||
|
||||
dd szGetDisplay , get_display
|
||||
dd szSetScreen , set_screen
|
||||
|
||||
dd szStrncat , strncat
|
||||
dd szStrncpy , strncpy
|
||||
dd szstrncmp , strncmp
|
||||
dd szStrnlen , strnlen
|
||||
dd szStrchr , strchr
|
||||
dd szStrrchr , strrchr
|
||||
|
||||
exp_lfb:
|
||||
dd szLFBAddress , 0
|
||||
dd 0 ;terminator, must be zero
|
||||
|
||||
endg
|
320
kernel/branches/kolibri-cfg/core/ext_lib.inc
Normal file
320
kernel/branches/kolibri-cfg/core/ext_lib.inc
Normal file
@ -0,0 +1,320 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;============================================================================
|
||||
;
|
||||
; External kernel dependencies (libraries) loading
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
$Revision$
|
||||
|
||||
if 0
|
||||
; The code currently does not work. Kill "if 0/end if" only after correcting
|
||||
; to current kernel (dll.inc).
|
||||
macro library [name,fname]
|
||||
{
|
||||
forward
|
||||
dd __#name#_library_table__,__#name#_library_name__
|
||||
common
|
||||
dd 0
|
||||
forward
|
||||
__#name#_library_name__ db fname,0
|
||||
}
|
||||
|
||||
macro import lname,[name,sname]
|
||||
{
|
||||
common
|
||||
align 4
|
||||
__#lname#_library_table__:
|
||||
forward
|
||||
name dd __#name#_import_name__
|
||||
common
|
||||
dd 0
|
||||
forward
|
||||
__#name#_import_name__ db sname,0
|
||||
}
|
||||
|
||||
macro export [name,sname]
|
||||
{
|
||||
align 4
|
||||
forward
|
||||
dd __#name#_export_name__,name
|
||||
common
|
||||
dd 0
|
||||
forward
|
||||
__#name#_export_name__ db sname,0
|
||||
}
|
||||
|
||||
|
||||
|
||||
align 4 ; loading library (use kernel functions)
|
||||
proc load_k_library stdcall, file_name:dword
|
||||
locals
|
||||
coff dd ?
|
||||
sym dd ?
|
||||
strings dd ?
|
||||
img_size dd ?
|
||||
img_base dd ?
|
||||
exports dd ?
|
||||
endl
|
||||
|
||||
cli
|
||||
|
||||
stdcall load_file, [file_name]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [coff], eax
|
||||
movzx ecx, [eax+CFH.nSections]
|
||||
xor ebx, ebx
|
||||
|
||||
lea edx, [eax+20]
|
||||
@@:
|
||||
add ebx, [edx+CFS.SizeOfRawData]
|
||||
add ebx, 15
|
||||
and ebx, not 15
|
||||
add edx, COFF_SECTION_SIZE
|
||||
dec ecx
|
||||
jnz @B
|
||||
mov [img_size], ebx
|
||||
|
||||
stdcall kernel_alloc, [img_size]
|
||||
|
||||
test eax, eax
|
||||
jz .fail
|
||||
mov [img_base], eax
|
||||
|
||||
mov edx, [coff]
|
||||
movzx ebx, [edx+CFH.nSections]
|
||||
mov edi, [img_base]
|
||||
lea eax, [edx+20]
|
||||
@@:
|
||||
mov [eax+CFS.VirtualAddress], edi
|
||||
mov esi, [eax+CFS.PtrRawData]
|
||||
test esi, esi
|
||||
jnz .copy
|
||||
add edi, [eax+CFS.SizeOfRawData]
|
||||
jmp .next
|
||||
.copy:
|
||||
add esi, edx
|
||||
mov ecx, [eax+CFS.SizeOfRawData]
|
||||
cld
|
||||
rep movsb
|
||||
.next:
|
||||
add edi, 15
|
||||
and edi, not 15
|
||||
add eax, COFF_SECTION_SIZE
|
||||
dec ebx
|
||||
jnz @B
|
||||
|
||||
mov ebx, [edx+CFH.pSymTable]
|
||||
add ebx, edx
|
||||
mov [sym], ebx
|
||||
mov ecx, [edx+CFH.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+CFH.nSymbols],\
|
||||
[strings], dword 0
|
||||
test eax, eax
|
||||
jnz @F
|
||||
|
||||
@@:
|
||||
mov edx, [coff]
|
||||
movzx ebx, [edx+CFH.nSections]
|
||||
mov edi, 0
|
||||
lea eax, [edx+20]
|
||||
@@:
|
||||
add [eax+CFS.VirtualAddress], edi ;patch user space offset
|
||||
add eax, COFF_SECTION_SIZE
|
||||
dec ebx
|
||||
jnz @B
|
||||
|
||||
add edx, 20
|
||||
stdcall fix_coff_relocs, [coff], edx, [sym]
|
||||
|
||||
mov ebx, [coff]
|
||||
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS
|
||||
mov [exports], eax
|
||||
|
||||
stdcall kernel_free, [coff]
|
||||
|
||||
mov eax, [exports]
|
||||
ret
|
||||
.fail:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
proc dll.Load, import_table:dword
|
||||
mov esi,[import_table]
|
||||
.next_lib: mov edx,[esi]
|
||||
or edx,edx
|
||||
jz .exit
|
||||
push esi
|
||||
|
||||
mov edi,s_libname
|
||||
|
||||
mov al, '/'
|
||||
stosb
|
||||
mov esi,sysdir_path
|
||||
@@: lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jnz @b
|
||||
dec edi
|
||||
mov [edi], dword '/lib'
|
||||
mov [edi+4],byte '/'
|
||||
add edi,5
|
||||
pop esi
|
||||
push esi
|
||||
mov esi,[esi+4]
|
||||
@@: lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jnz @b
|
||||
|
||||
pushad
|
||||
stdcall load_k_library,s_libname
|
||||
mov [esp+28],eax
|
||||
popad
|
||||
or eax,eax
|
||||
jz .fail
|
||||
stdcall dll.Link,eax,edx
|
||||
stdcall dll.Init,[eax+4]
|
||||
pop esi
|
||||
add esi,8
|
||||
jmp .next_lib
|
||||
.exit: xor eax,eax
|
||||
ret
|
||||
.fail: add esp,4
|
||||
xor eax,eax
|
||||
inc eax
|
||||
ret
|
||||
endp
|
||||
|
||||
proc dll.Link, exp:dword,imp:dword
|
||||
push eax
|
||||
mov esi,[imp]
|
||||
test esi,esi
|
||||
jz .done
|
||||
.next: lodsd
|
||||
test eax,eax
|
||||
jz .done
|
||||
stdcall dll.GetProcAddress,[exp],eax
|
||||
or eax,eax
|
||||
jz @f
|
||||
mov [esi-4],eax
|
||||
jmp .next
|
||||
@@: mov dword[esp],0
|
||||
.done: pop eax
|
||||
ret
|
||||
endp
|
||||
|
||||
proc dll.Init, dllentry:dword
|
||||
pushad
|
||||
mov eax,mem.Alloc
|
||||
mov ebx,mem.Free
|
||||
mov ecx,mem.ReAlloc
|
||||
mov edx,dll.Load
|
||||
stdcall [dllentry]
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
proc dll.GetProcAddress, exp:dword,sz_name:dword
|
||||
mov edx,[exp]
|
||||
.next: test edx,edx
|
||||
jz .end
|
||||
stdcall strncmp,[edx],[sz_name], dword -1
|
||||
test eax,eax
|
||||
jz .ok
|
||||
add edx,8
|
||||
jmp .next
|
||||
.ok: mov eax,[edx+4]
|
||||
.end: ret
|
||||
endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
proc mem.Alloc size ;/////////////////////////////////////////////////////////
|
||||
;-----------------------------------------------------------------------------
|
||||
push ebx ecx
|
||||
; mov eax,[size]
|
||||
; lea ecx,[eax+4+4095]
|
||||
; and ecx,not 4095
|
||||
; stdcall kernel_alloc, ecx
|
||||
; add ecx,-4
|
||||
; mov [eax],ecx
|
||||
; add eax,4
|
||||
|
||||
stdcall kernel_alloc, [size]
|
||||
|
||||
pop ecx ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
proc mem.ReAlloc mptr,size;///////////////////////////////////////////////////
|
||||
;-----------------------------------------------------------------------------
|
||||
push ebx ecx esi edi eax
|
||||
mov eax,[mptr]
|
||||
mov ebx,[size]
|
||||
or eax,eax
|
||||
jz @f
|
||||
lea ecx,[ebx+4+4095]
|
||||
and ecx,not 4095
|
||||
add ecx,-4
|
||||
cmp ecx,[eax-4]
|
||||
je .exit
|
||||
@@: mov eax,ebx
|
||||
call mem.Alloc
|
||||
xchg eax,[esp]
|
||||
or eax,eax
|
||||
jz .exit
|
||||
mov esi,eax
|
||||
xchg eax,[esp]
|
||||
mov edi,eax
|
||||
mov ecx,[esi-4]
|
||||
cmp ecx,[edi-4]
|
||||
jbe @f
|
||||
mov ecx,[edi-4]
|
||||
@@: add ecx,3
|
||||
shr ecx,2
|
||||
cld
|
||||
rep movsd
|
||||
xchg eax,[esp]
|
||||
call mem.Free
|
||||
.exit:
|
||||
pop eax edi esi ecx ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
proc mem.Free mptr ;//////////////////////////////////////////////////////////
|
||||
;-----------------------------------------------------------------------------
|
||||
; mov eax,[mptr]
|
||||
; or eax,eax
|
||||
; jz @f
|
||||
; push ebx ecx
|
||||
; lea ecx,[eax-4]
|
||||
; stdcall kernel_free, ecx
|
||||
; pop ecx ebx
|
||||
; @@: ret
|
||||
stdcall kernel_free, [mptr]
|
||||
ret
|
||||
endp
|
||||
|
||||
uglobal
|
||||
s_libname db 64 dup (0)
|
||||
endg
|
||||
end if
|
183
kernel/branches/kolibri-cfg/core/fpu.inc
Normal file
183
kernel/branches/kolibri-cfg/core/fpu.inc
Normal file
@ -0,0 +1,183 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
init_fpu:
|
||||
clts
|
||||
fninit
|
||||
|
||||
bt [cpu_caps], CAPS_SSE
|
||||
jnc .no_SSE
|
||||
|
||||
mov ebx, cr4
|
||||
mov ecx, cr0
|
||||
or ebx, CR4_OSFXSR+CR4_OSXMMEXPT
|
||||
mov cr4, ebx
|
||||
|
||||
and ecx, not (CR0_MP+CR0_EM)
|
||||
or ecx, CR0_NE
|
||||
mov cr0, ecx
|
||||
|
||||
mov dword [esp-4], SSE_INIT
|
||||
ldmxcsr [esp-4]
|
||||
|
||||
xorps xmm0, xmm0
|
||||
xorps xmm1, xmm1
|
||||
xorps xmm2, xmm2
|
||||
xorps xmm3, xmm3
|
||||
xorps xmm4, xmm4
|
||||
xorps xmm5, xmm5
|
||||
xorps xmm6, xmm6
|
||||
xorps xmm7, xmm7
|
||||
fxsave [fpu_data] ;[eax]
|
||||
ret
|
||||
.no_SSE:
|
||||
mov ecx, cr0
|
||||
and ecx, not CR0_EM
|
||||
or ecx, CR0_MP+CR0_NE
|
||||
mov cr0, ecx
|
||||
fnsave [fpu_data]
|
||||
ret
|
||||
|
||||
; param
|
||||
; eax= 512 bytes memory area
|
||||
|
||||
align 4
|
||||
fpu_save:
|
||||
push ecx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
pushfd
|
||||
cli
|
||||
|
||||
clts
|
||||
mov edi, eax
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov esi, [CURRENT_TASK]
|
||||
cmp ecx, esi
|
||||
jne .save
|
||||
|
||||
call save_context
|
||||
jmp .exit
|
||||
.save:
|
||||
mov [fpu_owner], esi
|
||||
|
||||
shl ecx, 8
|
||||
mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state]
|
||||
|
||||
call save_context
|
||||
|
||||
shl esi, 8
|
||||
mov esi, [esi+SLOT_BASE+APPDATA.fpu_state]
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
fninit
|
||||
.exit:
|
||||
popfd
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
align 4
|
||||
save_context:
|
||||
bt [cpu_caps], CAPS_SSE
|
||||
jnc .no_SSE
|
||||
|
||||
fxsave [eax]
|
||||
ret
|
||||
.no_SSE:
|
||||
fnsave [eax]
|
||||
ret
|
||||
|
||||
align 4
|
||||
fpu_restore:
|
||||
push ecx
|
||||
push esi
|
||||
|
||||
mov esi, eax
|
||||
|
||||
pushfd
|
||||
cli
|
||||
|
||||
mov ecx, [fpu_owner]
|
||||
mov eax, [CURRENT_TASK]
|
||||
cmp ecx, eax
|
||||
jne .copy
|
||||
|
||||
clts
|
||||
bt [cpu_caps], CAPS_SSE
|
||||
jnc .no_SSE
|
||||
|
||||
fxrstor [esi]
|
||||
popfd
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
.no_SSE:
|
||||
fnclex ;fix possible problems
|
||||
frstor [esi]
|
||||
popfd
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
.copy:
|
||||
shl eax, 8
|
||||
mov edi, [eax+SLOT_BASE+APPDATA.fpu_state]
|
||||
mov ecx, 512/4
|
||||
cld
|
||||
rep movsd
|
||||
popfd
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
align 4
|
||||
except_7: ;#NM exception handler
|
||||
save_ring3_context
|
||||
clts
|
||||
mov ax, app_data ;
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
|
||||
mov ebx, [fpu_owner]
|
||||
cmp ebx, [CURRENT_TASK]
|
||||
je .exit
|
||||
|
||||
shl ebx, 8
|
||||
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
|
||||
bt [cpu_caps], CAPS_SSE
|
||||
jnc .no_SSE
|
||||
|
||||
fxsave [eax]
|
||||
mov ebx, [CURRENT_TASK]
|
||||
mov [fpu_owner], ebx
|
||||
shl ebx, 8
|
||||
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
|
||||
fxrstor [eax]
|
||||
.exit:
|
||||
restore_ring3_context
|
||||
iret
|
||||
|
||||
.no_SSE:
|
||||
fnsave [eax]
|
||||
mov ebx, [CURRENT_TASK]
|
||||
mov [fpu_owner], ebx
|
||||
shl ebx, 8
|
||||
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
|
||||
frstor [eax]
|
||||
restore_ring3_context
|
||||
iret
|
||||
|
||||
iglobal
|
||||
fpu_owner dd 0
|
||||
endg
|
1540
kernel/branches/kolibri-cfg/core/heap.inc
Normal file
1540
kernel/branches/kolibri-cfg/core/heap.inc
Normal file
File diff suppressed because it is too large
Load Diff
1029
kernel/branches/kolibri-cfg/core/malloc.inc
Normal file
1029
kernel/branches/kolibri-cfg/core/malloc.inc
Normal file
File diff suppressed because it is too large
Load Diff
1523
kernel/branches/kolibri-cfg/core/memory.inc
Normal file
1523
kernel/branches/kolibri-cfg/core/memory.inc
Normal file
File diff suppressed because it is too large
Load Diff
331
kernel/branches/kolibri-cfg/core/peload.inc
Normal file
331
kernel/branches/kolibri-cfg/core/peload.inc
Normal file
@ -0,0 +1,331 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
include 'export.inc'
|
||||
|
||||
align 4
|
||||
|
||||
proc load_PE stdcall, file_name:dword
|
||||
locals
|
||||
image dd ?
|
||||
entry dd ?
|
||||
base dd ?
|
||||
endl
|
||||
|
||||
stdcall load_file, [file_name]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [image], eax
|
||||
|
||||
mov edx, [eax+60]
|
||||
|
||||
stdcall kernel_alloc, [eax+80+edx]
|
||||
test eax, eax
|
||||
jz .cleanup
|
||||
|
||||
mov [base], eax
|
||||
|
||||
stdcall map_PE, eax, [image]
|
||||
|
||||
mov [entry], eax
|
||||
test eax, eax
|
||||
jnz .cleanup
|
||||
|
||||
stdcall kernel_free, [base]
|
||||
.cleanup:
|
||||
stdcall kernel_free, [image]
|
||||
mov eax, [entry]
|
||||
ret
|
||||
.fail:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
DWORD equ dword
|
||||
PTR equ
|
||||
|
||||
align 4
|
||||
map_PE: ;stdcall base:dword, image:dword
|
||||
cld
|
||||
push ebp
|
||||
push edi
|
||||
push esi
|
||||
push ebx
|
||||
sub esp, 60
|
||||
mov ebx, DWORD PTR [esp+84]
|
||||
mov ebp, DWORD PTR [esp+80]
|
||||
mov edx, ebx
|
||||
mov esi, ebx
|
||||
add edx, DWORD PTR [ebx+60]
|
||||
mov edi, ebp
|
||||
mov DWORD PTR [esp+32], edx
|
||||
mov ecx, DWORD PTR [edx+84]
|
||||
|
||||
shr ecx, 2
|
||||
rep movsd
|
||||
|
||||
movzx eax, WORD PTR [edx+6]
|
||||
mov DWORD PTR [esp+36], 0
|
||||
mov DWORD PTR [esp+16], eax
|
||||
jmp L2
|
||||
L3:
|
||||
mov eax, DWORD PTR [edx+264]
|
||||
test eax, eax
|
||||
je L4
|
||||
mov esi, ebx
|
||||
mov edi, ebp
|
||||
add esi, DWORD PTR [edx+268]
|
||||
mov ecx, eax
|
||||
add edi, DWORD PTR [edx+260]
|
||||
|
||||
shr ecx, 2
|
||||
rep movsd
|
||||
|
||||
L4:
|
||||
mov ecx, DWORD PTR [edx+256]
|
||||
add ecx, 4095
|
||||
and ecx, -4096
|
||||
cmp ecx, eax
|
||||
jbe L6
|
||||
sub ecx, eax
|
||||
add eax, DWORD PTR [edx+260]
|
||||
lea edi, [eax+ebp]
|
||||
|
||||
xor eax, eax
|
||||
rep stosb
|
||||
|
||||
L6:
|
||||
inc DWORD PTR [esp+36]
|
||||
add edx, 40
|
||||
L2:
|
||||
mov esi, DWORD PTR [esp+16]
|
||||
cmp DWORD PTR [esp+36], esi
|
||||
jne L3
|
||||
mov edi, DWORD PTR [esp+32]
|
||||
cmp DWORD PTR [edi+164], 0
|
||||
je L9
|
||||
mov esi, ebp
|
||||
mov ecx, ebp
|
||||
sub esi, DWORD PTR [edi+52]
|
||||
add ecx, DWORD PTR [edi+160]
|
||||
mov eax, esi
|
||||
shr eax, 16
|
||||
mov DWORD PTR [esp+12], eax
|
||||
jmp L11
|
||||
L12:
|
||||
lea ebx, [eax-8]
|
||||
xor edi, edi
|
||||
shr ebx,1
|
||||
jmp L13
|
||||
L14:
|
||||
movzx eax, WORD PTR [ecx+8+edi*2]
|
||||
mov edx, eax
|
||||
shr eax, 12
|
||||
and edx, 4095
|
||||
add edx, DWORD PTR [ecx]
|
||||
cmp ax, 2
|
||||
je L17
|
||||
cmp ax, 3
|
||||
je L18
|
||||
dec ax
|
||||
jne L15
|
||||
mov eax, DWORD PTR [esp+12]
|
||||
add WORD PTR [edx+ebp], ax
|
||||
L17:
|
||||
add WORD PTR [edx+ebp], si
|
||||
L18:
|
||||
add DWORD PTR [edx+ebp], esi
|
||||
L15:
|
||||
inc edi
|
||||
L13:
|
||||
cmp edi, ebx
|
||||
jne L14
|
||||
add ecx, DWORD PTR [ecx+4]
|
||||
L11:
|
||||
mov eax, DWORD PTR [ecx+4]
|
||||
test eax, eax
|
||||
jne L12
|
||||
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]
|
||||
mov DWORD PTR [esp+52], 0
|
||||
add ecx, ebp
|
||||
add edx, ebp
|
||||
mov DWORD PTR [esp+24], edx
|
||||
mov DWORD PTR [esp+28], ecx
|
||||
L26:
|
||||
mov esi, DWORD PTR [esp+52]
|
||||
mov edi, DWORD PTR [esp+24]
|
||||
mov eax, DWORD PTR [edi+esi*4]
|
||||
test eax, eax
|
||||
je L27
|
||||
test eax, eax
|
||||
js L27
|
||||
lea edi, [ebp+eax]
|
||||
mov eax, DWORD PTR [esp+28]
|
||||
mov DWORD PTR [eax+esi*4], 0
|
||||
lea esi, [edi+2]
|
||||
push eax
|
||||
push 32
|
||||
movzx eax, WORD PTR [edi]
|
||||
mov edx, DWORD PTR [esp+56]
|
||||
mov eax, DWORD PTR [edx+eax*4]
|
||||
add eax, OS_BASE
|
||||
push eax
|
||||
push esi
|
||||
call strncmp
|
||||
pop ebx
|
||||
xor ebx, ebx
|
||||
test eax, eax
|
||||
jne L32
|
||||
jmp L30
|
||||
L33:
|
||||
push ecx
|
||||
push 32
|
||||
mov ecx, DWORD PTR [esp+28]
|
||||
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4]
|
||||
add eax, OS_BASE
|
||||
push eax
|
||||
push esi
|
||||
call strncmp
|
||||
pop edx
|
||||
test eax, eax
|
||||
jne L34
|
||||
mov esi, DWORD PTR [esp+44]
|
||||
mov edx, DWORD PTR [esp+52]
|
||||
mov ecx, DWORD PTR [esp+28]
|
||||
mov eax, DWORD PTR [esi+ebx*4]
|
||||
add eax, OS_BASE
|
||||
mov DWORD PTR [ecx+edx*4], eax
|
||||
jmp L36
|
||||
L34:
|
||||
inc ebx
|
||||
L32:
|
||||
cmp ebx, DWORD PTR [__exports+24]
|
||||
jb L33
|
||||
L36:
|
||||
cmp ebx, DWORD PTR [__exports+24]
|
||||
jne L37
|
||||
|
||||
mov esi, msg_unresolved
|
||||
call sys_msg_board_str
|
||||
lea esi, [edi+2]
|
||||
call sys_msg_board_str
|
||||
mov esi, msg_CR
|
||||
call sys_msg_board_str
|
||||
|
||||
mov DWORD PTR [esp+40], 1
|
||||
jmp L37
|
||||
L30:
|
||||
movzx eax, WORD PTR [edi]
|
||||
mov esi, DWORD PTR [esp+44]
|
||||
mov edi, DWORD PTR [esp+52]
|
||||
mov edx, DWORD PTR [esp+28]
|
||||
mov eax, DWORD PTR [esi+eax*4]
|
||||
add eax, OS_BASE
|
||||
mov DWORD PTR [edx+edi*4], eax
|
||||
L37:
|
||||
inc DWORD PTR [esp+52]
|
||||
jmp L26
|
||||
L27:
|
||||
add DWORD PTR [esp+56], 20
|
||||
jmp L22
|
||||
L25:
|
||||
xor eax, eax
|
||||
cmp DWORD PTR [esp+40], 0
|
||||
jne L40
|
||||
L20:
|
||||
mov ecx, DWORD PTR [esp+32]
|
||||
mov eax, ebp
|
||||
add eax, DWORD PTR [ecx+40]
|
||||
L40:
|
||||
add esp, 60
|
||||
pop ebx
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret 8
|
||||
|
||||
align 16
|
||||
__exports:
|
||||
export 'KERNEL', \
|
||||
alloc_kernel_space, 'AllocKernelSpace', \ ; stdcall
|
||||
alloc_page, 'AllocPage', \ ; gcc ABI
|
||||
alloc_pages, 'AllocPages', \ ; stdcall
|
||||
commit_pages, 'CommitPages', \ ; eax, ebx, ecx
|
||||
\
|
||||
create_event, 'CreateEvent', \ ; ecx, esi
|
||||
raise_event, 'RaiseEvent', \ ; eax, ebx, edx, esi
|
||||
wait_event, 'WaitEvent', \ ; eax, ebx
|
||||
get_event_ex, 'GetEvent', \ ; edi
|
||||
\
|
||||
create_kernel_object, 'CreateObject', \
|
||||
create_ring_buffer, 'CreateRingBuffer', \ ; stdcall
|
||||
destroy_kernel_object, 'DestroyObject', \
|
||||
free_kernel_space, 'FreeKernelSpace', \ ; stdcall
|
||||
kernel_alloc, 'KernelAlloc', \ ; stdcall
|
||||
kernel_free, 'KernelFree', \ ; stdcall
|
||||
malloc, 'Kmalloc', \
|
||||
free, 'Kfree', \
|
||||
map_io_mem, 'MapIoMem', \ ; stdcall
|
||||
get_pg_addr, 'GetPgAddr', \ ; eax
|
||||
\
|
||||
mutex_init, 'MutexInit', \ ; gcc fastcall
|
||||
mutex_lock, 'MutexLock', \ ; gcc fastcall
|
||||
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
|
||||
\
|
||||
get_display, 'GetDisplay', \
|
||||
set_screen, 'SetScreen', \
|
||||
pci_api_drv, 'PciApi', \
|
||||
pci_read8, 'PciRead8', \ ; stdcall
|
||||
pci_read16, 'PciRead16', \ ; stdcall
|
||||
pci_read32, 'PciRead32', \ ; stdcall
|
||||
pci_write8, 'PciWrite8', \ ; stdcall
|
||||
pci_write16, 'PciWrite16', \ ; stdcall
|
||||
pci_write32, 'PciWrite32', \ ; stdcall
|
||||
\
|
||||
get_service, 'GetService', \ ;
|
||||
reg_service, 'RegService', \ ; stdcall
|
||||
attach_int_handler, 'AttachIntHandler', \ ; stdcall
|
||||
user_alloc, 'UserAlloc', \ ; stdcall
|
||||
user_free, 'UserFree', \ ; stdcall
|
||||
unmap_pages, 'UnmapPages', \ ; eax, ecx
|
||||
sys_msg_board_str, 'SysMsgBoardStr', \
|
||||
get_timer_ticks, 'GetTimerTicks', \
|
||||
get_stack_base, 'GetStackBase', \
|
||||
delay_hs, 'Delay', \ ; ebx
|
||||
set_mouse_data, 'SetMouseData', \ ;
|
||||
set_keyboard_data, 'SetKeyboardData' ; gcc fastcall
|
||||
|
||||
|
||||
|
412
kernel/branches/kolibri-cfg/core/sched.inc
Normal file
412
kernel/branches/kolibri-cfg/core/sched.inc
Normal file
@ -0,0 +1,412 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
align 32
|
||||
irq0:
|
||||
pushad
|
||||
Mov ds, ax, app_data
|
||||
mov es, ax
|
||||
inc [timer_ticks]
|
||||
mov eax, [timer_ticks]
|
||||
call playNote ; <<<--- Speaker driver
|
||||
sub eax,[next_usage_update]
|
||||
cmp eax,100
|
||||
jb .nocounter
|
||||
add [next_usage_update],100
|
||||
call updatecputimes
|
||||
.nocounter:
|
||||
mov al,0x20 ; send End Of Interrupt signal
|
||||
out 0x20,al
|
||||
btr dword[DONT_SWITCH], 0
|
||||
jc .return
|
||||
call find_next_task
|
||||
jz .return ; if there is only one running process
|
||||
call do_change_task
|
||||
.return:
|
||||
popad
|
||||
iretd
|
||||
|
||||
align 4
|
||||
change_task:
|
||||
pushfd
|
||||
cli
|
||||
pushad
|
||||
if 0
|
||||
; \begin{Mario79} ; <- must be refractoried, if used...
|
||||
cmp [dma_task_switched], 1
|
||||
jne .find_next_task
|
||||
mov [dma_task_switched], 0
|
||||
mov ebx, [dma_process]
|
||||
cmp [CURRENT_TASK], ebx
|
||||
je .return
|
||||
mov edi, [dma_slot_ptr]
|
||||
mov [CURRENT_TASK], ebx
|
||||
mov [TASK_BASE], edi
|
||||
jmp @f
|
||||
.find_next_task:
|
||||
; \end{Mario79}
|
||||
end if
|
||||
call find_next_task
|
||||
jz .return ; the same task -> skip switch
|
||||
@@: mov byte[DONT_SWITCH], 1
|
||||
call do_change_task
|
||||
.return:
|
||||
popad
|
||||
popfd
|
||||
ret
|
||||
|
||||
uglobal
|
||||
align 4
|
||||
; far_jump:
|
||||
; .offs dd ?
|
||||
; .sel dw ?
|
||||
context_counter dd 0 ;noname & halyavin
|
||||
next_usage_update dd 0
|
||||
timer_ticks dd 0
|
||||
; prev_slot dd ?
|
||||
; event_sched dd ?
|
||||
endg
|
||||
|
||||
align 4
|
||||
update_counters:
|
||||
mov edi, [TASK_BASE]
|
||||
rdtsc
|
||||
sub eax, [edi+TASKDATA.counter_add] ; time stamp counter add
|
||||
add [edi+TASKDATA.counter_sum], eax ; counter sum
|
||||
ret
|
||||
align 4
|
||||
updatecputimes:
|
||||
xor eax,eax
|
||||
xchg eax,[idleuse]
|
||||
mov [idleusesec],eax
|
||||
mov ecx, [TASK_COUNT]
|
||||
mov edi, TASK_DATA
|
||||
.newupdate:
|
||||
xor eax,eax
|
||||
xchg eax,[edi+TASKDATA.counter_sum]
|
||||
mov [edi+TASKDATA.cpu_usage],eax
|
||||
add edi,0x20
|
||||
loop .newupdate
|
||||
ret
|
||||
|
||||
align 4
|
||||
find_next_task:
|
||||
;info:
|
||||
; Find next task to execute
|
||||
;retval:
|
||||
; ebx = address of the APPDATA for the selected task (slot-base)
|
||||
; esi = previous slot-base ([current_slot] at the begin)
|
||||
; edi = address of the TASKDATA for the selected task
|
||||
; ZF = 1 if the task is the same
|
||||
;warning:
|
||||
; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
|
||||
; [current_slot] is not set to new value (ebx)!!!
|
||||
;scratched: eax,ecx
|
||||
call update_counters ; edi := [TASK_BASE]
|
||||
Mov esi, ebx, [current_slot]
|
||||
.loop:
|
||||
cmp bh,[TASK_COUNT]
|
||||
jb @f
|
||||
xor bh, bh
|
||||
mov edi,CURRENT_TASK
|
||||
@@: inc bh ; ebx += APPDATA.size
|
||||
add edi,0x20 ; edi += TASKDATA.size
|
||||
mov al, [edi+TASKDATA.state]
|
||||
test al, al
|
||||
jz .found ; state == 0
|
||||
cmp al, 5
|
||||
jne .loop ; state == 1,2,3,4,9
|
||||
; state == 5
|
||||
pushad ; more freedom for [APPDATA.wait_test]
|
||||
call [ebx+APPDATA.wait_test]
|
||||
mov [esp+28],eax
|
||||
popad
|
||||
or eax,eax
|
||||
jnz @f
|
||||
; testing for timeout
|
||||
mov ecx, [timer_ticks]
|
||||
sub ecx, [ebx+APPDATA.wait_begin]
|
||||
cmp ecx, [ebx+APPDATA.wait_timeout]
|
||||
jb .loop
|
||||
@@: mov [ebx+APPDATA.wait_param], eax ; retval for wait
|
||||
mov [edi+TASKDATA.state], 0
|
||||
.found:
|
||||
mov [CURRENT_TASK],bh
|
||||
mov [TASK_BASE],edi
|
||||
rdtsc ;call _rdtsc
|
||||
mov [edi+TASKDATA.counter_add],eax ; for next using update_counters
|
||||
cmp ebx, esi ;esi - previous slot-base
|
||||
ret
|
||||
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86...
|
||||
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task
|
||||
|
||||
align 4
|
||||
do_change_task:
|
||||
;param:
|
||||
; ebx = address of the APPDATA for incoming task (new)
|
||||
;warning:
|
||||
; [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
|
||||
; [current_slot] is the outcoming (old), and set here to a new value (ebx)
|
||||
;scratched: eax,ecx,esi
|
||||
mov esi,ebx
|
||||
xchg esi,[current_slot]
|
||||
; set new stack after saving old
|
||||
mov [esi+APPDATA.saved_esp], esp
|
||||
mov esp, [ebx+APPDATA.saved_esp]
|
||||
; set new thread 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]
|
||||
; set new thread memory-map
|
||||
mov ecx, APPDATA.dir_table
|
||||
mov eax, [ebx+ecx] ;offset>0x7F
|
||||
cmp eax, [esi+ecx] ;offset>0x7F
|
||||
je @f
|
||||
mov cr3, eax
|
||||
@@:
|
||||
; set tss.esp0
|
||||
|
||||
Mov [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
|
||||
|
||||
mov edx, [ebx+APPDATA.tls_base]
|
||||
cmp edx, [esi+APPDATA.tls_base]
|
||||
je @f
|
||||
|
||||
mov [tls_data_l+2],dx
|
||||
shr edx,16
|
||||
mov [tls_data_l+4],dl
|
||||
mov [tls_data_l+7],dh
|
||||
|
||||
mov dx, app_tls
|
||||
mov fs, dx
|
||||
@@:
|
||||
; set gs selector unconditionally
|
||||
Mov gs,ax,graph_data
|
||||
; set CR0.TS
|
||||
cmp bh, byte[fpu_owner] ;bh == incoming task (new)
|
||||
clts ;clear a task switch flag
|
||||
je @f
|
||||
mov eax, cr0 ;and set it again if the owner
|
||||
or eax, CR0_TS ;of a fpu has changed
|
||||
mov cr0, eax
|
||||
@@: ; set context_counter (only for user pleasure ???)
|
||||
inc [context_counter] ;noname & halyavin
|
||||
; set debug-registers, if it's necessary
|
||||
test byte[ebx+APPDATA.dbg_state], 1
|
||||
jz @f
|
||||
xor eax, eax
|
||||
mov dr6, eax
|
||||
lea esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F
|
||||
cld
|
||||
macro lodsReg [reg] {
|
||||
lodsd
|
||||
mov reg,eax
|
||||
} lodsReg dr0, dr1, dr2, dr3, dr7
|
||||
purge lodsReg
|
||||
@@: ret
|
||||
;end.
|
||||
|
||||
|
||||
|
||||
struc MUTEX_WAITER
|
||||
{
|
||||
.next rd 1
|
||||
.prev rd 1
|
||||
.task rd 1
|
||||
.sizeof:
|
||||
};
|
||||
|
||||
virtual at 0
|
||||
MUTEX_WAITER MUTEX_WAITER
|
||||
end virtual
|
||||
|
||||
;void __fastcall mutex_init(struct mutex *lock)
|
||||
|
||||
align 4
|
||||
mutex_init:
|
||||
lea eax, [ecx+MUTEX.next]
|
||||
mov [ecx+MUTEX.count],1
|
||||
mov [ecx+MUTEX.next], eax
|
||||
mov [ecx+MUTEX.prev], eax
|
||||
ret
|
||||
|
||||
|
||||
;void __fastcall mutex_lock(struct mutex *lock)
|
||||
|
||||
align 4
|
||||
mutex_lock:
|
||||
|
||||
dec [ecx+MUTEX.count]
|
||||
jns .done
|
||||
|
||||
pushfd
|
||||
cli
|
||||
|
||||
push esi
|
||||
sub esp, MUTEX_WAITER.sizeof
|
||||
|
||||
mov eax, [ecx+MUTEX.prev]
|
||||
lea esi, [ecx+MUTEX.next]
|
||||
|
||||
mov [ecx+MUTEX.prev], esp
|
||||
mov [esp+MUTEX_WAITER.next], esi
|
||||
mov [esp+MUTEX_WAITER.prev], eax
|
||||
mov [eax], esp
|
||||
|
||||
mov edx, [TASK_BASE]
|
||||
mov [esp+MUTEX_WAITER.task], edx
|
||||
|
||||
.forever:
|
||||
|
||||
mov eax, -1
|
||||
xchg eax, [ecx+MUTEX.count]
|
||||
dec eax
|
||||
jz @F
|
||||
|
||||
mov [edx+TASKDATA.state], 1
|
||||
call change_task
|
||||
jmp .forever
|
||||
@@:
|
||||
mov edx, [esp+MUTEX_WAITER.next]
|
||||
mov eax, [esp+MUTEX_WAITER.prev]
|
||||
|
||||
mov [eax+MUTEX_WAITER.next], edx
|
||||
cmp [ecx+MUTEX.next], esi
|
||||
mov [edx+MUTEX_WAITER.prev], eax
|
||||
jne @F
|
||||
|
||||
mov [ecx+MUTEX.count], 0
|
||||
@@:
|
||||
add esp, MUTEX_WAITER.sizeof
|
||||
|
||||
pop esi
|
||||
popfd
|
||||
.done:
|
||||
ret
|
||||
|
||||
;void __fastcall mutex_unlock(struct mutex *lock)
|
||||
|
||||
align 4
|
||||
mutex_unlock:
|
||||
|
||||
pushfd
|
||||
cli
|
||||
|
||||
lea eax, [ecx+MUTEX.next]
|
||||
cmp eax, [ecx+MUTEX.next]
|
||||
mov [ecx+MUTEX.count], 1
|
||||
je @F
|
||||
|
||||
mov eax, [eax+MUTEX_WAITER.task]
|
||||
mov [eax+TASKDATA.state], 0
|
||||
@@:
|
||||
popfd
|
||||
ret
|
||||
|
||||
|
||||
purge MUTEX_WAITER
|
||||
|
||||
if 0
|
||||
|
||||
struc TIMER
|
||||
{
|
||||
.next dd ?
|
||||
.exp_time dd ?
|
||||
.func dd ?
|
||||
.arg dd ?
|
||||
}
|
||||
|
||||
|
||||
MAX_PROIRITY 0 ; highest, used for kernel tasks
|
||||
MAX_USER_PRIORITY 0 ; highest priority for user processes
|
||||
USER_PRIORITY 7 ; default (should correspond to nice 0)
|
||||
MIN_USER_PRIORITY 14 ; minimum priority for user processes
|
||||
IDLE_PRIORITY 15 ; lowest, only IDLE process goes here
|
||||
NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1
|
||||
|
||||
uglobal
|
||||
rdy_head rd 16
|
||||
endg
|
||||
|
||||
align 4
|
||||
pick_task:
|
||||
|
||||
xor eax, eax
|
||||
.pick:
|
||||
mov ebx, [rdy_head+eax*4]
|
||||
test ebx, ebx
|
||||
jz .next
|
||||
|
||||
mov [next_task], ebx
|
||||
test [ebx+flags.billable]
|
||||
jz @F
|
||||
mov [bill_task], ebx
|
||||
@@:
|
||||
ret
|
||||
.next:
|
||||
inc eax
|
||||
jmp .pick
|
||||
|
||||
; param
|
||||
; eax= task
|
||||
;
|
||||
; retval
|
||||
; eax= task
|
||||
; ebx= queue
|
||||
; ecx= front if 1 or back if 0
|
||||
align 4
|
||||
shed:
|
||||
cmp [eax+.tics_left], 0 ;signed compare
|
||||
mov ebx, [eax+.priority]
|
||||
setg ecx
|
||||
jg @F
|
||||
|
||||
mov edx, [eax+.tics_quantum]
|
||||
mov [eax+.ticks_left], edx
|
||||
cmp ebx, (IDLE_PRIORITY-1)
|
||||
je @F
|
||||
inc ebx
|
||||
@@:
|
||||
ret
|
||||
|
||||
; param
|
||||
; eax= task
|
||||
align 4
|
||||
enqueue:
|
||||
call shed ;eax
|
||||
cmp [rdy_head+ebx*4],0
|
||||
jnz @F
|
||||
|
||||
mov [rdy_head+ebx*4], eax
|
||||
mov [rdy_tail+ebx*4], eax
|
||||
mov [eax+.next_ready], 0
|
||||
jmp .pick
|
||||
@@:
|
||||
test ecx, ecx
|
||||
jz .back
|
||||
|
||||
mov ecx, [rdy_head+ebx*4]
|
||||
mov [eax+.next_ready], ecx
|
||||
mov [rdy_head+ebx*4], eax
|
||||
jmp .pick
|
||||
.back:
|
||||
mov ecx, [rdy_tail+ebx*4]
|
||||
mov [ecx+.next_ready], eax
|
||||
mov [rdy_tail+ebx*4], eax
|
||||
mov [eax+.next_ready], 0
|
||||
.pick:
|
||||
call pick_proc ;select next task
|
||||
ret
|
||||
|
||||
end if
|
188
kernel/branches/kolibri-cfg/core/string.inc
Normal file
188
kernel/branches/kolibri-cfg/core/string.inc
Normal file
@ -0,0 +1,188 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; Author: Kees J. Bot 1 Jan 1994 ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
; size_t strncat(char *s1, const char *s2, size_t n)
|
||||
; Append string s2 to s1.
|
||||
|
||||
; char *strchr(const char *s, int c)
|
||||
|
||||
|
||||
; int strncmp(const char *s1, const char *s2, size_t n)
|
||||
; Compare two strings.
|
||||
|
||||
; char *strncpy(char *s1, const char *s2, size_t n)
|
||||
; Copy string s2 to s1.
|
||||
|
||||
; size_t strnlen(const char *s, size_t n)
|
||||
; Return the length of a string.
|
||||
|
||||
; proc strrchr stdcall, s:dword, c:dword
|
||||
; Look for the last occurrence a character in a string.
|
||||
|
||||
proc strncat stdcall, s1:dword, s2:dword, n:dword
|
||||
push esi
|
||||
push edi
|
||||
mov edi, [s1] ; String s1
|
||||
mov edx, [n] ; Maximum length
|
||||
|
||||
mov ecx, -1
|
||||
xor al, al ; Null byte
|
||||
cld
|
||||
repne scasb ; Look for the zero byte in s1
|
||||
dec edi ; Back one up (and clear 'Z' flag)
|
||||
push edi ; Save end of s1
|
||||
mov edi, [s2] ; edi = string s2
|
||||
mov ecx, edx ; Maximum count
|
||||
repne scasb ; Look for the end of s2
|
||||
jne @F
|
||||
inc ecx ; Exclude null byte
|
||||
@@:
|
||||
sub edx, ecx ; Number of bytes in s2
|
||||
mov ecx, edx
|
||||
mov esi, [s2] ; esi = string s2
|
||||
pop edi ; edi = end of string s1
|
||||
rep movsb ; Copy bytes
|
||||
stosb ; Add a terminating null
|
||||
mov eax, [s1] ; Return s1
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc strncmp stdcall, s1:dword, s2:dword, n:dword
|
||||
|
||||
push esi
|
||||
push edi
|
||||
mov ecx, [n]
|
||||
test ecx, ecx ; Max length is zero?
|
||||
je .done
|
||||
|
||||
mov esi, [s1] ; esi = string s1
|
||||
mov edi, [s2] ; edi = string s2
|
||||
cld
|
||||
.compare:
|
||||
cmpsb ; Compare two bytes
|
||||
jne .done
|
||||
cmp byte [esi-1], 0 ; End of string?
|
||||
je .done
|
||||
dec ecx ; Length limit reached?
|
||||
jne .compare
|
||||
.done:
|
||||
seta al ; al = (s1 > s2)
|
||||
setb ah ; ah = (s1 < s2)
|
||||
sub al, ah
|
||||
movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc strncpy stdcall, s1:dword, s2:dword, n:dword
|
||||
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov ecx, [n] ; Maximum length
|
||||
mov edi, [s2] ; edi = string s2
|
||||
xor al, al ; Look for a zero byte
|
||||
mov edx, ecx ; Save maximum count
|
||||
cld
|
||||
repne scasb ; Look for end of s2
|
||||
sub edx, ecx ; Number of bytes in s2 including null
|
||||
xchg ecx, edx
|
||||
mov esi, [s2] ; esi = string s2
|
||||
mov edi, [s1] ; edi = string s1
|
||||
rep movsb ; Copy bytes
|
||||
|
||||
mov ecx, edx ; Number of bytes not copied
|
||||
rep stosb ; strncpy always copies n bytes by null padding
|
||||
mov eax, [s1] ; Return s1
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc strnlen stdcall, s:dword, n:dword
|
||||
|
||||
push edi
|
||||
mov edi, [s] ; edi = string
|
||||
xor al, al ; Look for a zero byte
|
||||
mov edx, ecx ; Save maximum count
|
||||
cmp cl, 1 ; 'Z' bit must be clear if ecx = 0
|
||||
cld
|
||||
repne scasb ; Look for zero
|
||||
jne @F
|
||||
inc ecx ; Don't count zero byte
|
||||
@@:
|
||||
mov eax, edx
|
||||
sub eax, ecx ; Compute bytes scanned
|
||||
pop edi
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc strchr stdcall, s:dword, c:dword
|
||||
push edi
|
||||
cld
|
||||
mov edi, [s] ; edi = string
|
||||
mov edx, 16 ; Look at small chunks of the string
|
||||
.next:
|
||||
shl edx, 1 ; Chunks become bigger each time
|
||||
mov ecx, edx
|
||||
xor al, al ; Look for the zero at the end
|
||||
repne scasb
|
||||
pushf ; Remember the flags
|
||||
sub ecx, edx
|
||||
neg ecx ; Some or all of the chunk
|
||||
sub edi, ecx ; Step back
|
||||
mov eax, [c] ; The character to look for
|
||||
repne scasb
|
||||
je .found
|
||||
popf ; Did we find the end of string earlier?
|
||||
jne .next ; No, try again
|
||||
xor eax, eax ; Return NULL
|
||||
pop edi
|
||||
ret
|
||||
.found:
|
||||
pop eax ; Get rid of those flags
|
||||
lea eax, [edi-1] ; Address of byte found
|
||||
pop edi
|
||||
ret
|
||||
|
||||
endp
|
||||
|
||||
|
||||
proc strrchr stdcall, s:dword, c:dword
|
||||
push edi
|
||||
mov edi, [s] ; edi = string
|
||||
mov ecx, -1
|
||||
xor al, al
|
||||
cld
|
||||
repne scasb ; Look for the end of the string
|
||||
not ecx ; -1 - ecx = Length of the string + null
|
||||
dec edi ; Put edi back on the zero byte
|
||||
mov eax, [c] ; The character to look for
|
||||
std ; Downwards search
|
||||
repne scasb
|
||||
cld ; Direction bit back to default
|
||||
jne .fail
|
||||
lea eax, [edi+1] ; Found it
|
||||
pop edi
|
||||
ret
|
||||
.fail:
|
||||
xor eax, eax ; Not there
|
||||
pop edi
|
||||
ret
|
||||
endp
|
||||
|
||||
|
119
kernel/branches/kolibri-cfg/core/sync.inc
Normal file
119
kernel/branches/kolibri-cfg/core/sync.inc
Normal file
@ -0,0 +1,119 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; Synhronization for MenuetOS. ;;
|
||||
;; Author: Halyavin Andrey, halyavin@land.ru ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
if ~defined sync_inc
|
||||
sync_inc_fix:
|
||||
sync_inc fix sync_inc_fix
|
||||
|
||||
;simplest mutex.
|
||||
macro SimpleMutex name
|
||||
{
|
||||
; iglobal
|
||||
name dd 0
|
||||
name#.type = 1
|
||||
; endg
|
||||
}
|
||||
macro WaitSimpleMutex name
|
||||
{
|
||||
local start_wait,ok
|
||||
start_wait=$
|
||||
cli
|
||||
cmp [name],dword 0
|
||||
jz ok
|
||||
sti
|
||||
call change_task
|
||||
jmp start_wait
|
||||
ok=$
|
||||
push eax
|
||||
mov eax,dword [TASK_BASE+second_base_address]
|
||||
mov eax,[eax+TASKDATA.pid]
|
||||
mov [name],eax
|
||||
pop eax
|
||||
sti
|
||||
}
|
||||
macro ReleaseSimpleMutex name
|
||||
{
|
||||
mov [name],dword 0
|
||||
}
|
||||
macro TryWaitSimpleMutex name ;result in eax and in flags
|
||||
{
|
||||
local ok,try_end
|
||||
cmp [name],dword 0
|
||||
jz ok
|
||||
xor eax,eax
|
||||
jmp try_end
|
||||
ok=$
|
||||
xor eax,eax
|
||||
inc eax
|
||||
try_end=$
|
||||
}
|
||||
macro SimpleCriticalSection name
|
||||
{
|
||||
; iglobal
|
||||
name dd 0
|
||||
dd 0
|
||||
name#.type=2
|
||||
; endg
|
||||
}
|
||||
macro WaitSimpleCriticalSection name
|
||||
{
|
||||
local start_wait,first_wait,inc_counter,end_wait
|
||||
push eax
|
||||
mov eax,[TASK_BASE+second_base_address]
|
||||
mov eax,[eax+TASKDATA.pid]
|
||||
start_wait=$
|
||||
cli
|
||||
cmp [name],dword 0
|
||||
jz first_wait
|
||||
cmp [name],eax
|
||||
jz inc_counter
|
||||
sti
|
||||
call change_task
|
||||
jmp start_wait
|
||||
first_wait=$
|
||||
mov [name],eax
|
||||
mov [name+4],dword 1
|
||||
jmp end_wait
|
||||
inc_counter=$
|
||||
inc dword [name+4]
|
||||
end_wait=$
|
||||
sti
|
||||
pop eax
|
||||
}
|
||||
macro ReleaseSimpleCriticalSection name
|
||||
{
|
||||
local release_end
|
||||
dec dword [name+4]
|
||||
jnz release_end
|
||||
mov [name],dword 0
|
||||
release_end=$
|
||||
}
|
||||
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
|
||||
{
|
||||
local ok,try_end
|
||||
mov eax,[CURRENT_TASK+second_base_address]
|
||||
mov eax,[eax+TASKDATA.pid]
|
||||
cmp [name],eax
|
||||
jz ok
|
||||
cmp [name],0
|
||||
jz ok
|
||||
xor eax,eax
|
||||
jmp try_end
|
||||
ok=$
|
||||
xor eax,eax
|
||||
inc eax
|
||||
try_end=$
|
||||
}
|
||||
_cli equ call MEM_HeapLock
|
||||
_sti equ call MEM_HeapUnLock
|
||||
end if
|
||||
|
834
kernel/branches/kolibri-cfg/core/sys32.inc
Normal file
834
kernel/branches/kolibri-cfg/core/sys32.inc
Normal file
@ -0,0 +1,834 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; ;;
|
||||
;; MenuetOS process management, protected ring3 ;;
|
||||
;; ;;
|
||||
;; Distributed under GPL. See file COPYING for details. ;;
|
||||
;; Copyright 2003 Ville Turjanmaa ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
align 4 ;3A08
|
||||
build_interrupt_table:
|
||||
mov edi, idts
|
||||
mov esi, sys_int
|
||||
mov ecx, 0x40
|
||||
mov eax, (10001110b shl 24) + os_code
|
||||
@@: movsw ;low word of code-entry
|
||||
stosd ;interrupt gate type : os_code selector
|
||||
movsw ;high word of code-entry
|
||||
loop @b
|
||||
movsd ;copy low dword of trap gate for int 0x40
|
||||
movsd ;copy high dword of trap gate for int 0x40
|
||||
lidt [esi]
|
||||
ret
|
||||
|
||||
iglobal
|
||||
align 4
|
||||
sys_int:
|
||||
;exception handlers addresses (for interrupt gate construction)
|
||||
dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc
|
||||
dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15
|
||||
dd e16, e17,e18, e19
|
||||
times 12 dd unknown_interrupt ;int_20..int_31
|
||||
|
||||
;interrupt handlers addresses (for interrupt gate construction)
|
||||
dd irq0, irq_serv.irq_1, irq_serv.irq_2
|
||||
if USE_COM_IRQ
|
||||
dd irq_serv.irq_3, irq_serv.irq_4
|
||||
else
|
||||
dd p_irq3, p_irq4 ;??? íåñòûêîâêà
|
||||
end if
|
||||
dd irq_serv.irq_5, p_irq6, irq_serv.irq_7
|
||||
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10
|
||||
dd irq_serv.irq_11, irq_serv.irq_12, irqD,p_irq14,p_irq15
|
||||
times 16 dd unknown_interrupt ;int_0x30..int_0x3F
|
||||
|
||||
;int_0x40 gate trap (for directly copied)
|
||||
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
|
||||
|
||||
idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data)
|
||||
dw 2*($-sys_int-4)-1
|
||||
dd idts ;0x8000B100
|
||||
dw 0 ;ïðîñòî âûðàâíèâàíèå
|
||||
|
||||
msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b
|
||||
dd msg_exc_c,msg_exc_d,msg_exc_e
|
||||
|
||||
msg_exc_8 db "Double fault", 0
|
||||
msg_exc_u db "Undefined Exception", 0
|
||||
msg_exc_a db "Invalid TSS", 0
|
||||
msg_exc_b db "Segment not present", 0
|
||||
msg_exc_c db "Stack fault", 0
|
||||
msg_exc_d db "General protection fault", 0
|
||||
msg_exc_e db "Page fault", 0
|
||||
|
||||
msg_sel_ker db "kernel", 0
|
||||
msg_sel_app db "application", 0
|
||||
|
||||
endg
|
||||
|
||||
macro save_ring3_context {
|
||||
pushad
|
||||
}
|
||||
macro restore_ring3_context {
|
||||
popad
|
||||
}
|
||||
macro exc_wo_code [num] {
|
||||
e#num :
|
||||
save_ring3_context
|
||||
mov bl, num
|
||||
jmp exc_c
|
||||
} exc_wo_code 0,1,2,3,4,5,6,15,16,19
|
||||
|
||||
macro exc_w_code [num] {
|
||||
e#num :
|
||||
add esp, 4
|
||||
save_ring3_context
|
||||
mov bl, num
|
||||
jmp exc_c
|
||||
} exc_w_code 8,9,10,11,12,13,17,18
|
||||
|
||||
|
||||
uglobal
|
||||
pf_err_code dd ?
|
||||
endg
|
||||
|
||||
page_fault_exc: ; äóðàêîóñòî÷èâîñòü: ñåëåêòîðû èñïîð÷åíû...
|
||||
pop [ss:pf_err_code]; äåéñòâèòåëüíî äî ñëåäóþùåãî #PF
|
||||
save_ring3_context
|
||||
mov bl,14
|
||||
|
||||
exc_c: ; èñêëþ÷åíèÿ (âñå, êðîìå 7-ãî - #NM)
|
||||
; Ôðýéì ñòåêà ïðè èñêëþ÷åíèè/ïðåðûâàíèè èç 3-ãî êîëüöà + pushad (ò.å., èìåííî çäåñü)
|
||||
reg_ss equ esp+0x30
|
||||
reg_esp3 equ esp+0x2C
|
||||
reg_eflags equ esp+0x28
|
||||
reg_cs3 equ esp+0x24
|
||||
reg_eip equ esp+0x20
|
||||
; ýòî ôðýéì îò pushad
|
||||
reg_eax equ esp+0x1C
|
||||
reg_ecx equ esp+0x18
|
||||
reg_edx equ esp+0x14
|
||||
reg_ebx equ esp+0x10
|
||||
reg_esp0 equ esp+0x0C
|
||||
reg_ebp equ esp+0x08
|
||||
reg_esi equ esp+0x04
|
||||
reg_edi equ esp+0x00
|
||||
|
||||
Mov ds,ax,app_data ; çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ
|
||||
mov es,ax ; â ñåãìåíòíûå ðåãèñòðû
|
||||
cld ; è ïðèâîäèì DF ê ñòàíäàðòó
|
||||
movzx ebx,bl
|
||||
; redirect to V86 manager? (EFLAGS & 0x20000) != 0?
|
||||
test byte[reg_eflags+2],2
|
||||
jnz v86_exc_c
|
||||
cmp bl,14 ; #PF
|
||||
jne @f
|
||||
call page_fault_handler ; SEE: core/memory.inc
|
||||
@@: mov esi, [current_slot]
|
||||
btr [esi+APPDATA.except_mask], ebx
|
||||
jnc @f
|
||||
mov eax,[esi+APPDATA.exc_handler]
|
||||
test eax, eax
|
||||
jnz IRetToUserHook
|
||||
@@: cli
|
||||
mov eax, [esi+APPDATA.debugger_slot]
|
||||
test eax, eax
|
||||
jnz .debug
|
||||
sti
|
||||
; not debuggee => say error and terminate
|
||||
call show_error_parameters ;; only ONE using, inline ???
|
||||
;mov edx, [TASK_BASE]
|
||||
mov [edx + TASKDATA.state], byte 4 ; terminate
|
||||
jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc
|
||||
.debug:
|
||||
; we are debugged process, notify debugger and suspend ourself
|
||||
; eax=debugger PID
|
||||
mov ecx,1 ; debug_message code=other_exception
|
||||
cmp bl,1 ; #DB
|
||||
jne .notify ; notify debugger and suspend ourself
|
||||
mov ebx, dr6 ; debug_message data=DR6_image
|
||||
xor edx, edx
|
||||
mov dr6, edx
|
||||
mov edx, dr7
|
||||
mov cl, not 8
|
||||
.l1: shl dl,2
|
||||
jc @f
|
||||
and bl, cl
|
||||
@@: sar cl,1
|
||||
jc .l1
|
||||
mov cl, 3 ; debug_message code=debug_exception
|
||||
.notify:
|
||||
push ebx ; debug_message data
|
||||
mov ebx, [TASK_BASE]
|
||||
push [ebx+TASKDATA.pid] ; PID
|
||||
push ecx ; debug_message code ((here: ecx==1/3))
|
||||
mov cl, 12 ; debug_message size
|
||||
call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc
|
||||
add esp,12
|
||||
mov edx, [TASK_BASE]
|
||||
mov byte [edx+TASKDATA.state], 1 ; suspended
|
||||
call change_task ; SEE: core/shed.inc
|
||||
restore_ring3_context
|
||||
iretd
|
||||
|
||||
IRetToUserHook:
|
||||
xchg eax, [reg_eip]
|
||||
sub dword[reg_esp3], 8
|
||||
mov edi, [reg_esp3]
|
||||
stosd
|
||||
mov [edi], ebx
|
||||
restore_ring3_context
|
||||
unknown_interrupt:
|
||||
iretd
|
||||
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
show_error_parameters:
|
||||
mov edx,[TASK_BASE] ;not scratched below
|
||||
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid]
|
||||
cmp bl, 0x08
|
||||
jb .l0
|
||||
cmp bl, 0x0e
|
||||
jbe .l1
|
||||
.l0: mov bl, 0x09
|
||||
.l1: mov eax,[msg_fault_sel+ebx*4 - 0x08*4]
|
||||
DEBUGF 1, "K : %s\n", eax
|
||||
mov eax, [reg_cs3+4]
|
||||
mov edi, msg_sel_app
|
||||
mov ebx, [reg_esp3+4]
|
||||
cmp eax, app_code
|
||||
je @f
|
||||
mov edi, msg_sel_ker
|
||||
mov ebx, [reg_esp0+4]
|
||||
@@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4]
|
||||
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4]
|
||||
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx
|
||||
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi
|
||||
ret
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
restore reg_ss
|
||||
restore reg_esp3
|
||||
restore reg_eflags
|
||||
restore reg_cs
|
||||
restore reg_eip
|
||||
restore reg_eax
|
||||
restore reg_ecx
|
||||
restore reg_edx
|
||||
restore reg_ebx
|
||||
restore reg_esp0
|
||||
restore reg_ebp
|
||||
restore reg_esi
|
||||
restore reg_edi
|
||||
|
||||
; irq1 -> hid/keyboard.inc
|
||||
macro irqh [num] {
|
||||
p_irq#num :
|
||||
mov edi, num
|
||||
jmp irqhandler
|
||||
}
|
||||
|
||||
|
||||
|
||||
p_irq6:
|
||||
save_ring3_context
|
||||
mov ax, app_data ;os_data
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov edi, 6
|
||||
cmp [v86_irqhooks+edi*8], 0
|
||||
jnz v86_irq2
|
||||
call fdc_irq
|
||||
call ready_for_next_irq
|
||||
restore_ring3_context
|
||||
iret
|
||||
|
||||
|
||||
p_irq14:
|
||||
save_ring3_context
|
||||
mov ax, app_data ;os_data
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov edi, 14
|
||||
cmp [v86_irqhooks+edi*8], 0
|
||||
jnz v86_irq2
|
||||
; mov byte [BOOT_VAR + 0x48E], 0xFF
|
||||
call [irq14_func]
|
||||
call ready_for_next_irq_1
|
||||
restore_ring3_context
|
||||
iret
|
||||
p_irq15:
|
||||
save_ring3_context
|
||||
mov ax, app_data ;os_data
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov edi, 15
|
||||
cmp [v86_irqhooks+edi*8], 0
|
||||
jnz v86_irq2
|
||||
; mov byte [BOOT_VAR + 0x48E], 0xFF
|
||||
call [irq15_func]
|
||||
call ready_for_next_irq_1
|
||||
restore_ring3_context
|
||||
iret
|
||||
|
||||
ready_for_next_irq:
|
||||
mov eax,5
|
||||
mov [check_idle_semaphore],eax
|
||||
; mov al, 0x20
|
||||
add eax,(0x20-0x5)
|
||||
|
||||
out 0x20, al
|
||||
ret
|
||||
;destroy eax
|
||||
ready_for_next_irq_1:
|
||||
mov eax,5
|
||||
mov [check_idle_semaphore],eax
|
||||
; mov al, 0x20
|
||||
add eax,(0x20-0x5)
|
||||
out 0xa0,al
|
||||
out 0x20, al
|
||||
ret
|
||||
|
||||
irqD:
|
||||
push eax
|
||||
xor eax,eax
|
||||
out 0xf0,al
|
||||
mov al,0x20
|
||||
out 0xa0,al
|
||||
out 0x20,al
|
||||
pop eax
|
||||
iret
|
||||
|
||||
|
||||
irqh 2,3,4,5,7,8,9,10,11
|
||||
|
||||
irqhandler:
|
||||
|
||||
mov esi,edi ; 1
|
||||
shl esi,6 ; 1
|
||||
add esi,irq00read ; 1
|
||||
shl edi,12 ; 1
|
||||
add edi,IRQ_SAVE
|
||||
mov ecx,16
|
||||
|
||||
irqnewread:
|
||||
dec ecx
|
||||
js irqover
|
||||
|
||||
movzx edx, word [esi] ; 2+
|
||||
|
||||
test edx, edx ; 1
|
||||
jz irqover
|
||||
|
||||
|
||||
mov ebx, [edi] ; address of begin of buffer in edi ; + 0x0 dword - data size
|
||||
mov eax, 4000 ; + 0x4 dword - data begin offset
|
||||
cmp ebx, eax
|
||||
je irqfull
|
||||
add ebx, [edi + 0x4] ; add data size to data begin offset
|
||||
cmp ebx, eax ; if end of buffer, begin cycle again
|
||||
jb @f
|
||||
|
||||
xor ebx, ebx
|
||||
|
||||
@@:
|
||||
add ebx, edi
|
||||
movzx eax, byte[esi + 3] ; get type of data being received 1 - byte, 2 - word
|
||||
dec eax
|
||||
jz irqbyte
|
||||
dec eax
|
||||
jnz noirqword
|
||||
|
||||
in ax,dx
|
||||
cmp ebx, 3999 ; check for address odd in the end of buffer
|
||||
jne .odd
|
||||
mov [ebx + 0x10], ax
|
||||
jmp .add_size
|
||||
.odd:
|
||||
mov [ebx + 0x10], al ; I could make mistake here :)
|
||||
mov [edi + 0x10], ah
|
||||
.add_size:
|
||||
add dword [edi], 2
|
||||
jmp nextport
|
||||
|
||||
|
||||
irqbyte:
|
||||
in al,dx
|
||||
mov [ebx + 0x10],al
|
||||
inc dword [edi]
|
||||
nextport:
|
||||
add esi,4
|
||||
jmp irqnewread
|
||||
|
||||
|
||||
noirqword:
|
||||
irqfull:
|
||||
irqover:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
set_application_table_status:
|
||||
push eax
|
||||
|
||||
mov eax,[CURRENT_TASK]
|
||||
shl eax, 5
|
||||
add eax,CURRENT_TASK+TASKDATA.pid
|
||||
mov eax,[eax]
|
||||
|
||||
mov [application_table_status],eax
|
||||
|
||||
pop eax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
clear_application_table_status:
|
||||
push eax
|
||||
|
||||
mov eax,[CURRENT_TASK]
|
||||
shl eax, 5
|
||||
add eax,CURRENT_TASK+TASKDATA.pid
|
||||
mov eax,[eax]
|
||||
|
||||
cmp eax,[application_table_status]
|
||||
jne apptsl1
|
||||
xor eax,eax
|
||||
mov [application_table_status],eax
|
||||
apptsl1:
|
||||
|
||||
pop eax
|
||||
|
||||
ret
|
||||
|
||||
; * eax = 64 - íîìåð ôóíêöèè
|
||||
; * ebx = 1 - åäèíñòâåííàÿ ïîäôóíêöèÿ
|
||||
; * ecx = íîâûé ðàçìåð ïàìÿòè
|
||||
;Âîçâðàùàåìîå çíà÷åíèå:
|
||||
; * eax = 0 - óñïåøíî
|
||||
; * eax = 1 - íåäîñòàòî÷íî ïàìÿòè
|
||||
|
||||
sys_resize_app_memory:
|
||||
; ebx = 1 - resize
|
||||
; ecx = new amount of memory
|
||||
|
||||
; cmp eax,1
|
||||
dec ebx
|
||||
jnz .no_application_mem_resize
|
||||
stdcall new_mem_resize, ecx
|
||||
mov [esp+32], eax
|
||||
.no_application_mem_resize:
|
||||
ret
|
||||
|
||||
iglobal
|
||||
; process_terminating db 'K : Process - terminating',13,10,0
|
||||
; process_terminated db 'K : Process - done',13,10,0
|
||||
msg_obj_destroy db 'K : destroy app object',13,10,0
|
||||
endg
|
||||
|
||||
; param
|
||||
; esi= slot
|
||||
|
||||
terminate: ; terminate application
|
||||
|
||||
.slot equ esp ;locals
|
||||
|
||||
push esi ;save .slot
|
||||
|
||||
shl esi, 8
|
||||
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0
|
||||
jne @F
|
||||
pop esi
|
||||
shl esi, 5
|
||||
mov [CURRENT_TASK+esi+TASKDATA.state], 9
|
||||
ret
|
||||
@@:
|
||||
;mov esi,process_terminating
|
||||
;call sys_msg_board_str
|
||||
@@:
|
||||
cli
|
||||
cmp [application_table_status],0
|
||||
je term9
|
||||
sti
|
||||
call change_task
|
||||
jmp @b
|
||||
term9:
|
||||
call set_application_table_status
|
||||
|
||||
; if the process is in V86 mode...
|
||||
mov eax, [.slot]
|
||||
shl eax, 8
|
||||
mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack]
|
||||
add esi, RING0_STACK_SIZE
|
||||
cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi
|
||||
jz .nov86
|
||||
; ...it has page directory for V86 mode
|
||||
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
|
||||
mov ecx, [esi+4]
|
||||
mov [eax+SLOT_BASE+APPDATA.dir_table], ecx
|
||||
; ...and I/O permission map for V86 mode
|
||||
mov ecx, [esi+12]
|
||||
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
|
||||
mov ecx, [esi+8]
|
||||
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
|
||||
.nov86:
|
||||
|
||||
mov esi, [.slot]
|
||||
shl esi,8
|
||||
add esi, SLOT_BASE+APP_OBJ_OFFSET
|
||||
@@:
|
||||
mov eax, [esi+APPOBJ.fd]
|
||||
test eax, eax
|
||||
jz @F
|
||||
|
||||
cmp eax, esi
|
||||
je @F
|
||||
|
||||
push esi
|
||||
call [eax+APPOBJ.destroy]
|
||||
DEBUGF 1,"%s",msg_obj_destroy
|
||||
pop esi
|
||||
jmp @B
|
||||
@@:
|
||||
|
||||
mov eax, [.slot]
|
||||
shl eax, 8
|
||||
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
|
||||
|
||||
mov esi, [.slot]
|
||||
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
|
||||
jne @F
|
||||
|
||||
mov [fpu_owner],1
|
||||
mov eax, [256+SLOT_BASE+APPDATA.fpu_state]
|
||||
clts
|
||||
bt [cpu_caps], CAPS_SSE
|
||||
jnc .no_SSE
|
||||
fxrstor [eax]
|
||||
jmp @F
|
||||
.no_SSE:
|
||||
fnclex
|
||||
frstor [eax]
|
||||
@@:
|
||||
|
||||
mov [KEY_COUNT],byte 0 ; empty keyboard buffer
|
||||
mov [BTN_COUNT],byte 0 ; empty button buffer
|
||||
|
||||
|
||||
; remove defined hotkeys
|
||||
mov eax, hotkey_list
|
||||
.loop:
|
||||
cmp [eax+8], esi
|
||||
jnz .cont
|
||||
mov ecx, [eax]
|
||||
jecxz @f
|
||||
push dword [eax+12]
|
||||
pop dword [ecx+12]
|
||||
@@:
|
||||
mov ecx, [eax+12]
|
||||
push dword [eax]
|
||||
pop dword [ecx]
|
||||
xor ecx, ecx
|
||||
mov [eax], ecx
|
||||
mov [eax+4], ecx
|
||||
mov [eax+8], ecx
|
||||
mov [eax+12], ecx
|
||||
.cont:
|
||||
add eax, 16
|
||||
cmp eax, hotkey_list+256*16
|
||||
jb .loop
|
||||
; remove hotkeys in buffer
|
||||
mov eax, hotkey_buffer
|
||||
.loop2:
|
||||
cmp [eax], esi
|
||||
jnz .cont2
|
||||
and dword [eax+4], 0
|
||||
and dword [eax], 0
|
||||
.cont2:
|
||||
add eax, 8
|
||||
cmp eax, hotkey_buffer+120*8
|
||||
jb .loop2
|
||||
|
||||
mov ecx,esi ; remove buttons
|
||||
bnewba2:
|
||||
mov edi,[BTN_ADDR]
|
||||
mov eax,edi
|
||||
cld
|
||||
movzx ebx,word [edi]
|
||||
inc bx
|
||||
bnewba:
|
||||
dec bx
|
||||
jz bnmba
|
||||
add eax,0x10
|
||||
cmp cx,[eax]
|
||||
jnz bnewba
|
||||
pusha
|
||||
mov ecx,ebx
|
||||
inc ecx
|
||||
shl ecx,4
|
||||
mov ebx,eax
|
||||
add eax,0x10
|
||||
call memmove
|
||||
dec dword [edi]
|
||||
popa
|
||||
jmp bnewba2
|
||||
bnmba:
|
||||
|
||||
pusha ; save window coordinates for window restoring
|
||||
cld
|
||||
shl esi,5
|
||||
add esi,window_data
|
||||
mov eax,[esi+WDATA.box.left]
|
||||
mov [draw_limits.left],eax
|
||||
add eax,[esi+WDATA.box.width]
|
||||
mov [draw_limits.right],eax
|
||||
mov eax,[esi+WDATA.box.top]
|
||||
mov [draw_limits.top],eax
|
||||
add eax,[esi+WDATA.box.height]
|
||||
mov [draw_limits.bottom],eax
|
||||
|
||||
xor eax, eax
|
||||
mov [esi+WDATA.box.left],eax
|
||||
mov [esi+WDATA.box.width],eax
|
||||
mov [esi+WDATA.box.top],eax
|
||||
mov [esi+WDATA.box.height],eax
|
||||
mov [esi+WDATA.cl_workarea],eax
|
||||
mov [esi+WDATA.cl_titlebar],eax
|
||||
mov [esi+WDATA.cl_frames],eax
|
||||
mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn
|
||||
lea edi, [esi-window_data+draw_data]
|
||||
mov ecx,32/4
|
||||
rep stosd
|
||||
popa
|
||||
|
||||
; debuggee test
|
||||
pushad
|
||||
mov edi, esi
|
||||
shl edi, 5
|
||||
mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
|
||||
test eax, eax
|
||||
jz .nodebug
|
||||
push 8
|
||||
pop ecx
|
||||
push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID
|
||||
push 2
|
||||
call debugger_notify
|
||||
pop ecx
|
||||
pop ecx
|
||||
.nodebug:
|
||||
popad
|
||||
|
||||
mov ebx, [.slot]
|
||||
shl ebx, 8
|
||||
push ebx
|
||||
mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack]
|
||||
|
||||
stdcall kernel_free, ebx
|
||||
|
||||
pop ebx
|
||||
mov ebx,[SLOT_BASE+ebx+APPDATA.cur_dir]
|
||||
stdcall kernel_free, ebx
|
||||
|
||||
mov edi, [.slot]
|
||||
shl edi,8
|
||||
add edi,SLOT_BASE
|
||||
|
||||
mov eax, [edi+APPDATA.io_map]
|
||||
cmp eax, [SLOT_BASE+256+APPDATA.io_map]
|
||||
je @F
|
||||
call free_page
|
||||
@@:
|
||||
mov eax, [edi+APPDATA.io_map+4]
|
||||
cmp eax, [SLOT_BASE+256+APPDATA.io_map+4]
|
||||
je @F
|
||||
call free_page
|
||||
@@:
|
||||
mov eax, 0x20202020
|
||||
stosd
|
||||
stosd
|
||||
stosd
|
||||
mov ecx,244/4
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
|
||||
; activate window
|
||||
movzx eax, word [WIN_STACK + esi*2]
|
||||
cmp eax, [TASK_COUNT]
|
||||
jne .dont_activate
|
||||
pushad
|
||||
.check_next_window:
|
||||
dec eax
|
||||
cmp eax, 1
|
||||
jbe .nothing_to_activate
|
||||
lea esi, [WIN_POS+eax*2]
|
||||
movzx edi, word [esi] ; edi = process
|
||||
shl edi, 5
|
||||
cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots
|
||||
je .check_next_window
|
||||
add edi, window_data
|
||||
; \begin{diamond}[19.09.2006]
|
||||
; skip minimized windows
|
||||
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
|
||||
jnz .check_next_window
|
||||
; \end{diamond}
|
||||
call waredraw
|
||||
.nothing_to_activate:
|
||||
popad
|
||||
.dont_activate:
|
||||
|
||||
push esi ; remove hd1 & cd & flp reservation
|
||||
shl esi, 5
|
||||
mov esi, [esi+CURRENT_TASK+TASKDATA.pid]
|
||||
cmp [hd1_status], esi
|
||||
jnz @f
|
||||
call free_hd_channel
|
||||
and [hd1_status], 0
|
||||
@@:
|
||||
cmp [cd_status], esi
|
||||
jnz @f
|
||||
call free_cd_channel
|
||||
and [cd_status], 0
|
||||
@@:
|
||||
cmp [flp_status], esi
|
||||
jnz @f
|
||||
and [flp_status], 0
|
||||
@@:
|
||||
pop esi
|
||||
cmp [bgrlockpid], esi
|
||||
jnz @f
|
||||
and [bgrlockpid], 0
|
||||
and [bgrlock], 0
|
||||
@@:
|
||||
|
||||
pusha ; remove all irq reservations
|
||||
mov eax,esi
|
||||
shl eax, 5
|
||||
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
|
||||
mov edi,irq_owner
|
||||
xor ebx, ebx
|
||||
xor edx, edx
|
||||
newirqfree:
|
||||
cmp [edi + 4 * ebx], eax
|
||||
jne nofreeirq
|
||||
mov [edi + 4 * ebx], edx ; remove irq reservation
|
||||
mov [irq_tab + 4 * ebx], edx ; remove irq handler
|
||||
mov [irq_rights + 4 * ebx], edx ; set access rights to full access
|
||||
nofreeirq:
|
||||
inc ebx
|
||||
cmp ebx, 16
|
||||
jb newirqfree
|
||||
popa
|
||||
|
||||
pusha ; remove all port reservations
|
||||
mov edx,esi
|
||||
shl edx, 5
|
||||
add edx,CURRENT_TASK
|
||||
mov edx,[edx+TASKDATA.pid]
|
||||
|
||||
rmpr0:
|
||||
|
||||
mov esi,[RESERVED_PORTS]
|
||||
|
||||
test esi,esi
|
||||
jz rmpr9
|
||||
|
||||
rmpr3:
|
||||
|
||||
mov edi,esi
|
||||
shl edi,4
|
||||
add edi,RESERVED_PORTS
|
||||
|
||||
cmp edx,[edi]
|
||||
je rmpr4
|
||||
|
||||
dec esi
|
||||
jnz rmpr3
|
||||
|
||||
jmp rmpr9
|
||||
|
||||
rmpr4:
|
||||
|
||||
mov ecx,256
|
||||
sub ecx,esi
|
||||
shl ecx,4
|
||||
|
||||
mov esi,edi
|
||||
add esi,16
|
||||
cld
|
||||
rep movsb
|
||||
|
||||
dec dword [RESERVED_PORTS]
|
||||
|
||||
jmp rmpr0
|
||||
|
||||
rmpr9:
|
||||
|
||||
popa
|
||||
mov edi,esi ; do not run this process slot
|
||||
shl edi, 5
|
||||
mov [edi+CURRENT_TASK + TASKDATA.state],byte 9
|
||||
; debugger test - terminate all debuggees
|
||||
mov eax, 2
|
||||
mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
|
||||
.xd0:
|
||||
cmp eax, [TASK_COUNT]
|
||||
ja .xd1
|
||||
cmp dword [ecx], esi
|
||||
jnz @f
|
||||
and dword [ecx], 0
|
||||
pushad
|
||||
xchg eax, ecx
|
||||
mov ebx, 2
|
||||
call sys_system
|
||||
popad
|
||||
@@:
|
||||
inc eax
|
||||
add ecx, 0x100
|
||||
jmp .xd0
|
||||
.xd1:
|
||||
; call systest
|
||||
sti ; .. and life goes on
|
||||
|
||||
mov eax, [draw_limits.left]
|
||||
mov ebx, [draw_limits.top]
|
||||
mov ecx, [draw_limits.right]
|
||||
mov edx, [draw_limits.bottom]
|
||||
call calculatescreen
|
||||
xor eax, eax
|
||||
xor esi, esi
|
||||
call redrawscreen
|
||||
|
||||
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background
|
||||
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse
|
||||
|
||||
and [application_table_status],0
|
||||
;mov esi,process_terminated
|
||||
;call sys_msg_board_str
|
||||
add esp, 4
|
||||
ret
|
||||
restore .slot
|
||||
|
||||
iglobal
|
||||
boot_sched_1 db 'Building gdt tss pointer',0
|
||||
boot_sched_2 db 'Building IDT table',0
|
||||
endg
|
||||
|
||||
|
||||
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
|
200
kernel/branches/kolibri-cfg/core/syscall.inc
Normal file
200
kernel/branches/kolibri-cfg/core/syscall.inc
Normal file
@ -0,0 +1,200 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
; Old style system call converter
|
||||
align 16
|
||||
cross_order:
|
||||
; load all registers in crossed order
|
||||
mov eax, ebx
|
||||
mov ebx, ecx
|
||||
mov ecx, edx
|
||||
mov edx, esi
|
||||
mov esi, edi
|
||||
movzx edi, byte[esp+28 + 4]
|
||||
sub edi,53
|
||||
call dword [servetable+edi*4]
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; SYSENTER ENTRY ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 32
|
||||
sysenter_entry:
|
||||
; Íàñòðàèâàåì ñòåê
|
||||
mov esp, [ss:tss._esp0]
|
||||
sti
|
||||
push ebp ; save app esp + 4
|
||||
mov ebp, [ebp] ; ebp - original ebp
|
||||
;------------------
|
||||
pushad
|
||||
cld
|
||||
|
||||
movzx eax, al
|
||||
call dword [servetable2 + eax * 4]
|
||||
|
||||
popad
|
||||
;------------------
|
||||
xchg ecx, [ss:esp] ; â âåðøèí ñòåêà - app ecx, ecx - app esp + 4
|
||||
sub ecx, 4
|
||||
xchg edx, [ecx] ; edx - return point, & save original edx
|
||||
push edx
|
||||
mov edx, [ss:esp + 4]
|
||||
mov [ecx + 4], edx ; save original ecx
|
||||
pop edx
|
||||
sysexit
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; SYSTEM CALL ENTRY ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 16
|
||||
i40:
|
||||
pushad
|
||||
cld
|
||||
movzx eax, al
|
||||
call dword [servetable2 + eax * 4]
|
||||
popad
|
||||
iretd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; SYSCALL ENTRY ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
align 32
|
||||
syscall_entry:
|
||||
; cli syscall clear IF
|
||||
xchg esp, [ss:tss._esp0]
|
||||
push ecx
|
||||
lea ecx, [esp+4]
|
||||
xchg ecx, [ss:tss._esp0]
|
||||
sti
|
||||
push ecx
|
||||
mov ecx, [ecx]
|
||||
;------------------
|
||||
pushad
|
||||
cld
|
||||
|
||||
movzx eax, al
|
||||
call dword [servetable2 + eax * 4]
|
||||
|
||||
popad
|
||||
;------------------
|
||||
mov ecx, [ss:esp+4]
|
||||
pop esp
|
||||
sysret
|
||||
|
||||
iglobal
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; SYSTEM FUNCTIONS TABLE ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 4
|
||||
servetable:
|
||||
dd socket ; 53-Socket interface
|
||||
dd 0
|
||||
dd 0
|
||||
dd 0
|
||||
dd 0
|
||||
dd file_system ; 58-Common file system interface
|
||||
dd 0
|
||||
dd 0
|
||||
dd 0
|
||||
dd 0 ; 62-PCI functions
|
||||
dd sys_msg_board ; 63-System message board
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; NEW SYSTEM FUNCTIONS TABLE ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
align 4
|
||||
servetable2:
|
||||
|
||||
dd syscall_draw_window ; 0-DrawWindow
|
||||
dd syscall_setpixel ; 1-SetPixel
|
||||
dd sys_getkey ; 2-GetKey
|
||||
dd sys_clock ; 3-GetTime
|
||||
dd syscall_writetext ; 4-WriteText
|
||||
dd delay_hs ; 5-DelayHs
|
||||
dd syscall_openramdiskfile ; 6-OpenRamdiskFile
|
||||
dd syscall_putimage ; 7-PutImage
|
||||
dd syscall_button ; 8-DefineButton
|
||||
dd sys_cpuusage ; 9-GetProcessInfo
|
||||
dd sys_waitforevent ; 10-WaitForEvent
|
||||
dd sys_getevent ; 11-CheckForEvent
|
||||
dd sys_redrawstat ; 12-BeginDraw and EndDraw
|
||||
dd syscall_drawrect ; 13-DrawRect
|
||||
dd syscall_getscreensize ; 14-GetScreenSize
|
||||
dd sys_background ; 15-bgr
|
||||
dd sys_cachetodiskette ; 16-FlushFloppyCache
|
||||
dd sys_getbutton ; 17-GetButton
|
||||
dd sys_system ; 18-System Services
|
||||
dd paleholder ; 19-reserved
|
||||
dd sys_midi ; 20-ResetMidi and OutputMidi
|
||||
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,.
|
||||
dd sys_settime ; 22-setting date,time,clock and alarm-clock
|
||||
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent
|
||||
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist
|
||||
dd undefined_syscall ; 25-reserved
|
||||
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
|
||||
dd undefined_syscall ; 27-reserved
|
||||
dd undefined_syscall ; 28-reserved
|
||||
dd sys_date ; 29-GetDate
|
||||
dd sys_current_directory ; 30-Get/SetCurrentDirectory
|
||||
dd undefined_syscall ; 31-reserved
|
||||
dd undefined_syscall ; 32-reserved
|
||||
dd undefined_syscall ; 33-reserved
|
||||
dd undefined_syscall ; 34-reserved
|
||||
dd syscall_getpixel ; 35-GetPixel
|
||||
dd syscall_getarea ; 36-GetArea
|
||||
dd readmousepos ; 37-GetMousePosition_ScreenRelative,.
|
||||
dd syscall_drawline ; 38-DrawLine
|
||||
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,.
|
||||
dd set_app_param ; 40-WantEvents
|
||||
dd syscall_getirqowner ; 41-GetIrqOwner
|
||||
dd get_irq_data ; 42-ReadIrqData
|
||||
dd sys_outport ; 43-SendDeviceData
|
||||
dd sys_programirq ; 44-ProgramIrqs
|
||||
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq
|
||||
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea
|
||||
dd display_number ; 47-WriteNum
|
||||
dd syscall_display_settings ; 48-SetRedrawType and SetButtonType
|
||||
dd sys_apm ; 49-Advanced Power Management (APM)
|
||||
dd syscall_set_window_shape ; 50-Window shape & scale
|
||||
dd syscall_threads ; 51-Threads
|
||||
dd stack_driver_stat ; 52-Stack driver status
|
||||
dd cross_order ; 53-Socket interface
|
||||
dd undefined_syscall ; 54-reserved
|
||||
dd sound_interface ; 55-Sound interface
|
||||
dd undefined_syscall ; 56-reserved
|
||||
dd sys_pcibios ; 57-PCI BIOS32
|
||||
dd cross_order ; 58-Common file system interface
|
||||
dd undefined_syscall ; 59-reserved
|
||||
dd sys_IPC ; 60-Inter Process Communication
|
||||
dd sys_gs ; 61-Direct graphics access
|
||||
dd pci_api ;cross_order ; 62-PCI functions
|
||||
dd cross_order ; 63-System message board
|
||||
dd sys_resize_app_memory ; 64-Resize application memory usage
|
||||
dd sys_putimage_palette ; 65-PutImagePalette
|
||||
dd sys_process_def ; 66-Process definitions - keyboard
|
||||
dd syscall_move_window ; 67-Window move or resize
|
||||
dd f68 ; 68-Some internal services
|
||||
dd sys_debug_services ; 69-Debug
|
||||
dd file_system_lfn ; 70-Common file system interface, version 2
|
||||
dd syscall_window_settings ; 71-Window settings
|
||||
dd sys_sendwindowmsg ; 72-Send window message
|
||||
dd blit_32 ; blitter;
|
||||
times 255 - ( ($-servetable2) /4 ) dd undefined_syscall
|
||||
dd sys_end ; -1-end application
|
||||
|
||||
endg
|
1178
kernel/branches/kolibri-cfg/core/taskman.inc
Normal file
1178
kernel/branches/kolibri-cfg/core/taskman.inc
Normal file
File diff suppressed because it is too large
Load Diff
223
kernel/branches/kolibri-cfg/core/test_malloc.asm
Normal file
223
kernel/branches/kolibri-cfg/core/test_malloc.asm
Normal file
@ -0,0 +1,223 @@
|
||||
; Tests of malloc()/free() from the kernel heap.
|
||||
; This file is not included in the kernel, it is just test application.
|
||||
use32
|
||||
db 'MENUET01'
|
||||
dd 1, start, i_end, mem, mem, 0, 0
|
||||
|
||||
start:
|
||||
; Zero-initialize uglobals (as in kernel at boot)
|
||||
mov ecx, (zeroend - zerostart + 3) / 4
|
||||
xor eax, eax
|
||||
mov edi, zerostart
|
||||
rep stosd
|
||||
; Initialize small heap (as in kernel at boot)
|
||||
call init_malloc
|
||||
; Run tests
|
||||
call run_test1
|
||||
call run_test2
|
||||
call run_test3
|
||||
; All is OK, return
|
||||
or eax, -1
|
||||
int 0x40
|
||||
|
||||
run_test1:
|
||||
; basic test
|
||||
mov eax, 1
|
||||
call malloc_with_test
|
||||
mov byte [eax], 0xDD
|
||||
mov esi, eax
|
||||
mov eax, 1
|
||||
call malloc_with_test
|
||||
cmp byte [esi], 0xDD
|
||||
jnz memory_destroyed
|
||||
mov byte [eax], 0xEE
|
||||
xchg eax, esi
|
||||
call free
|
||||
cmp byte [esi], 0xEE
|
||||
jnz memory_destroyed
|
||||
xchg eax, esi
|
||||
call free
|
||||
ret
|
||||
|
||||
run_test2:
|
||||
ret
|
||||
|
||||
run_test3:
|
||||
; 1024000 times run random operation.
|
||||
; Randomly select malloc(random size from 1 to 1023)
|
||||
; or free(random of previously allocated areas)
|
||||
mov edi, 0x12345678
|
||||
xor esi, esi ; 0 areas allocated
|
||||
mov ebx, 1024000
|
||||
.loop:
|
||||
imul edi, 1103515245
|
||||
add edi, 12345
|
||||
mov eax, edi
|
||||
shr eax, 16
|
||||
test ebx, 64
|
||||
jz .prefer_free
|
||||
.prefer_malloc:
|
||||
test eax, 3
|
||||
jz .free
|
||||
jmp @f
|
||||
.prefer_free:
|
||||
test eax, 3
|
||||
jnz .free
|
||||
@@:
|
||||
shr eax, 2
|
||||
and eax, 1023
|
||||
jz .loop
|
||||
push ebx
|
||||
push eax
|
||||
; mov ecx, [saved_state_num]
|
||||
; mov [saved_state+ecx*8], eax
|
||||
call malloc_with_test
|
||||
; mov ecx, [saved_state_num]
|
||||
; mov [saved_state+ecx*8+4], eax
|
||||
; inc [saved_state_num]
|
||||
pop ecx
|
||||
pop ebx
|
||||
inc esi
|
||||
push ecx eax
|
||||
push edi
|
||||
mov edi, eax
|
||||
mov eax, esi
|
||||
rep stosb
|
||||
pop edi
|
||||
jmp .common
|
||||
.free:
|
||||
test esi, esi
|
||||
jz .loop
|
||||
xor edx, edx
|
||||
div esi
|
||||
sub edx, esi
|
||||
neg edx
|
||||
dec edx
|
||||
mov eax, [esp+edx*8]
|
||||
; mov ecx, [saved_state_num]
|
||||
; mov [saved_state+ecx*8], -1
|
||||
; mov [saved_state+ecx*8+4], eax
|
||||
; inc [saved_state_num]
|
||||
mov ecx, [esp+edx*8+4]
|
||||
push edi eax
|
||||
mov edi, eax
|
||||
mov al, [edi]
|
||||
repz scasb
|
||||
jnz memory_destroyed
|
||||
pop eax edi
|
||||
push ebx edx
|
||||
call free
|
||||
pop edx ebx
|
||||
dec esi
|
||||
pop eax ecx
|
||||
push edi
|
||||
lea edi, [esp+4]
|
||||
@@:
|
||||
dec edx
|
||||
js @f
|
||||
xchg eax, [edi]
|
||||
xchg ecx, [edi+4]
|
||||
add edi, 8
|
||||
jmp @b
|
||||
@@:
|
||||
pop edi
|
||||
.common:
|
||||
dec ebx
|
||||
jnz .loop
|
||||
@@:
|
||||
dec esi
|
||||
js @f
|
||||
pop eax ecx
|
||||
call free
|
||||
jmp @b
|
||||
@@:
|
||||
ret
|
||||
|
||||
malloc_with_test:
|
||||
; calls malloc() and checks returned value
|
||||
call malloc
|
||||
test eax, eax
|
||||
jz generic_malloc_fail
|
||||
call check_mutex
|
||||
call check_range
|
||||
ret
|
||||
|
||||
; Stubs for kernel procedures used by heap code
|
||||
wait_mutex:
|
||||
inc dword [ebx]
|
||||
ret
|
||||
|
||||
kernel_alloc:
|
||||
cmp dword [esp+4], bufsize
|
||||
jnz error1
|
||||
mov eax, buffer
|
||||
ret 4
|
||||
|
||||
macro $Revision [args]
|
||||
{
|
||||
}
|
||||
|
||||
; Error handlers
|
||||
error1:
|
||||
mov eax, 1
|
||||
jmp error_with_code
|
||||
|
||||
generic_malloc_fail:
|
||||
mov eax, 2
|
||||
jmp error_with_code
|
||||
|
||||
check_mutex:
|
||||
cmp [mst.mutex], 0
|
||||
jnz @f
|
||||
ret
|
||||
@@:
|
||||
mov eax, 3
|
||||
jmp error_with_code
|
||||
|
||||
check_range:
|
||||
cmp eax, buffer
|
||||
jb @f
|
||||
cmp eax, buffer+bufsize
|
||||
jae @f
|
||||
ret
|
||||
@@:
|
||||
mov eax, 4
|
||||
jmp error_with_code
|
||||
|
||||
memory_destroyed:
|
||||
mov eax, 5
|
||||
jmp error_with_code
|
||||
|
||||
error_with_code:
|
||||
mov edx, saved_state_num
|
||||
; eax = error code
|
||||
; 1 signals error in testing code (wrong bufsize)
|
||||
; 2 = malloc() returned NULL
|
||||
; 3 = mutex not released
|
||||
; 4 = weird returned value from malloc()
|
||||
; 5 = memory destroyed by malloc() or free()
|
||||
int3 ; simplest way to report error
|
||||
jmp $-1 ; just in case
|
||||
|
||||
; Include main heap code
|
||||
include '../proc32.inc'
|
||||
include '../const.inc'
|
||||
include 'malloc.inc'
|
||||
|
||||
i_end:
|
||||
|
||||
align 4
|
||||
zerostart:
|
||||
mst MEM_STATE
|
||||
|
||||
align 16
|
||||
bufsize = 0x40000 ; change if malloc.inc changes
|
||||
buffer rb bufsize
|
||||
zeroend:
|
||||
|
||||
saved_state_num dd ?
|
||||
saved_state rd 0x10000
|
||||
|
||||
align 4
|
||||
rb 0x10000 ; for stack
|
||||
mem:
|
935
kernel/branches/kolibri-cfg/core/v86.inc
Normal file
935
kernel/branches/kolibri-cfg/core/v86.inc
Normal file
@ -0,0 +1,935 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2007-2008. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
; Virtual-8086 mode manager
|
||||
; diamond, 2007, 2008
|
||||
|
||||
DEBUG_SHOW_IO = 0
|
||||
|
||||
struc V86_machine
|
||||
{
|
||||
; page directory
|
||||
.pagedir dd ?
|
||||
; translation table: V86 address -> flat linear address
|
||||
.pages dd ?
|
||||
; mutex to protect all data from writing by multiple threads at one time
|
||||
.mutex dd ?
|
||||
; i/o permission map
|
||||
.iopm dd ?
|
||||
.size = $
|
||||
}
|
||||
virtual at 0
|
||||
V86_machine V86_machine
|
||||
end virtual
|
||||
|
||||
; Create V86 machine
|
||||
; in: nothing
|
||||
; out: eax = handle (pointer to struc V86_machine)
|
||||
; eax = NULL => failure
|
||||
; destroys: ebx, ecx, edx (due to malloc)
|
||||
v86_create:
|
||||
; allocate V86_machine structure
|
||||
mov eax, V86_machine.size
|
||||
call malloc
|
||||
test eax, eax
|
||||
jz .fail
|
||||
; initialize mutex
|
||||
and dword [eax+V86_machine.mutex], 0
|
||||
; allocate tables
|
||||
mov ebx, eax
|
||||
; We allocate 4 pages.
|
||||
; First is main page directory for V86 mode.
|
||||
; Second page:
|
||||
; first half (0x800 bytes) is page table for addresses 0 - 0x100000,
|
||||
; second half is for V86-to-linear translation.
|
||||
; Third and fourth are for I/O permission map.
|
||||
push 8000h ; blocks less than 8 pages are discontinuous
|
||||
call kernel_alloc
|
||||
test eax, eax
|
||||
jz .fail2
|
||||
mov [ebx+V86_machine.pagedir], eax
|
||||
push edi eax
|
||||
mov edi, eax
|
||||
add eax, 1800h
|
||||
mov [ebx+V86_machine.pages], eax
|
||||
; initialize tables
|
||||
mov ecx, 2000h/4
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
mov [ebx+V86_machine.iopm], edi
|
||||
dec eax
|
||||
mov ecx, 2000h/4
|
||||
rep stosd
|
||||
pop eax
|
||||
; page directory: first entry is page table...
|
||||
mov edi, eax
|
||||
add eax, 1000h
|
||||
push eax
|
||||
call get_pg_addr
|
||||
or al, PG_UW
|
||||
stosd
|
||||
; ...and also copy system page tables
|
||||
; thx to Serge, system is located at high addresses
|
||||
add edi, (OS_BASE shr 20) - 4
|
||||
push esi
|
||||
mov esi, (OS_BASE shr 20) + sys_pgdir
|
||||
mov ecx, 0x80000000 shr 22
|
||||
rep movsd
|
||||
|
||||
mov eax, [ebx+V86_machine.pagedir] ;root dir also is
|
||||
call get_pg_addr ;used as page table
|
||||
or al, PG_SW
|
||||
mov [edi-4096+(page_tabs shr 20)], eax
|
||||
|
||||
pop esi
|
||||
; now V86 specific: initialize known addresses in first Mb
|
||||
pop eax
|
||||
; first page - BIOS data (shared between all machines!)
|
||||
; physical address = 0
|
||||
; linear address = OS_BASE
|
||||
mov dword [eax], 111b
|
||||
mov dword [eax+800h], OS_BASE
|
||||
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
|
||||
; physical address = 0x9C000
|
||||
; linear address = 0x8009C000
|
||||
; (I have seen one computer with EBDA segment = 0x9D80,
|
||||
; all other computers use less memory)
|
||||
mov ecx, 4
|
||||
mov edx, 0x9C000
|
||||
push eax
|
||||
lea edi, [eax+0x9C*4]
|
||||
@@:
|
||||
lea eax, [edx + OS_BASE]
|
||||
mov [edi+800h], eax
|
||||
lea eax, [edx + 111b]
|
||||
stosd
|
||||
add edx, 0x1000
|
||||
loop @b
|
||||
pop eax
|
||||
pop edi
|
||||
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
|
||||
; physical address = 0xC0000
|
||||
; linear address = 0x800C0000
|
||||
mov ecx, 0xC0
|
||||
@@:
|
||||
mov edx, ecx
|
||||
shl edx, 12
|
||||
push edx
|
||||
or edx, 111b
|
||||
mov [eax+ecx*4], edx
|
||||
pop edx
|
||||
add edx, OS_BASE
|
||||
mov [eax+ecx*4+0x800], edx
|
||||
inc cl
|
||||
jnz @b
|
||||
mov eax, ebx
|
||||
ret
|
||||
.fail2:
|
||||
mov eax, ebx
|
||||
call free
|
||||
.fail:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
; Destroy V86 machine
|
||||
; in: eax = handle
|
||||
; out: nothing
|
||||
; destroys: eax, ebx, ecx, edx (due to free)
|
||||
v86_destroy:
|
||||
push eax
|
||||
stdcall kernel_free, [eax+V86_machine.pagedir]
|
||||
pop eax
|
||||
jmp free
|
||||
|
||||
; Translate V86-address to linear address
|
||||
; in: eax=V86 address
|
||||
; esi=handle
|
||||
; out: eax=linear address
|
||||
; destroys: nothing
|
||||
v86_get_lin_addr:
|
||||
push ecx edx
|
||||
mov ecx, eax
|
||||
mov edx, [esi+V86_machine.pages]
|
||||
shr ecx, 12
|
||||
and eax, 0xFFF
|
||||
add eax, [edx+ecx*4] ; atomic operation, no mutex needed
|
||||
pop edx ecx
|
||||
ret
|
||||
|
||||
; Sets linear address for V86-page
|
||||
; in: eax=linear address (must be page-aligned)
|
||||
; ecx=V86 page (NOT address!)
|
||||
; esi=handle
|
||||
; out: nothing
|
||||
; destroys: nothing
|
||||
v86_set_page:
|
||||
push eax ebx
|
||||
mov ebx, [esi+V86_machine.pagedir]
|
||||
mov [ebx+ecx*4+0x1800], eax
|
||||
call get_pg_addr
|
||||
or al, 111b
|
||||
mov [ebx+ecx*4+0x1000], eax
|
||||
pop ebx eax
|
||||
ret
|
||||
|
||||
; Allocate memory in V86 machine
|
||||
; in: eax=size (in bytes)
|
||||
; esi=handle
|
||||
; out: eax=V86 address, para-aligned (0x10 multiple)
|
||||
; destroys: nothing
|
||||
; ¥¤®¯¨á !!!
|
||||
;v86_alloc:
|
||||
; push ebx ecx edx edi
|
||||
; lea ebx, [esi+V86_machine.mutex]
|
||||
; call wait_mutex
|
||||
; add eax, 0x1F
|
||||
; shr eax, 4
|
||||
; mov ebx, 0x1000 ; start with address 0x1000 (second page)
|
||||
; mov edi, [esi+V86_machine.tables]
|
||||
;.l:
|
||||
; mov ecx, ebx
|
||||
; shr ecx, 12
|
||||
; mov edx, [edi+0x1000+ecx*4] ; get linear address
|
||||
; test edx, edx ; page allocated?
|
||||
; jz .unalloc
|
||||
; mov ecx, ebx
|
||||
; and ecx, 0xFFF
|
||||
; add edx, ecx
|
||||
; cmp dword [edx], 0 ; free block?
|
||||
; jnz .n
|
||||
; cmp dword [edx+4],
|
||||
; and [esi+V86_machine.mutex], 0
|
||||
; pop edi edx ecx ebx
|
||||
; ret
|
||||
|
||||
uglobal
|
||||
sys_v86_machine dd ?
|
||||
endg
|
||||
|
||||
; Called from kernel.asm at first stages of loading
|
||||
; Initialize system V86 machine (used to simulate BIOS int 13h)
|
||||
init_sys_v86:
|
||||
call v86_create
|
||||
mov [sys_v86_machine], eax
|
||||
test eax, eax
|
||||
jz .ret
|
||||
mov byte [OS_BASE + 0x500], 0xCD
|
||||
mov byte [OS_BASE + 0x501], 0x13
|
||||
mov byte [OS_BASE + 0x502], 0xF4
|
||||
mov byte [OS_BASE + 0x503], 0xCD
|
||||
mov byte [OS_BASE + 0x504], 0x10
|
||||
mov byte [OS_BASE + 0x505], 0xF4
|
||||
mov esi, eax
|
||||
mov ebx, [eax+V86_machine.pagedir]
|
||||
; one page for stack, two pages for results (0x2000 bytes = 16 sectors)
|
||||
mov dword [ebx+0x99*4+0x1000], 0x99000 or 111b
|
||||
mov dword [ebx+0x99*4+0x1800], OS_BASE + 0x99000
|
||||
mov dword [ebx+0x9A*4+0x1000], 0x9A000 or 111b
|
||||
mov dword [ebx+0x9A*4+0x1800], OS_BASE + 0x9A000
|
||||
mov dword [ebx+0x9B*4+0x1000], 0x9B000 or 111b
|
||||
mov dword [ebx+0x9B*4+0x1800], OS_BASE + 0x9B000
|
||||
if ~DEBUG_SHOW_IO
|
||||
; allow access to all ports
|
||||
mov ecx, [esi+V86_machine.iopm]
|
||||
xor eax, eax
|
||||
mov edi, ecx
|
||||
mov ecx, 10000h/8/4
|
||||
rep stosd
|
||||
end if
|
||||
.ret:
|
||||
ret
|
||||
|
||||
struc v86_regs
|
||||
{
|
||||
; don't change the order, it is important
|
||||
.edi dd ?
|
||||
.esi dd ?
|
||||
.ebp dd ?
|
||||
dd ? ; ignored
|
||||
.ebx dd ?
|
||||
.edx dd ?
|
||||
.ecx dd ?
|
||||
.eax dd ?
|
||||
.eip dd ?
|
||||
.cs dd ?
|
||||
.eflags dd ? ; VM flag must be set!
|
||||
.esp dd ?
|
||||
.ss dd ?
|
||||
.es dd ?
|
||||
.ds dd ?
|
||||
.fs dd ?
|
||||
.gs dd ?
|
||||
.size = $
|
||||
}
|
||||
virtual at 0
|
||||
v86_regs v86_regs
|
||||
end virtual
|
||||
|
||||
; Run V86 machine
|
||||
; in: ebx -> registers for V86 (two structures: in and out)
|
||||
; esi = handle
|
||||
; ecx = expected end address (CS:IP)
|
||||
; edx = IRQ to hook or -1 if not required
|
||||
; out: structure pointed to by ebx is filled with new values
|
||||
; eax = 1 - exception has occured, cl contains code
|
||||
; eax = 2 - access to disabled i/o port, ecx contains port address
|
||||
; eax = 3 - IRQ is already hooked by another VM
|
||||
; destroys: nothing
|
||||
v86_start:
|
||||
pushad
|
||||
|
||||
cli
|
||||
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
add ecx, SLOT_BASE
|
||||
|
||||
mov eax, [esi+V86_machine.iopm]
|
||||
call get_pg_addr
|
||||
inc eax
|
||||
push dword [ecx+APPDATA.io_map]
|
||||
push dword [ecx+APPDATA.io_map+4]
|
||||
mov dword [ecx+APPDATA.io_map], eax
|
||||
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax
|
||||
add eax, 0x1000
|
||||
mov dword [ecx+APPDATA.io_map+4], eax
|
||||
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax
|
||||
|
||||
push [ecx+APPDATA.dir_table]
|
||||
push [ecx+APPDATA.saved_esp0]
|
||||
mov [ecx+APPDATA.saved_esp0], esp
|
||||
mov [tss._esp0], esp
|
||||
|
||||
mov eax, [esi+V86_machine.pagedir]
|
||||
call get_pg_addr
|
||||
mov [ecx+APPDATA.dir_table], eax
|
||||
mov cr3, eax
|
||||
|
||||
; mov [irq_tab+5*4], my05
|
||||
|
||||
; We do not enable interrupts, because V86 IRQ redirector assumes that
|
||||
; machine is running
|
||||
; They will be enabled by IRET.
|
||||
; sti
|
||||
|
||||
mov eax, esi
|
||||
sub esp, v86_regs.size
|
||||
mov esi, ebx
|
||||
mov edi, esp
|
||||
mov ecx, v86_regs.size/4
|
||||
rep movsd
|
||||
|
||||
cmp edx, -1
|
||||
jz .noirqhook
|
||||
uglobal
|
||||
v86_irqhooks rd 16*2
|
||||
endg
|
||||
cmp [v86_irqhooks+edx*8], 0
|
||||
jz @f
|
||||
cmp [v86_irqhooks+edx*8], eax
|
||||
jz @f
|
||||
mov esi, v86_irqerr
|
||||
call sys_msg_board_str
|
||||
inc [v86_irqhooks+edx*8+4]
|
||||
mov eax, 3
|
||||
jmp v86_exc_c.exit
|
||||
@@:
|
||||
mov [v86_irqhooks+edx*8], eax
|
||||
inc [v86_irqhooks+edx*8+4]
|
||||
.noirqhook:
|
||||
|
||||
popad
|
||||
iretd
|
||||
|
||||
; It is only possible to leave virtual-8086 mode by faulting to
|
||||
; a protected-mode interrupt handler (typically the general-protection
|
||||
; exception handler, which in turn calls the virtual 8086-mode monitor).
|
||||
|
||||
iglobal
|
||||
v86_exc_str1 db 'V86 : unexpected exception ',0
|
||||
v86_exc_str2 db ' at ',0
|
||||
v86_exc_str3 db ':',0
|
||||
v86_exc_str4 db 13,10,'V86 : faulted code:',0
|
||||
v86_exc_str5 db ' (unavailable)',0
|
||||
v86_newline db 13,10,0
|
||||
v86_io_str1 db 'V86 : access to disabled i/o port ',0
|
||||
v86_io_byte db ' (byte)',13,10,0
|
||||
v86_io_word db ' (word)',13,10,0
|
||||
v86_io_dword db ' (dword)',13,10,0
|
||||
v86_irqerr db 'V86 : IRQ already hooked',13,10,0
|
||||
endg
|
||||
|
||||
v86_exc_c:
|
||||
; Did we all that we have wanted to do?
|
||||
cmp bl,1
|
||||
jne @f
|
||||
xor eax, eax
|
||||
mov dr6, eax
|
||||
@@: mov eax, [esp+v86_regs.size+10h+18h]
|
||||
cmp word [esp+v86_regs.eip], ax
|
||||
jnz @f
|
||||
shr eax, 16
|
||||
cmp word [esp+v86_regs.cs], ax
|
||||
jz .done
|
||||
@@:
|
||||
; Various system events, which must be handled, result in #GP
|
||||
cmp bl, 13
|
||||
jnz .nogp
|
||||
; If faulted EIP exceeds 0xFFFF, we have #GP and it is an error
|
||||
cmp word [esp+v86_regs.eip+2], 0
|
||||
jnz .nogp
|
||||
; Otherwise we can safely access byte at CS:IP
|
||||
; (because it is #GP, not #PF handler)
|
||||
; …᫨ ¡ë ¬ë ¬®£«¨ áå«®¯®â âì ¨áª«î票¥ ⮫쪮 ¨§-§ çâ¥¨ï ¡ ©â®¢ ª®¤ ,
|
||||
; ¬ë ¡ë ¥£® 㦥 áå«®¯®â «¨ ¨ íâ® ¡ë«® ¡ë ¥ #GP
|
||||
movzx esi, word [esp+v86_regs.cs]
|
||||
shl esi, 4
|
||||
add esi, [esp+v86_regs.eip]
|
||||
lodsb
|
||||
cmp al, 0xCD ; int xx command = CD xx
|
||||
jz .handle_int
|
||||
cmp al, 0xCF
|
||||
jz .handle_iret
|
||||
cmp al, 0xF3
|
||||
jz .handle_rep
|
||||
cmp al, 0xEC
|
||||
jz .handle_in
|
||||
cmp al, 0xED
|
||||
jz .handle_in_word
|
||||
cmp al, 0xEE
|
||||
jz .handle_out
|
||||
cmp al, 0xEF
|
||||
jz .handle_out_word
|
||||
cmp al, 0xE4
|
||||
jz .handle_in_imm
|
||||
cmp al, 0xE6
|
||||
jz .handle_out_imm
|
||||
cmp al, 0x9C
|
||||
jz .handle_pushf
|
||||
cmp al, 0x9D
|
||||
jz .handle_popf
|
||||
cmp al, 0xFA
|
||||
jz .handle_cli
|
||||
cmp al, 0xFB
|
||||
jz .handle_sti
|
||||
cmp al, 0x66
|
||||
jz .handle_66
|
||||
jmp .nogp
|
||||
.handle_int:
|
||||
cmp word [esp+v86_regs.eip], 0xFFFF
|
||||
jae .nogp
|
||||
xor eax, eax
|
||||
lodsb
|
||||
; call sys_msg_board_byte
|
||||
; simulate INT command
|
||||
; N.B. It is possible that some checks need to be corrected,
|
||||
; but at least in case of normal execution the code works.
|
||||
.simulate_int:
|
||||
cmp word [esp+v86_regs.esp], 6
|
||||
jae @f
|
||||
mov bl, 12 ; #SS exception
|
||||
jmp .nogp
|
||||
@@:
|
||||
movzx edx, word [esp+v86_regs.ss]
|
||||
shl edx, 4
|
||||
push eax
|
||||
movzx eax, word [esp+4+v86_regs.esp]
|
||||
sub eax, 6
|
||||
add edx, eax
|
||||
mov eax, edx
|
||||
mov esi, [esp+4+v86_regs.size+10h+4]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14 ; #PF exception
|
||||
jmp .nogp
|
||||
@@:
|
||||
lea eax, [edx+5]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14 ; #PF exception
|
||||
jmp .nogp
|
||||
@@:
|
||||
sub word [esp+4+v86_regs.esp], 6
|
||||
mov eax, [esp+4+v86_regs.eip]
|
||||
cmp byte [esp+1], 0
|
||||
jnz @f
|
||||
inc eax
|
||||
inc eax
|
||||
@@:
|
||||
mov word [edx], ax
|
||||
mov eax, [esp+4+v86_regs.cs]
|
||||
mov word [edx+2], ax
|
||||
mov eax, [esp+4+v86_regs.eflags]
|
||||
mov word [edx+4], ax
|
||||
pop eax
|
||||
mov ah, 0
|
||||
mov cx, [eax*4]
|
||||
mov word [esp+v86_regs.eip], cx
|
||||
mov cx, [eax*4+2]
|
||||
mov word [esp+v86_regs.cs], cx
|
||||
; note that interrupts will be disabled globally at IRET
|
||||
and byte [esp+v86_regs.eflags+1], not 3 ; clear IF and TF flags
|
||||
; continue V86 execution
|
||||
popad
|
||||
iretd
|
||||
.handle_iret:
|
||||
cmp word [esp+v86_regs.esp], 0x10000 - 6
|
||||
jbe @f
|
||||
mov bl, 12
|
||||
jmp .nogp
|
||||
@@:
|
||||
movzx edx, word [esp+v86_regs.ss]
|
||||
shl edx, 4
|
||||
movzx eax, word [esp+v86_regs.esp]
|
||||
add edx, eax
|
||||
mov eax, edx
|
||||
mov esi, [esp+v86_regs.size+10h+4]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14
|
||||
jmp .nogp
|
||||
@@:
|
||||
lea eax, [edx+5]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14
|
||||
jmp .nogp
|
||||
@@:
|
||||
mov ax, [edx]
|
||||
mov word [esp+v86_regs.eip], ax
|
||||
mov ax, [edx+2]
|
||||
mov word [esp+v86_regs.cs], ax
|
||||
mov ax, [edx+4]
|
||||
mov word [esp+v86_regs.eflags], ax
|
||||
add word [esp+v86_regs.esp], 6
|
||||
popad
|
||||
iretd
|
||||
.handle_pushf:
|
||||
cmp word [esp+v86_regs.esp], 1
|
||||
jnz @f
|
||||
mov bl, 12
|
||||
jmp .nogp
|
||||
@@:
|
||||
movzx edx, word [esp+v86_regs.ss]
|
||||
shl edx, 4
|
||||
mov eax, [esp+v86_regs.esp]
|
||||
sub eax, 2
|
||||
movzx eax, ax
|
||||
add edx, eax
|
||||
mov eax, edx
|
||||
mov esi, [esp+v86_regs.size+10h+4]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14 ; #PF exception
|
||||
jmp .nogp
|
||||
@@:
|
||||
lea eax, [edx+1]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14
|
||||
jmp .nogp
|
||||
@@:
|
||||
sub word [esp+v86_regs.esp], 2
|
||||
mov eax, [esp+v86_regs.eflags]
|
||||
mov [edx], ax
|
||||
inc word [esp+v86_regs.eip]
|
||||
popad
|
||||
iretd
|
||||
.handle_pushfd:
|
||||
cmp word [esp+v86_regs.esp], 4
|
||||
jae @f
|
||||
mov bl, 12 ; #SS exception
|
||||
jmp .nogp
|
||||
@@:
|
||||
movzx edx, word [esp+v86_regs.ss]
|
||||
shl edx, 4
|
||||
movzx eax, word [esp+v86_regs.esp]
|
||||
sub eax, 4
|
||||
add edx, eax
|
||||
mov eax, edx
|
||||
mov esi, [esp+v86_regs.size+10h+4]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14 ; #PF exception
|
||||
jmp .nogp
|
||||
@@:
|
||||
lea eax, [edx+3]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14 ; #PF exception
|
||||
jmp .nogp
|
||||
@@:
|
||||
sub word [esp+v86_regs.esp], 4
|
||||
movzx eax, word [esp+v86_regs.eflags]
|
||||
mov [edx], eax
|
||||
add word [esp+v86_regs.eip], 2
|
||||
popad
|
||||
iretd
|
||||
.handle_popf:
|
||||
cmp word [esp+v86_regs.esp], 0xFFFF
|
||||
jnz @f
|
||||
mov bl, 12
|
||||
jmp .nogp
|
||||
@@:
|
||||
movzx edx, word [esp+v86_regs.ss]
|
||||
shl edx, 4
|
||||
movzx eax, word [esp+v86_regs.esp]
|
||||
add edx, eax
|
||||
mov eax, edx
|
||||
mov esi, [esp+v86_regs.size+10h+4]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14 ; #PF exception
|
||||
jmp .nogp
|
||||
@@:
|
||||
lea eax, [edx+1]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14
|
||||
jmp .nogp
|
||||
@@:
|
||||
mov ax, [edx]
|
||||
mov word [esp+v86_regs.eflags], ax
|
||||
add word [esp+v86_regs.esp], 2
|
||||
inc word [esp+v86_regs.eip]
|
||||
popad
|
||||
iretd
|
||||
.handle_popfd:
|
||||
cmp word [esp+v86_regs.esp], 0x10000 - 4
|
||||
jbe @f
|
||||
mov bl, 12
|
||||
jmp .nogp
|
||||
@@:
|
||||
movzx edx, word [esp+v86_regs.ss]
|
||||
shl edx, 4
|
||||
movzx eax, word [esp+v86_regs.esp]
|
||||
add edx, eax
|
||||
mov eax, edx
|
||||
mov esi, [esp+v86_regs.size+10h+4]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14
|
||||
jmp .nogp
|
||||
@@:
|
||||
lea eax, [edx+3]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jae @f
|
||||
mov bl, 14
|
||||
jmp .nogp
|
||||
@@:
|
||||
mov eax, [edx]
|
||||
mov word [esp+v86_regs.eflags], ax
|
||||
add word [esp+v86_regs.esp], 4
|
||||
add word [esp+v86_regs.eip], 2
|
||||
popad
|
||||
iretd
|
||||
.handle_cli:
|
||||
and byte [esp+v86_regs.eflags+1], not 2
|
||||
inc word [esp+v86_regs.eip]
|
||||
popad
|
||||
iretd
|
||||
.handle_sti:
|
||||
or byte [esp+v86_regs.eflags+1], 2
|
||||
inc word [esp+v86_regs.eip]
|
||||
popad
|
||||
iretd
|
||||
.handle_rep:
|
||||
cmp word [esp+v86_regs.eip], 0xFFFF
|
||||
jae .nogp
|
||||
lodsb
|
||||
cmp al, 6Eh
|
||||
jz .handle_rep_outsb
|
||||
jmp .nogp
|
||||
.handle_rep_outsb:
|
||||
.handle_in:
|
||||
.handle_out:
|
||||
.invalid_io_byte:
|
||||
movzx ebx, word [esp+v86_regs.edx]
|
||||
mov ecx, 1
|
||||
jmp .invalid_io
|
||||
.handle_in_imm:
|
||||
.handle_out_imm:
|
||||
cmp word [esp+v86_regs.eip], 0xFFFF
|
||||
jae .nogp
|
||||
lodsb
|
||||
movzx ebx, al
|
||||
mov ecx, 1
|
||||
jmp .invalid_io
|
||||
.handle_66:
|
||||
cmp word [esp+v86_regs.eip], 0xFFFF
|
||||
jae .nogp
|
||||
lodsb
|
||||
cmp al, 0x9C
|
||||
jz .handle_pushfd
|
||||
cmp al, 0x9D
|
||||
jz .handle_popfd
|
||||
cmp al, 0xEF
|
||||
jz .handle_out_dword
|
||||
cmp al, 0xED
|
||||
jz .handle_in_dword
|
||||
jmp .nogp
|
||||
.handle_in_word:
|
||||
.handle_out_word:
|
||||
movzx ebx, word [esp+v86_regs.edx]
|
||||
mov ecx, 2
|
||||
jmp .invalid_io
|
||||
.handle_in_dword:
|
||||
.handle_out_dword:
|
||||
.invalid_io_dword:
|
||||
movzx ebx, word [esp+v86_regs.edx]
|
||||
mov ecx, 4
|
||||
.invalid_io:
|
||||
mov esi, v86_io_str1
|
||||
call sys_msg_board_str
|
||||
mov eax, ebx
|
||||
call sys_msg_board_dword
|
||||
mov esi, v86_io_byte
|
||||
cmp ecx, 1
|
||||
jz @f
|
||||
mov esi, v86_io_word
|
||||
cmp ecx, 2
|
||||
jz @f
|
||||
mov esi, v86_io_dword
|
||||
@@:
|
||||
call sys_msg_board_str
|
||||
if DEBUG_SHOW_IO
|
||||
mov edx, ebx
|
||||
mov ebx, 200
|
||||
call delay_hs
|
||||
mov esi, [esp+v86_regs.size+10h+4]
|
||||
mov eax, [esi+V86_machine.iopm]
|
||||
@@:
|
||||
btr [eax], edx
|
||||
inc edx
|
||||
loop @b
|
||||
popad
|
||||
iretd
|
||||
else
|
||||
mov eax, 2
|
||||
jmp .exit
|
||||
end if
|
||||
.nogp:
|
||||
|
||||
mov esi, v86_exc_str1
|
||||
call sys_msg_board_str
|
||||
mov al, bl
|
||||
call sys_msg_board_byte
|
||||
mov esi, v86_exc_str2
|
||||
call sys_msg_board_str
|
||||
mov ax, [esp+32+4]
|
||||
call sys_msg_board_word
|
||||
mov esi, v86_exc_str3
|
||||
call sys_msg_board_str
|
||||
mov ax, [esp+32]
|
||||
call sys_msg_board_word
|
||||
mov esi, v86_exc_str4
|
||||
call sys_msg_board_str
|
||||
mov ecx, 8
|
||||
movzx edx, word [esp+32+4]
|
||||
shl edx, 4
|
||||
add edx, [esp+32]
|
||||
@@:
|
||||
mov esi, [esp+v86_regs.size+10h+4]
|
||||
mov eax, edx
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jb .nopage
|
||||
mov esi, v86_exc_str3-2
|
||||
call sys_msg_board_str
|
||||
mov al, [edx]
|
||||
call sys_msg_board_byte
|
||||
inc edx
|
||||
loop @b
|
||||
jmp @f
|
||||
.nopage:
|
||||
mov esi, v86_exc_str5
|
||||
call sys_msg_board_str
|
||||
@@:
|
||||
mov esi, v86_newline
|
||||
call sys_msg_board_str
|
||||
mov eax, 1
|
||||
jmp .exit
|
||||
|
||||
.done:
|
||||
xor eax, eax
|
||||
|
||||
.exit:
|
||||
mov [esp+v86_regs.size+10h+1Ch], eax
|
||||
mov [esp+v86_regs.size+10h+18h], ebx
|
||||
|
||||
mov edx, [esp+v86_regs.size+10h+14h]
|
||||
cmp edx, -1
|
||||
jz @f
|
||||
dec [v86_irqhooks+edx*8+4]
|
||||
jnz @f
|
||||
and [v86_irqhooks+edx*8], 0
|
||||
@@:
|
||||
|
||||
mov esi, esp
|
||||
mov edi, [esi+v86_regs.size+10h+10h]
|
||||
add edi, v86_regs.size
|
||||
mov ecx, v86_regs.size/4
|
||||
rep movsd
|
||||
mov esp, esi
|
||||
|
||||
cli
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
pop eax
|
||||
mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax
|
||||
mov [tss._esp0], eax
|
||||
pop eax
|
||||
mov [SLOT_BASE+ecx+APPDATA.dir_table], eax
|
||||
pop ebx
|
||||
mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx
|
||||
mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx
|
||||
pop ebx
|
||||
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx
|
||||
mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx
|
||||
mov cr3, eax
|
||||
; mov [irq_tab+5*4], 0
|
||||
sti
|
||||
|
||||
popad
|
||||
ret
|
||||
|
||||
;my05:
|
||||
; mov dx, 30C2h
|
||||
; mov cx, 4
|
||||
;.0:
|
||||
; in al, dx
|
||||
; cmp al, 0FFh
|
||||
; jz @f
|
||||
; test al, 4
|
||||
; jnz .1
|
||||
;@@:
|
||||
; add dx, 8
|
||||
; in al, dx
|
||||
; cmp al, 0FFh
|
||||
; jz @f
|
||||
; test al, 4
|
||||
; jnz .1
|
||||
;@@:
|
||||
; loop .0
|
||||
; ret
|
||||
;.1:
|
||||
; or al, 84h
|
||||
; out dx, al
|
||||
;.2:
|
||||
; mov dx, 30F7h
|
||||
; in al, dx
|
||||
; mov byte [BOOT_VAR + 48Eh], 0FFh
|
||||
; ret
|
||||
|
||||
v86_irq:
|
||||
; push irq/pushad/jmp v86_irq
|
||||
; eax = irq
|
||||
lea esi, [esp+1Ch]
|
||||
lea edi, [esi+4]
|
||||
mov ecx, 8
|
||||
std
|
||||
rep movsd
|
||||
cld
|
||||
mov edi, eax
|
||||
pop eax
|
||||
v86_irq2:
|
||||
mov esi, [v86_irqhooks+edi*8] ; get VM handle
|
||||
mov eax, [esi+V86_machine.pagedir]
|
||||
call get_pg_addr
|
||||
mov ecx, [CURRENT_TASK]
|
||||
shl ecx, 8
|
||||
cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax
|
||||
jnz .notcurrent
|
||||
lea eax, [edi+8]
|
||||
cmp al, 10h
|
||||
mov ah, 1
|
||||
jb @f
|
||||
add al, 60h
|
||||
@@:
|
||||
jmp v86_exc_c.simulate_int
|
||||
.notcurrent:
|
||||
mov ebx, SLOT_BASE + 0x100
|
||||
mov ecx, [TASK_COUNT]
|
||||
.scan:
|
||||
cmp [ebx+APPDATA.dir_table], eax
|
||||
jnz .cont
|
||||
push ecx
|
||||
mov ecx, [ebx+APPDATA.saved_esp0]
|
||||
cmp word [ecx-v86_regs.size+v86_regs.esp], 6
|
||||
jb .cont2
|
||||
movzx edx, word [ecx-v86_regs.size+v86_regs.ss]
|
||||
shl edx, 4
|
||||
push eax
|
||||
movzx eax, word [ecx-v86_regs.size+v86_regs.esp]
|
||||
sub eax, 6
|
||||
add edx, eax
|
||||
mov eax, edx
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jb .cont3
|
||||
lea eax, [edx+5]
|
||||
call v86_get_lin_addr
|
||||
cmp eax, 0x1000
|
||||
jb .cont3
|
||||
pop eax
|
||||
pop ecx
|
||||
jmp .found
|
||||
.cont3:
|
||||
pop eax
|
||||
.cont2:
|
||||
pop ecx
|
||||
.cont:
|
||||
loop .scan
|
||||
mov al, 20h
|
||||
out 20h, al
|
||||
cmp edi, 8
|
||||
jb @f
|
||||
out 0A0h, al
|
||||
@@:
|
||||
popad
|
||||
iretd
|
||||
.found:
|
||||
mov cr3, eax
|
||||
sub word [esi-v86_regs.size+v86_regs.esp], 6
|
||||
mov ecx, [esi-v86_regs.size+v86_regs.eip]
|
||||
mov word [edx], cx
|
||||
mov ecx, [esi-v86_regs.size+v86_regs.cs]
|
||||
mov word [edx+2], cx
|
||||
mov ecx, [esi-v86_regs.size+v86_regs.eflags]
|
||||
mov word [edx+4], cx
|
||||
lea eax, [edi+8]
|
||||
cmp al, 10h
|
||||
jb @f
|
||||
add al, 60h
|
||||
@@:
|
||||
mov cx, [eax*4]
|
||||
mov word [esi-v86_regs.size+v86_regs.eip], cx
|
||||
mov cx, [eax*4+2]
|
||||
mov word [esi-v86_regs.size+v86_regs.cs], cx
|
||||
and byte [esi-v86_regs.size+v86_regs.eflags+1], not 3
|
||||
call update_counters
|
||||
lea edi, [ebx + 0x100000000 - SLOT_BASE]
|
||||
shr edi, 3
|
||||
add edi, TASK_DATA
|
||||
call find_next_task.found
|
||||
call do_change_task
|
||||
popad
|
||||
iretd
|
81
kernel/branches/kolibri-cfg/data16.inc
Normal file
81
kernel/branches/kolibri-cfg/data16.inc
Normal file
@ -0,0 +1,81 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
flm db 0
|
||||
preboot_lfb db 0
|
||||
preboot_bootlog db 0
|
||||
boot_drive db 0
|
||||
bx_from_load: dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007]
|
||||
; a,b,c,d - âèí÷åñòåðû, r - ðàì äèñê
|
||||
; # äèñêà... ñèìâîë, à íå áàéò. '1', à íå 1
|
||||
|
||||
align 4
|
||||
old_ints_h:
|
||||
dw 0x400
|
||||
dd 0
|
||||
dw 0
|
||||
|
||||
; table for move to extended memory (int 15h, ah=87h)
|
||||
align 8
|
||||
movedesc:
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
|
||||
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
|
||||
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
|
||||
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
|
||||
fwmovedesc:
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
|
||||
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
|
||||
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
|
||||
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
|
||||
|
||||
; look in PrimaryLoader.txt for the description
|
||||
bootdevice dw 0 ; ax from primary loader
|
||||
bootfs dw 0 ; bx from primary loader
|
||||
bootcallback dd 0 ; ds:si from primary loader
|
||||
; data for configuration file loading, look in PrimaryLoader.txt
|
||||
config_file_struct:
|
||||
dw 0, 4000h ; load to 4000:0000
|
||||
dw 16 ; read no more than 16*4K = 64K
|
||||
db 'config.ini',0
|
||||
; data for configuration file parsing
|
||||
macro config_variable string,parser
|
||||
{
|
||||
local len
|
||||
len dw 0
|
||||
db string
|
||||
store word $ - len - 2 at len
|
||||
dw parser
|
||||
}
|
||||
config_file_variables:
|
||||
config_variable 'timeout', parse_timeout
|
||||
config_variable 'resolution', parse_resolution
|
||||
config_variable 'vbemode', parse_vbemode
|
||||
config_variable 'vrr', parse_vrr
|
||||
config_variable 'biosdisks', parse_biosdisks
|
||||
config_variable 'imgfrom', parse_imgfrom
|
||||
dw 0
|
||||
; data for image file loading, look in PrimaryLoader.txt
|
||||
image_file_struct:
|
||||
dw 0, 4000h ; load to 4000:0000
|
||||
dw 16 ; read no more than 16*4K = 64K
|
||||
db 'kolibri.img',0
|
467
kernel/branches/kolibri-cfg/data32.inc
Normal file
467
kernel/branches/kolibri-cfg/data32.inc
Normal file
@ -0,0 +1,467 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
keymap:
|
||||
|
||||
db '6',27
|
||||
db '1234567890-=',8,9
|
||||
db 'qwertyuiop[]',13
|
||||
db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 '
|
||||
db '@234567890123',180,178,184,'6',176,'7'
|
||||
db 179,'8',181,177,183,185,182
|
||||
db 'AB<D',255,'FGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
keymap_shift:
|
||||
db '6',27
|
||||
db '!@#$%^&*()_+',8,9
|
||||
db 'QWERTYUIOP{}',13
|
||||
db '~ASDFGHJKL:"~',0,'|ZXCVBNM<>?',0,'45 '
|
||||
db '@234567890123',180,178,184,'6',176,'7'
|
||||
db 179,'8',181,177,183,185,182
|
||||
db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
|
||||
keymap_alt:
|
||||
db ' ',27
|
||||
db ' @ $ {[]}\ ',8,9
|
||||
db ' ',13
|
||||
db ' ',0,' ',0,'4',0,' '
|
||||
db ' ',180,178,184,'6',176,'7'
|
||||
db 179,'8',181,177,183,185,182
|
||||
db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
|
||||
boot_memdetect db 'Determining amount of memory',0
|
||||
boot_fonts db 'Fonts loaded',0
|
||||
boot_tss db 'Setting TSSs',0
|
||||
boot_cpuid db 'Reading CPUIDs',0
|
||||
boot_devices db 'Detecting devices',0
|
||||
boot_timer db 'Setting timer',0
|
||||
boot_irqs db 'Reprogramming IRQs',0
|
||||
boot_setmouse db 'Setting mouse',0
|
||||
boot_windefs db 'Setting window defaults',0
|
||||
boot_bgr db 'Calculating background',0
|
||||
boot_resirqports db 'Reserving IRQs & ports',0
|
||||
boot_setrports db 'Setting addresses for IRQs',0
|
||||
boot_setostask db 'Setting OS task',0
|
||||
boot_allirqs db 'Unmasking all IRQs',0
|
||||
boot_tsc db 'Reading TSC',0
|
||||
boot_cpufreq db 'CPU frequency is ',' ',' MHz',0
|
||||
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0
|
||||
boot_pal_vga db 'Setting VGA 640x480 palette',0
|
||||
boot_failed db 'Failed to start first app',0
|
||||
boot_mtrr db 'Setting MTRR',0
|
||||
if preboot_blogesc
|
||||
boot_tasking db 'All set - press ESC to start',0
|
||||
end if
|
||||
|
||||
;new_process_loading db 'K : New Process - loading',13,10,0
|
||||
;new_process_running db 'K : New Process - done',13,10,0
|
||||
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
|
||||
|
||||
msg_unresolved db 'unresolved ',0
|
||||
msg_module db 'in module ',0
|
||||
msg_version db 'incompatible driver version',13,10,0
|
||||
msg_www db 'please visit www.kolibrios.org',13,10,0
|
||||
msg_CR db 13,10,0
|
||||
aSis db 'SIS',0
|
||||
|
||||
intel_str db "GenuineIntel",0
|
||||
AMD_str db "AuthenticAMD",0
|
||||
|
||||
;szSound db 'SOUND',0
|
||||
;szInfinity db 'INFINITY',0
|
||||
szHwMouse db 'ATI2D',0
|
||||
szPS2MDriver db 'PS2MOUSE',0
|
||||
;szCOM_MDriver db 'COM_MOUSE',0
|
||||
szUSB db 'USB',0
|
||||
szAtiHW db '/rd/1/drivers/ati2d.drv',0
|
||||
|
||||
szSTART db 'START',0
|
||||
szEXPORTS db 'EXPORTS',0
|
||||
sz_EXPORTS db '_EXPORTS',0
|
||||
|
||||
szIMPORTS db 'IMPORTS',0
|
||||
|
||||
read_firstapp db '/sys/'
|
||||
firstapp db 'LAUNCHER',0
|
||||
|
||||
char db '/sys/FONTS/CHAR.MT',0
|
||||
char2 db '/sys/FONTS/CHAR2.MT',0
|
||||
|
||||
bootpath db '/KOLIBRI '
|
||||
bootpath2 db 0
|
||||
vmode db '/sys/drivers/VMODE.MDR',0
|
||||
vrr_m db 'VRR_M',0
|
||||
kernel_file db 'KERNEL MNT'
|
||||
|
||||
|
||||
align 4
|
||||
|
||||
shmem_list:
|
||||
.bk dd shmem_list
|
||||
.fd dd shmem_list
|
||||
|
||||
dll_list:
|
||||
.bk dd dll_list
|
||||
.fd dd dll_list
|
||||
|
||||
MAX_DEFAULT_DLL_ADDR = 0x20000000
|
||||
MIN_DEFAULT_DLL_ADDR = 0x10000000
|
||||
dll_cur_addr dd MIN_DEFAULT_DLL_ADDR
|
||||
|
||||
; supported videomodes
|
||||
|
||||
|
||||
; mike.dld {
|
||||
db 0
|
||||
dd servetable-0x10000
|
||||
draw_line dd __sys_draw_line
|
||||
draw_pointer dd __sys_draw_pointer
|
||||
;//mike.dld, 2006-08-02 [
|
||||
;drawbar dd __sys_drawbar
|
||||
drawbar dd __sys_drawbar.forced
|
||||
;//mike.dld, 2006-08-02 ]
|
||||
putpixel dd __sys_putpixel
|
||||
; } mike.dld
|
||||
|
||||
|
||||
align 4
|
||||
keyboard dd 1
|
||||
syslang dd 1
|
||||
|
||||
boot_y dd 10
|
||||
|
||||
pci_bios_entry dd 0
|
||||
dw pci_code_sel
|
||||
|
||||
if __DEBUG__ eq 1
|
||||
include_debug_strings
|
||||
end if
|
||||
|
||||
IncludeIGlobals
|
||||
|
||||
align 16
|
||||
gdts:
|
||||
|
||||
dw gdte-$-1
|
||||
dd gdts
|
||||
dw 0
|
||||
|
||||
; Attention! Do not change the order of the first four selectors. They are used in Fast System Call
|
||||
; must be : os_code, os_data, app_code, app_data, ....
|
||||
|
||||
int_code_l:
|
||||
os_code_l:
|
||||
dw 0xffff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
dw 11011111b *256 +10011010b
|
||||
db 0x00
|
||||
|
||||
int_data_l:
|
||||
os_data_l:
|
||||
dw 0xffff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
dw 11011111b *256 +10010010b
|
||||
db 0x00
|
||||
|
||||
app_code_l:
|
||||
dw 0xFFFF
|
||||
dw 0
|
||||
db 0
|
||||
db cpl3
|
||||
dw G32+D32+0xF;
|
||||
|
||||
app_data_l:
|
||||
dw 0xFFFF
|
||||
dw 0
|
||||
db 0
|
||||
db drw3
|
||||
dw G32+D32+0xF;
|
||||
|
||||
; ------------- PCI BIOS ------------------
|
||||
|
||||
pci_code_32:
|
||||
dw 0 ;lim 0-15
|
||||
dw 0 ;base 0-15
|
||||
db 0 ;base 16-23
|
||||
db cpl0 ;type
|
||||
db D32 ;lim 16-19+props
|
||||
db 0 ;base 24-31
|
||||
|
||||
pci_data_32:
|
||||
dw 0 ;lim 0-15
|
||||
dw 0 ;base 0-15
|
||||
db 0 ;base 16-23
|
||||
db dpl0 ;type
|
||||
db D32 ;lim 16-19+props
|
||||
db 0 ;base 24-31
|
||||
|
||||
; --------------- APM ---------------------
|
||||
apm_code_32:
|
||||
dw 0x0f ; limit 64kb
|
||||
db 0, 0, 0
|
||||
dw 11010000b *256 +10011010b
|
||||
db 0x00
|
||||
apm_code_16:
|
||||
dw 0x0f
|
||||
db 0, 0, 0
|
||||
dw 10010000b *256 +10011010b
|
||||
db 0x00
|
||||
apm_data_16:
|
||||
dw 0x0f
|
||||
db 0, 0, 0
|
||||
dw 10010000b *256 +10010010b
|
||||
db 0x00
|
||||
; -----------------------------------------
|
||||
|
||||
graph_data_l:
|
||||
|
||||
dw 0x7ff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
dw 11010000b *256 +11110010b
|
||||
db 0x00
|
||||
tss0_l:
|
||||
dw TSS_SIZE-1
|
||||
dw tss and 0xFFFF
|
||||
db (tss shr 16) and 0xFF
|
||||
db 10001001b
|
||||
dw (tss shr 16) and 0xFF00
|
||||
|
||||
tls_data_l:
|
||||
dw 0x0FFF
|
||||
dw 0
|
||||
db 0
|
||||
db drw3
|
||||
dw D32
|
||||
|
||||
endofcode:
|
||||
gdte:
|
||||
|
||||
align 16
|
||||
cur_saved_data rb 4096
|
||||
fpu_data: rb 512
|
||||
|
||||
; device irq owners
|
||||
irq_owner rd 16 ; process id
|
||||
|
||||
; on irq read ports
|
||||
|
||||
irq00read rd 16
|
||||
irq01read rd 16
|
||||
irq02read rd 16
|
||||
irq03read rd 16
|
||||
irq04read rd 16
|
||||
irq05read rd 16
|
||||
irq06read rd 16
|
||||
irq07read rd 16
|
||||
irq08read rd 16
|
||||
irq09read rd 16
|
||||
irq10read rd 16
|
||||
irq11read rd 16
|
||||
irq12read rd 16
|
||||
irq13read rd 16
|
||||
irq14read rd 16
|
||||
irq15read rd 16
|
||||
|
||||
irq_tab rd 16
|
||||
|
||||
mem_block_map rb 512
|
||||
mem_block_list rd 64
|
||||
large_block_list rd 31
|
||||
mem_block_mask rd 2
|
||||
large_block_mask rd 1
|
||||
|
||||
mem_used.fd rd 1
|
||||
mem_used.bk rd 1
|
||||
|
||||
mem_block_arr rd 1
|
||||
mem_block_start rd 1
|
||||
mem_block_end rd 1
|
||||
|
||||
heap_mutex rd 1
|
||||
heap_size rd 1
|
||||
heap_free rd 1
|
||||
heap_blocks rd 1
|
||||
free_blocks rd 1
|
||||
|
||||
mst MEM_STATE
|
||||
|
||||
page_start rd 1
|
||||
page_end rd 1
|
||||
sys_page_map rd 1
|
||||
os_stack_seg rd 1
|
||||
|
||||
|
||||
srv.fd rd 1
|
||||
srv.bk rd 1
|
||||
|
||||
|
||||
align 16
|
||||
|
||||
_display display_t
|
||||
|
||||
_WinMapAddress rd 1
|
||||
_WinMapSize rd 1
|
||||
|
||||
def_cursor rd 1
|
||||
current_cursor rd 1
|
||||
hw_cursor rd 1
|
||||
cur_saved_base rd 1
|
||||
|
||||
cur.lock rd 1 ;1 - lock update, 2- hide
|
||||
cur.left rd 1 ;cursor clip box
|
||||
cur.top rd 1
|
||||
cur.right rd 1
|
||||
cur.bottom rd 1
|
||||
cur.w rd 1
|
||||
cur.h rd 1
|
||||
|
||||
ipc_tmp rd 1
|
||||
ipc_pdir rd 1
|
||||
ipc_ptab rd 1
|
||||
|
||||
proc_mem_map rd 1
|
||||
proc_mem_pdir rd 1
|
||||
proc_mem_tab rd 1
|
||||
|
||||
tmp_task_pdir rd 1
|
||||
tmp_task_ptab rd 1
|
||||
|
||||
default_io_map rd 1
|
||||
|
||||
LFBSize rd 1
|
||||
|
||||
stall_mcs rd 1
|
||||
current_slot rd 1
|
||||
|
||||
; status
|
||||
hd1_status rd 1 ; 0 - free : other - pid
|
||||
application_table_status rd 1 ; 0 - free : other - pid
|
||||
|
||||
; device addresses
|
||||
mididp rd 1
|
||||
midisp rd 1
|
||||
|
||||
cdbase rd 1
|
||||
cdid rd 1
|
||||
|
||||
hdbase rd 1 ; for boot 0x1f0
|
||||
hdid rd 1
|
||||
hdpos rd 1 ; for boot 0x1
|
||||
label known_part dword
|
||||
fat32part rd 1 ; for boot 0x1
|
||||
cdpos rd 1
|
||||
|
||||
;CPUID information
|
||||
cpu_vendor rd 3
|
||||
cpu_sign rd 1
|
||||
cpu_info rd 1
|
||||
cpu_caps rd 4
|
||||
|
||||
|
||||
pg_data PG_DATA
|
||||
heap_test rd 1
|
||||
|
||||
buttontype rd 1
|
||||
windowtypechanged rd 1
|
||||
|
||||
hd_entries rd 1 ;unused ? 0xfe10
|
||||
|
||||
;* start code - Mario79
|
||||
|
||||
mouse_active rd 1
|
||||
mouse_pause rd 1
|
||||
MouseTickCounter rd 1
|
||||
|
||||
;* end code - Mario79
|
||||
|
||||
img_background rd 1
|
||||
mem_BACKGROUND rd 1
|
||||
static_background_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
|
||||
hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache
|
||||
cd_appl_data rb 1 ; 0 = system cache, 1 - application cache
|
||||
|
||||
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
|
||||
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled
|
||||
timer_ticks_enable rb 1 ; for cd driver
|
||||
|
||||
NumBiosDisks rd 1
|
||||
BiosDisksData rb 200h
|
||||
BiosDiskCaches rb 80h*(cache_ide1-cache_ide0)
|
||||
BiosDiskPartitions rd 80h
|
||||
|
||||
IncludeUGlobals
|
81
kernel/branches/kolibri-cfg/detect/biosdisk.inc
Normal file
81
kernel/branches/kolibri-cfg/detect/biosdisk.inc
Normal file
@ -0,0 +1,81 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2008. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Detect all BIOS hard drives.
|
||||
; diamond, 2008
|
||||
|
||||
xor cx, cx
|
||||
mov es, cx
|
||||
mov di, 0x9080
|
||||
mov byte [es:di-1], cl
|
||||
cmp [preboot_biosdisk], 1
|
||||
jnz bdde
|
||||
mov dl, 80h
|
||||
bdds:
|
||||
mov ah, 15h
|
||||
push cx dx di
|
||||
int 13h
|
||||
pop di dx cx
|
||||
jc bddc
|
||||
test ah, ah
|
||||
jz bddc
|
||||
inc cx
|
||||
mov ah, 48h
|
||||
push ds
|
||||
push es
|
||||
pop ds
|
||||
mov si, 0xA000
|
||||
mov word [si], 1Eh
|
||||
mov ah, 48h
|
||||
int 13h
|
||||
pop ds
|
||||
jc bddc2
|
||||
inc byte [es:0x907F]
|
||||
cmp word [es:si], 1Eh
|
||||
jb bddl
|
||||
cmp word [es:si+1Ah], 0xFFFF
|
||||
jz bddl
|
||||
mov al, dl
|
||||
stosb
|
||||
push ds
|
||||
lds si, [es:si+1Ah]
|
||||
mov al, [si+6]
|
||||
and al, 0xF
|
||||
stosb
|
||||
mov al, byte [si+4]
|
||||
shr al, 4
|
||||
and ax, 1
|
||||
cmp word [si], 1F0h
|
||||
jz @f
|
||||
inc ax
|
||||
inc ax
|
||||
cmp word [si], 170h
|
||||
jz @f
|
||||
or ax,-1
|
||||
; mov ax, -1
|
||||
@@:
|
||||
stosw
|
||||
pop ds
|
||||
jmp bddc2
|
||||
bddl:
|
||||
mov al, dl
|
||||
stosb
|
||||
xor ax,ax
|
||||
stosb
|
||||
dec ax
|
||||
stosw
|
||||
; mov al, 0
|
||||
; stosb
|
||||
; mov ax, -1
|
||||
; stosw
|
||||
bddc2:
|
||||
cmp cl, [es:0x475]
|
||||
jae bdde
|
||||
bddc:
|
||||
inc dl
|
||||
jnz bdds
|
||||
bdde:
|
43
kernel/branches/kolibri-cfg/detect/biosmem.inc
Normal file
43
kernel/branches/kolibri-cfg/detect/biosmem.inc
Normal file
@ -0,0 +1,43 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Query physical memory map from BIOS.
|
||||
; diamond, 2009
|
||||
|
||||
push ds
|
||||
; first call to fn E820
|
||||
mov eax, 0xE820
|
||||
xor ebx, ebx
|
||||
mov es, bx
|
||||
mov ds, bx
|
||||
mov di, 0x9104
|
||||
mov [di-4], ebx ; no blocks yet
|
||||
mov ecx, 20
|
||||
mov edx, 0x534D4150
|
||||
int 15h
|
||||
jc no_E820
|
||||
cmp eax, 0x534D4150
|
||||
jnz no_E820
|
||||
e820_mem_loop:
|
||||
cmp byte [di+16], 1 ; ignore non-free areas
|
||||
jnz e820_mem_next
|
||||
inc byte [0x9100]
|
||||
add di, 20
|
||||
e820_mem_next:
|
||||
; consequent calls to fn E820
|
||||
test ebx, ebx
|
||||
jz e820_test_done
|
||||
cmp byte [0x9100], 32
|
||||
jae e820_test_done
|
||||
mov eax, 0xE820
|
||||
int 15h
|
||||
jc e820_test_done
|
||||
jmp e820_mem_loop
|
||||
no_E820:
|
||||
; let's hope for mem_test from init.inc
|
||||
e820_test_done:
|
||||
pop ds
|
30
kernel/branches/kolibri-cfg/detect/dev_fd.inc
Normal file
30
kernel/branches/kolibri-cfg/detect/dev_fd.inc
Normal file
@ -0,0 +1,30 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
;***************************************************
|
||||
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû
|
||||
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD
|
||||
; àâòîð Mario79
|
||||
;***************************************************
|
||||
xor eax,eax
|
||||
mov edi,DRIVE_DATA
|
||||
mov ecx,16384
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov al,0x10
|
||||
out 0x70,al
|
||||
mov cx,0xff
|
||||
wait_cmos:
|
||||
dec cx
|
||||
test cx,cx
|
||||
jnz wait_cmos
|
||||
in al,0x71
|
||||
mov [DRIVE_DATA],al
|
385
kernel/branches/kolibri-cfg/detect/dev_hdcd.inc
Normal file
385
kernel/branches/kolibri-cfg/detect/dev_hdcd.inc
Normal file
@ -0,0 +1,385 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
;******************************************************
|
||||
; поиск приводов HDD и CD
|
||||
; автор исходного текста Кулаков Владимир Геннадьевич.
|
||||
; адаптация и доработка Mario79
|
||||
;******************************************************
|
||||
|
||||
;****************************************************
|
||||
;* ПОИСК HDD и CD *
|
||||
;****************************************************
|
||||
FindHDD:
|
||||
mov [ChannelNumber],1
|
||||
mov [DiskNumber],0
|
||||
call FindHDD_3
|
||||
; mov ax,[Sector512+176]
|
||||
; mov [DRIVE_DATA+6],ax
|
||||
; mov ax,[Sector512+126]
|
||||
; mov [DRIVE_DATA+8],ax
|
||||
; mov ax,[Sector512+128]
|
||||
; mov [DRIVE_DATA+8],ax
|
||||
mov [DiskNumber],1
|
||||
call FindHDD_3
|
||||
; mov al,[Sector512+176]
|
||||
; mov [DRIVE_DATA+7],al
|
||||
inc [ChannelNumber]
|
||||
mov [DiskNumber],0
|
||||
call FindHDD_3
|
||||
; mov al,[Sector512+176]
|
||||
; mov [DRIVE_DATA+8],al
|
||||
mov [DiskNumber],1
|
||||
call FindHDD_1
|
||||
; mov al,[Sector512+176]
|
||||
; mov [DRIVE_DATA+9],al
|
||||
|
||||
jmp EndFindHDD
|
||||
|
||||
FindHDD_1:
|
||||
call ReadHDD_ID
|
||||
cmp [DevErrorCode],0
|
||||
jne FindHDD_2
|
||||
cmp [Sector512+6],word 16
|
||||
ja FindHDD_2
|
||||
cmp [Sector512+12],word 255
|
||||
ja FindHDD_2
|
||||
inc byte [DRIVE_DATA+1]
|
||||
jmp FindHDD_2_2
|
||||
FindHDD_2:
|
||||
call DeviceReset
|
||||
cmp [DevErrorCode],0
|
||||
jne FindHDD_2_2
|
||||
call ReadCD_ID
|
||||
cmp [DevErrorCode],0
|
||||
jne FindHDD_2_2
|
||||
inc byte [DRIVE_DATA+1]
|
||||
inc byte [DRIVE_DATA+1]
|
||||
FindHDD_2_2:
|
||||
ret
|
||||
|
||||
FindHDD_3:
|
||||
call FindHDD_1
|
||||
shl byte [DRIVE_DATA+1],2
|
||||
ret
|
||||
|
||||
|
||||
; Адрес считываемого сектора в режиме LBA
|
||||
uglobal
|
||||
SectorAddress DD ?
|
||||
endg
|
||||
;*************************************************
|
||||
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала (1 или 2); *
|
||||
;* DiskNumber - номер диска на канале (0 или 1). *
|
||||
;* Идентификационный блок данных считывается *
|
||||
;* в массив Sector512. *
|
||||
;*************************************************
|
||||
ReadHDD_ID:
|
||||
; Задать режим CHS
|
||||
mov [ATAAddressMode],0
|
||||
; Послать команду идентификации устройства
|
||||
mov [ATAFeatures],0
|
||||
mov [ATAHead],0
|
||||
mov [ATACommand],0ECh
|
||||
call SendCommandToHDD
|
||||
cmp [DevErrorCode],0 ;проверить код ошибки
|
||||
jne @@End ;закончить, сохранив код ошибки
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;адрес регистра состояни
|
||||
mov ecx,0xffff
|
||||
@@WaitCompleet:
|
||||
; Проверить время выполнения команды
|
||||
dec ecx
|
||||
; cmp ecx,0
|
||||
jz @@Error1 ;ошибка тайм-аута
|
||||
; Проверить готовность
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitCompleet
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Error6
|
||||
test AL,08h ;состояние сигнала DRQ
|
||||
jz @@WaitCompleet
|
||||
; Принять блок данных от контроллера
|
||||
; mov AX,DS
|
||||
; mov ES,AX
|
||||
mov EDI,Sector512 ;offset Sector512
|
||||
mov DX,[ATABasePortAddr] ;регистр данных
|
||||
mov CX,256 ;число считываемых слов
|
||||
rep insw ;принять блок данных
|
||||
ret
|
||||
; Записать код ошибки
|
||||
@@Error1:
|
||||
mov [DevErrorCode],1
|
||||
ret
|
||||
@@Error6:
|
||||
mov [DevErrorCode],6
|
||||
@@End: ret
|
||||
|
||||
|
||||
iglobal
|
||||
; Стандартные базовые адреса каналов 1 и 2
|
||||
StandardATABases DW 1F0h, 170h
|
||||
endg
|
||||
uglobal
|
||||
; Номер канала
|
||||
ChannelNumber DW ?
|
||||
; Номер диска
|
||||
DiskNumber DB ?
|
||||
; Базовый адрес группы портов контроллера ATA
|
||||
ATABasePortAddr DW ?
|
||||
; Параметры ATA-команды
|
||||
ATAFeatures DB ? ;особенности
|
||||
ATASectorCount DB ? ;количество обрабатываемых секторов
|
||||
ATASectorNumber DB ? ;номер начального сектора
|
||||
ATACylinder DW ? ;номер начального цилиндра
|
||||
ATAHead DB ? ;номер начальной головки
|
||||
ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA)
|
||||
ATACommand DB ? ;код команды, подлежащей выполнению
|
||||
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
|
||||
; интервал ожидания, 2 - неверный код режима адресации,
|
||||
; 3 - неверный номер канала, 4 - неверный номер диска,
|
||||
; 5 - неверный номер головки, 6 - ошибка при выполнении
|
||||
; команды)
|
||||
DevErrorCode dd ?
|
||||
endg
|
||||
;****************************************************
|
||||
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала (1 или 2); *
|
||||
;* DiskNumber - номер диска (0 или 1); *
|
||||
;* ATAFeatures - "особенности"; *
|
||||
;* ATASectorCount - количество секторов; *
|
||||
;* ATASectorNumber - номер начального сектора; *
|
||||
;* ATACylinder - номер начального цилиндра; *
|
||||
;* ATAHead - номер начальной головки; *
|
||||
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
|
||||
;* ATACommand - код команды. *
|
||||
;* После успешного выполнения функции: *
|
||||
;* в ATABasePortAddr - базовый адрес HDD; *
|
||||
;* в DevErrorCode - ноль. *
|
||||
;* При возникновении ошибки в DevErrorCode будет *
|
||||
;* возвращен код ошибки. *
|
||||
;****************************************************
|
||||
SendCommandToHDD:
|
||||
; Проверить значение кода режима
|
||||
cmp [ATAAddressMode],1
|
||||
ja @@Err2
|
||||
; Проверить корректность номера канала
|
||||
mov BX,[ChannelNumber]
|
||||
cmp BX,1
|
||||
jb @@Err3
|
||||
cmp BX,2
|
||||
ja @@Err3
|
||||
; Установить базовый адрес
|
||||
dec BX
|
||||
shl BX,1
|
||||
movzx ebx,bx
|
||||
mov AX,[ebx+StandardATABases]
|
||||
mov [ATABasePortAddr],AX
|
||||
; Ожидание готовности HDD к приему команды
|
||||
; Выбрать нужный диск
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,6 ;адрес регистра головок
|
||||
mov AL,[DiskNumber]
|
||||
cmp AL,1 ;проверить номера диска
|
||||
ja @@Err4
|
||||
shl AL,4
|
||||
or AL,10100000b
|
||||
out DX,AL
|
||||
; Ожидать, пока диск не будет готов
|
||||
inc DX
|
||||
mov ecx,0xfff
|
||||
; mov eax,[timer_ticks]
|
||||
; mov [TickCounter_1],eax
|
||||
@@WaitHDReady:
|
||||
; Проверить время ожидани
|
||||
dec ecx
|
||||
; cmp ecx,0
|
||||
jz @@Err1
|
||||
; mov eax,[timer_ticks]
|
||||
; sub eax,[TickCounter_1]
|
||||
; cmp eax,300 ;ожидать 300 тиков
|
||||
; ja @@Err1 ;ошибка тайм-аута
|
||||
; Прочитать регистр состояни
|
||||
in AL,DX
|
||||
; Проверить состояние сигнала BSY
|
||||
test AL,80h
|
||||
jnz @@WaitHDReady
|
||||
; Проверить состояние сигнала DRQ
|
||||
test AL,08h
|
||||
jnz @@WaitHDReady
|
||||
; Загрузить команду в регистры контроллера
|
||||
cli
|
||||
mov DX,[ATABasePortAddr]
|
||||
inc DX ;регистр "особенностей"
|
||||
mov AL,[ATAFeatures]
|
||||
out DX,AL
|
||||
inc DX ;счетчик секторов
|
||||
mov AL,[ATASectorCount]
|
||||
out DX,AL
|
||||
inc DX ;регистр номера сектора
|
||||
mov AL,[ATASectorNumber]
|
||||
out DX,AL
|
||||
inc DX ;номер цилиндра (младший байт)
|
||||
mov AX,[ATACylinder]
|
||||
out DX,AL
|
||||
inc DX ;номер цилиндра (старший байт)
|
||||
mov AL,AH
|
||||
out DX,AL
|
||||
inc DX ;номер головки/номер диска
|
||||
mov AL,[DiskNumber]
|
||||
shl AL,4
|
||||
cmp [ATAHead],0Fh ;проверить номер головки
|
||||
ja @@Err5
|
||||
or AL,[ATAHead]
|
||||
or AL,10100000b
|
||||
mov AH,[ATAAddressMode]
|
||||
shl AH,6
|
||||
or AL,AH
|
||||
out DX,AL
|
||||
; Послать команду
|
||||
mov AL,[ATACommand]
|
||||
inc DX ;регистр команд
|
||||
out DX,AL
|
||||
sti
|
||||
; Сбросить признак ошибки
|
||||
mov [DevErrorCode],0
|
||||
ret
|
||||
; Записать код ошибки
|
||||
@@Err1: mov [DevErrorCode],1
|
||||
ret
|
||||
@@Err2: mov [DevErrorCode],2
|
||||
ret
|
||||
@@Err3: mov [DevErrorCode],3
|
||||
ret
|
||||
@@Err4: mov [DevErrorCode],4
|
||||
ret
|
||||
@@Err5: mov [DevErrorCode],5
|
||||
; Завершение работы программы
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;* Идентификационный блок данных считывается *
|
||||
;* в массив Sector512. *
|
||||
;*************************************************
|
||||
ReadCD_ID:
|
||||
; Задать режим CHS
|
||||
mov [ATAAddressMode],0
|
||||
; Послать команду идентификации устройства
|
||||
mov [ATAFeatures],0
|
||||
mov [ATASectorCount],0
|
||||
mov [ATASectorNumber],0
|
||||
mov [ATACylinder],0
|
||||
mov [ATAHead],0
|
||||
mov [ATACommand],0A1h
|
||||
call SendCommandToHDD
|
||||
cmp [DevErrorCode],0 ;проверить код ошибки
|
||||
jne @@End_1 ;закончить, сохранив код ошибки
|
||||
; Ожидать готовность данных HDD
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
mov ecx,0xffff
|
||||
@@WaitCompleet_1:
|
||||
; Проверить врем
|
||||
dec ecx
|
||||
; cmp ecx,0
|
||||
jz @@Error1_1 ;ошибка тайм-аута
|
||||
; Проверить готовность
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitCompleet_1
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Error6_1
|
||||
test AL,08h ;состояние сигнала DRQ
|
||||
jz @@WaitCompleet_1
|
||||
; Принять блок данных от контроллера
|
||||
; mov AX,DS
|
||||
; mov ES,AX
|
||||
mov EDI,Sector512 ;offset Sector512
|
||||
mov DX,[ATABasePortAddr] ;порт 1x0h
|
||||
mov CX,256 ;число считываемых слов
|
||||
rep insw
|
||||
ret
|
||||
; Записать код ошибки
|
||||
@@Error1_1:
|
||||
mov [DevErrorCode],1
|
||||
ret
|
||||
@@Error6_1:
|
||||
mov [DevErrorCode],6
|
||||
@@End_1:
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* СБРОС УСТРОЙСТВА *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала (1 или 2); *
|
||||
;* DiskNumber - номер диска (0 или 1). *
|
||||
;*************************************************
|
||||
DeviceReset:
|
||||
; Проверить корректность номера канала
|
||||
mov BX,[ChannelNumber]
|
||||
cmp BX,1
|
||||
jb @@Err3_2
|
||||
cmp BX,2
|
||||
ja @@Err3_2
|
||||
; Установить базовый адрес
|
||||
dec BX
|
||||
shl BX,1
|
||||
movzx ebx,bx
|
||||
mov DX,[ebx+StandardATABases]
|
||||
mov [ATABasePortAddr],DX
|
||||
; Выбрать нужный диск
|
||||
add DX,6 ;адрес регистра головок
|
||||
mov AL,[DiskNumber]
|
||||
cmp AL,1 ;проверить номера диска
|
||||
ja @@Err4_2
|
||||
shl AL,4
|
||||
or AL,10100000b
|
||||
out DX,AL
|
||||
; Послать команду "Сброс"
|
||||
mov AL,08h
|
||||
inc DX ;регистр команд
|
||||
out DX,AL
|
||||
mov ecx,0x80000
|
||||
@@WaitHDReady_1:
|
||||
; Проверить время ожидани
|
||||
dec ecx
|
||||
; cmp ecx,0
|
||||
je @@Err1_2 ;ошибка тайм-аута
|
||||
; Прочитать регистр состояни
|
||||
in AL,DX
|
||||
; Проверить состояние сигнала BSY
|
||||
test AL,80h
|
||||
jnz @@WaitHDReady_1
|
||||
; Сбросить признак ошибки
|
||||
mov [DevErrorCode],0
|
||||
ret
|
||||
; Обработка ошибок
|
||||
@@Err1_2: mov [DevErrorCode],1
|
||||
ret
|
||||
@@Err3_2: mov [DevErrorCode],3
|
||||
ret
|
||||
@@Err4_2: mov [DevErrorCode],4
|
||||
; Записать код ошибки
|
||||
ret
|
||||
|
||||
EndFindHDD:
|
||||
|
15
kernel/branches/kolibri-cfg/detect/disks.inc
Normal file
15
kernel/branches/kolibri-cfg/detect/disks.inc
Normal file
@ -0,0 +1,15 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
include 'dev_fd.inc'
|
||||
include 'dev_hdcd.inc'
|
||||
include 'getcache.inc'
|
||||
include 'sear_par.inc'
|
||||
|
212
kernel/branches/kolibri-cfg/detect/getcache.inc
Normal file
212
kernel/branches/kolibri-cfg/detect/getcache.inc
Normal file
@ -0,0 +1,212 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
pusha
|
||||
|
||||
mov eax,[pg_data.pages_free]
|
||||
; 1/32
|
||||
shr eax,5
|
||||
; round off up to 8 pages
|
||||
shr eax,3
|
||||
shl eax,3
|
||||
; translate pages in butes *4096
|
||||
shl eax,12
|
||||
; check a upper size of the cache, no more than 1 Mb on the physical device
|
||||
cmp eax,1024*1024
|
||||
jbe @f
|
||||
mov eax,1024*1024
|
||||
jmp .continue
|
||||
@@:
|
||||
; check a lower size of the cache, not less than 128 Kb on the physical device
|
||||
cmp eax,128*1024
|
||||
jae @f
|
||||
mov eax,128*1024
|
||||
@@:
|
||||
.continue:
|
||||
mov [cache_ide0_size],eax
|
||||
mov [cache_ide1_size],eax
|
||||
mov [cache_ide2_size],eax
|
||||
mov [cache_ide3_size],eax
|
||||
xor eax,eax
|
||||
mov [hdd_appl_data],1 ;al
|
||||
mov [cd_appl_data],1
|
||||
|
||||
mov ch,[DRIVE_DATA+1]
|
||||
mov cl,ch
|
||||
and cl,11b
|
||||
je .ide2
|
||||
mov esi,cache_ide3
|
||||
call get_cache_ide
|
||||
.ide2:
|
||||
mov cl,ch
|
||||
shr cl,2
|
||||
and cl,11b
|
||||
je .ide1
|
||||
mov esi,cache_ide2
|
||||
call get_cache_ide
|
||||
.ide1:
|
||||
mov cl,ch
|
||||
shr cl,4
|
||||
and cl,11b
|
||||
je .ide0
|
||||
mov esi,cache_ide1
|
||||
call get_cache_ide
|
||||
.ide0:
|
||||
mov cl,ch
|
||||
shr cl,6
|
||||
and cl,11b
|
||||
je @f
|
||||
mov esi,cache_ide0
|
||||
call get_cache_ide
|
||||
@@:
|
||||
xor ecx,ecx
|
||||
cmp [NumBiosDisks],ecx
|
||||
jz .endbd
|
||||
mov esi,BiosDiskCaches
|
||||
.loopbd:
|
||||
push ecx
|
||||
movsx ecx,byte [BiosDisksData+ecx*4+2]
|
||||
inc ecx
|
||||
jz .getbd
|
||||
add ecx,ecx
|
||||
movzx eax,byte [DRIVE_DATA+1]
|
||||
shl eax,cl
|
||||
and ah,3
|
||||
cmp ah,1
|
||||
jz .contbd
|
||||
pop ecx
|
||||
mov byte [BiosDisksData+ecx*4+2], -1
|
||||
push ecx
|
||||
.getbd:
|
||||
mov eax,[cache_ide0_size]
|
||||
mov [esi+cache_ide0_size-cache_ide0],eax
|
||||
mov cl,1
|
||||
call get_cache_ide
|
||||
.contbd:
|
||||
pop ecx
|
||||
add esi,cache_ide1-cache_ide0
|
||||
inc ecx
|
||||
cmp ecx,[NumBiosDisks]
|
||||
jb .loopbd
|
||||
.endbd:
|
||||
jmp end_get_cache
|
||||
|
||||
get_cache_ide:
|
||||
and [esi+cache_ide0_search_start-cache_ide0],0
|
||||
and [esi+cache_ide0_appl_search_start-cache_ide0],0
|
||||
push ecx
|
||||
stdcall kernel_alloc,[esi+cache_ide0_size-cache_ide0]
|
||||
mov [esi+cache_ide0_pointer-cache_ide0],eax
|
||||
pop ecx
|
||||
mov edx,eax
|
||||
mov eax,[esi+cache_ide0_size-cache_ide0]
|
||||
shr eax,3
|
||||
mov [esi+cache_ide0_system_data_size-cache_ide0],eax
|
||||
mov ebx,eax
|
||||
imul eax,7
|
||||
mov [esi+cache_ide0_appl_data_size-cache_ide0],eax
|
||||
add ebx,edx
|
||||
mov [esi+cache_ide0_data_pointer-cache_ide0],ebx
|
||||
|
||||
cmp cl,10b
|
||||
je .cd
|
||||
push ecx
|
||||
mov eax,[esi+cache_ide0_system_data_size-cache_ide0]
|
||||
call calculate_for_hd
|
||||
add eax,[esi+cache_ide0_pointer-cache_ide0]
|
||||
mov [esi+cache_ide0_system_data-cache_ide0],eax
|
||||
mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx
|
||||
|
||||
push edi
|
||||
mov edi,[esi+cache_ide0_pointer-cache_ide0]
|
||||
call clear_ide_cache
|
||||
pop edi
|
||||
|
||||
mov eax,[esi+cache_ide0_appl_data_size-cache_ide0]
|
||||
call calculate_for_hd
|
||||
add eax,[esi+cache_ide0_data_pointer-cache_ide0]
|
||||
mov [esi+cache_ide0_appl_data-cache_ide0],eax
|
||||
mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx
|
||||
|
||||
push edi
|
||||
mov edi,[esi+cache_ide0_data_pointer-cache_ide0]
|
||||
call clear_ide_cache
|
||||
pop edi
|
||||
|
||||
pop ecx
|
||||
ret
|
||||
.cd:
|
||||
push ecx
|
||||
mov eax,[esi+cache_ide0_system_data_size-cache_ide0]
|
||||
call calculate_for_cd
|
||||
add eax,[esi+cache_ide0_pointer-cache_ide0]
|
||||
mov [esi+cache_ide0_system_data-cache_ide0],eax
|
||||
mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx
|
||||
|
||||
push edi
|
||||
mov edi,[esi+cache_ide0_pointer-cache_ide0]
|
||||
call clear_ide_cache
|
||||
pop edi
|
||||
|
||||
mov eax,[esi+cache_ide0_appl_data_size-cache_ide0]
|
||||
call calculate_for_cd
|
||||
add eax,[esi+cache_ide0_data_pointer-cache_ide0]
|
||||
mov [esi+cache_ide0_appl_data-cache_ide0],eax
|
||||
mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx
|
||||
|
||||
push edi
|
||||
mov edi,[esi+cache_ide0_data_pointer-cache_ide0]
|
||||
call clear_ide_cache
|
||||
pop edi
|
||||
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
calculate_for_hd:
|
||||
push eax
|
||||
mov ebx,eax
|
||||
shr eax,9
|
||||
shl eax,3
|
||||
sub ebx,eax
|
||||
shr ebx,9
|
||||
mov ecx,ebx
|
||||
shl ebx,9
|
||||
pop eax
|
||||
sub eax,ebx
|
||||
dec ecx
|
||||
ret
|
||||
|
||||
calculate_for_cd:
|
||||
push eax
|
||||
mov ebx,eax
|
||||
shr eax,11
|
||||
shl eax,3
|
||||
sub ebx,eax
|
||||
shr ebx,11
|
||||
mov ecx,ebx
|
||||
shl ebx,11
|
||||
pop eax
|
||||
sub eax,ebx
|
||||
dec ecx
|
||||
ret
|
||||
|
||||
clear_ide_cache:
|
||||
push eax
|
||||
shl ecx,1
|
||||
xor eax,eax
|
||||
cld
|
||||
rep stosd
|
||||
pop eax
|
||||
ret
|
||||
|
||||
end_get_cache:
|
||||
; mov [cache_ide0_pointer],HD_CACHE
|
||||
; mov [cache_ide0_system_data],HD_CACHE+65536
|
||||
; mov [cache_ide0_system_sad_size],1919
|
||||
popa
|
157
kernel/branches/kolibri-cfg/detect/sear_par.inc
Normal file
157
kernel/branches/kolibri-cfg/detect/sear_par.inc
Normal file
@ -0,0 +1,157 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
;****************************************************
|
||||
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD
|
||||
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû
|
||||
; àâòîð Mario79
|
||||
;****************************************************
|
||||
mov [transfer_adress],DRIVE_DATA+0xa
|
||||
search_partitions_ide0:
|
||||
test [DRIVE_DATA+1],byte 0x40
|
||||
jz search_partitions_ide1
|
||||
mov [hdbase],0x1f0
|
||||
mov [hdid],0x0
|
||||
mov [hdpos],1
|
||||
mov [known_part],1
|
||||
search_partitions_ide0_1:
|
||||
call set_PARTITION_variables
|
||||
test [problem_partition],2
|
||||
jnz search_partitions_ide1 ; not found part
|
||||
test [problem_partition],1
|
||||
jnz @F ; not found known_part
|
||||
;cmp [problem_partition],0
|
||||
;jne search_partitions_ide1
|
||||
inc byte [DRIVE_DATA+2]
|
||||
call partition_data_transfer
|
||||
add [transfer_adress],100
|
||||
@@:
|
||||
inc [known_part]
|
||||
jmp search_partitions_ide0_1
|
||||
|
||||
search_partitions_ide1:
|
||||
test [DRIVE_DATA+1],byte 0x10
|
||||
jz search_partitions_ide2
|
||||
mov [hdbase],0x1f0
|
||||
mov [hdid],0x10
|
||||
mov [hdpos],2
|
||||
mov [known_part],1
|
||||
search_partitions_ide1_1:
|
||||
call set_PARTITION_variables
|
||||
test [problem_partition],2
|
||||
jnz search_partitions_ide2
|
||||
test [problem_partition],1
|
||||
jnz @F
|
||||
;cmp [problem_partition],0
|
||||
;jne search_partitions_ide2
|
||||
inc byte [DRIVE_DATA+3]
|
||||
call partition_data_transfer
|
||||
add [transfer_adress],100
|
||||
@@:
|
||||
inc [known_part]
|
||||
jmp search_partitions_ide1_1
|
||||
|
||||
search_partitions_ide2:
|
||||
test [DRIVE_DATA+1],byte 0x4
|
||||
jz search_partitions_ide3
|
||||
mov [hdbase],0x170
|
||||
mov [hdid],0x0
|
||||
mov [hdpos],3
|
||||
mov [known_part],1
|
||||
search_partitions_ide2_1:
|
||||
call set_PARTITION_variables
|
||||
test [problem_partition],2
|
||||
jnz search_partitions_ide3
|
||||
test [problem_partition],1
|
||||
jnz @F
|
||||
;cmp [problem_partition],0
|
||||
;jne search_partitions_ide3
|
||||
inc byte [DRIVE_DATA+4]
|
||||
call partition_data_transfer
|
||||
add [transfer_adress],100
|
||||
@@:
|
||||
inc [known_part]
|
||||
jmp search_partitions_ide2_1
|
||||
|
||||
search_partitions_ide3:
|
||||
test [DRIVE_DATA+1],byte 0x1
|
||||
jz end_search_partitions_ide
|
||||
mov [hdbase],0x170
|
||||
mov [hdid],0x10
|
||||
mov [hdpos],4
|
||||
mov [known_part],1
|
||||
search_partitions_ide3_1:
|
||||
call set_PARTITION_variables
|
||||
test [problem_partition],2
|
||||
jnz end_search_partitions_ide
|
||||
test [problem_partition],1
|
||||
jnz @F
|
||||
;cmp [problem_partition],0
|
||||
;jne end_search_partitions_ide
|
||||
inc byte [DRIVE_DATA+5]
|
||||
call partition_data_transfer
|
||||
add [transfer_adress],100
|
||||
@@:
|
||||
inc [known_part]
|
||||
jmp search_partitions_ide3_1
|
||||
|
||||
end_search_partitions_ide:
|
||||
mov [hdpos], 80h
|
||||
mov ecx, [NumBiosDisks]
|
||||
test ecx, ecx
|
||||
jz end_search_partitions
|
||||
start_search_partitions_bd:
|
||||
push ecx
|
||||
mov eax, [hdpos]
|
||||
and [BiosDiskPartitions+(eax-80h)*4], 0
|
||||
mov [known_part], 1
|
||||
search_partitions_bd:
|
||||
call set_PARTITION_variables
|
||||
test [problem_partition],2
|
||||
jnz end_search_partitions_bd
|
||||
test [problem_partition],1
|
||||
jnz @F
|
||||
;cmp [problem_partition], 0
|
||||
;jne end_search_partitions_bd
|
||||
mov eax, [hdpos]
|
||||
inc [BiosDiskPartitions+(eax-80h)*4]
|
||||
call partition_data_transfer
|
||||
add [transfer_adress], 100
|
||||
@@:
|
||||
inc [known_part]
|
||||
jmp search_partitions_bd
|
||||
end_search_partitions_bd:
|
||||
pop ecx
|
||||
inc [hdpos]
|
||||
loop start_search_partitions_bd
|
||||
jmp end_search_partitions
|
||||
|
||||
partition_data_transfer:
|
||||
mov edi,[transfer_adress]
|
||||
mov esi,PARTITION_START ;start of file_system_data
|
||||
mov ecx,(file_system_data_size+3)/4
|
||||
rep movsd
|
||||
ret
|
||||
uglobal
|
||||
transfer_adress dd 0
|
||||
endg
|
||||
partition_data_transfer_1:
|
||||
; cli
|
||||
push edi
|
||||
mov edi,PARTITION_START
|
||||
mov esi,[transfer_adress]
|
||||
mov ecx,(file_system_data_size+3)/4
|
||||
rep movsd
|
||||
pop edi
|
||||
; sti
|
||||
ret
|
||||
|
||||
end_search_partitions:
|
||||
|
518
kernel/branches/kolibri-cfg/docs/apm.txt
Normal file
518
kernel/branches/kolibri-cfg/docs/apm.txt
Normal file
@ -0,0 +1,518 @@
|
||||
--------p-155300-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK
|
||||
AX = 5300h
|
||||
BX = device ID of system BIOS (0000h)
|
||||
Return: CF clear if successful
|
||||
AH = major version (BCD)
|
||||
AL = minor version (BCD)
|
||||
BX = 504Dh ("PM")
|
||||
CX = flags (see #00472)
|
||||
CF set on error
|
||||
AH = error code (06h,09h,86h) (see #00473)
|
||||
BUG: early versions of the Award Modular BIOS with built-in APM support
|
||||
reportedly do not set BX on return
|
||||
|
||||
Bitfields for APM flags:
|
||||
Bit(s) Description (Table 00472)
|
||||
0 16-bit protected mode interface supported
|
||||
1 32-bit protected mode interface supported
|
||||
2 CPU idle call reduces processor speed
|
||||
3 BIOS power management disabled
|
||||
4 BIOS power management disengaged (APM v1.1)
|
||||
5-7 reserved
|
||||
|
||||
(Table 00473)
|
||||
Values for APM error code:
|
||||
01h power management functionality disabled
|
||||
02h interface connection already in effect
|
||||
03h interface not connected
|
||||
04h real-mode interface not connected
|
||||
05h 16-bit protected-mode interface already connected
|
||||
06h 16-bit protected-mode interface not supported
|
||||
07h 32-bit protected-mode interface already connected
|
||||
08h 32-bit protected-mode interface not supported
|
||||
09h unrecognized device ID
|
||||
0Ah invalid parameter value in CX
|
||||
0Bh (APM v1.1) interface not engaged
|
||||
0Ch (APM v1.2) function not supported
|
||||
0Dh (APM v1.2) Resume Timer disabled
|
||||
0Eh-1Fh reserved for other interface and general errors
|
||||
20h-3Fh reserved for CPU errors
|
||||
40h-5Fh reserved for device errors
|
||||
60h can't enter requested state
|
||||
61h-7Fh reserved for other system errors
|
||||
80h no power management events pending
|
||||
81h-85h reserved for other power management event errors
|
||||
86h APM not present
|
||||
87h-9Fh reserved for other power management event errors
|
||||
A0h-FEh reserved
|
||||
FFh undefined
|
||||
--------p-155301-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE
|
||||
AX = 5301h
|
||||
BX = device ID of system BIOS (0000h)
|
||||
Return: CF clear if successful
|
||||
CF set on error
|
||||
AH = error code (02h,05h,07h,09h) (see #00473)
|
||||
Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
|
||||
compatibility mode until it is informed that the user supports a
|
||||
newer version of APM (see AX=530Eh)
|
||||
SeeAlso: AX=5302h,AX=5303h,AX=5304h
|
||||
--------p-155302-----------------------------
|
||||
INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE
|
||||
AX = 5302h
|
||||
BX = device ID of system BIOS (0000h)
|
||||
Return: CF clear if successful
|
||||
AX = real-mode segment base address of protected-mode 16-bit code
|
||||
segment
|
||||
BX = offset of entry point
|
||||
CX = real-mode segment base address of protected-mode 16-bit data
|
||||
segment
|
||||
---APM v1.1---
|
||||
SI = APM BIOS code segment length
|
||||
DI = APM BIOS data segment length
|
||||
CF set on error
|
||||
AH = error code (02h,05h,06h,07h,09h) (see #00473)
|
||||
Notes: the caller must initialize two consecutive descriptors with the
|
||||
returned segment base addresses; these descriptors must be valid
|
||||
whenever the protected-mode interface is called, and will have
|
||||
their limits arbitrarily set to 64K.
|
||||
the protected mode interface is invoked by making a far call with the
|
||||
same register values as for INT 15; it must be invoked while CPL=0,
|
||||
the code segment descriptor must have a DPL of 0, the stack must be
|
||||
in a 16-bit segment and have enough room for BIOS use and possible
|
||||
interrupts, and the current I/O permission bit map must allow access
|
||||
to the I/O ports used for power management.
|
||||
functions 00h-03h are not available from protected mode
|
||||
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
|
||||
compatibility mode until it is informed that the user supports a
|
||||
newer version of APM (see AX=530Eh)
|
||||
SeeAlso: AX=5301h,AX=5303h,AX=5304h
|
||||
--------p-155303-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE
|
||||
AX = 5303h
|
||||
BX = device ID of system BIOS (0000h)
|
||||
Return: CF clear if successful
|
||||
AX = real-mode segment base address of protected-mode 32-bit code
|
||||
segment
|
||||
EBX = offset of entry point
|
||||
CX = real-mode segment base address of protected-mode 16-bit code
|
||||
segment
|
||||
DX = real-mode segment base address of protected-mode 16-bit data
|
||||
segment
|
||||
---APM v1.1---
|
||||
SI = APM BIOS code segment length
|
||||
DI = APM BIOS data segment length
|
||||
CF set on error
|
||||
AH = error code (02h,05h,07h,08h,09h) (see #00473)
|
||||
Notes: the caller must initialize three consecutive descriptors with the
|
||||
returned segment base addresses for 32-bit code, 16-bit code, and
|
||||
16-bit data, respectively; these descriptors must be valid whenever
|
||||
the protected-mode interface is called, and will have their limits
|
||||
arbitrarily set to 64K.
|
||||
the protected mode interface is invoked by making a far call to the
|
||||
32-bit code segment with the same register values as for INT 15; it
|
||||
must be invoked while CPL=0, the code segment descriptor must have a
|
||||
DPL of 0, the stack must be in a 32-bit segment and have enough room
|
||||
for BIOS use and possible interrupts, and the current I/O permission
|
||||
bit map must allow access to the I/O ports used for power management.
|
||||
functions 00h-03h are not available from protected mode
|
||||
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
|
||||
compatibility mode until it is informed that the user supports a
|
||||
newer version of APM (see AX=530Eh)
|
||||
SeeAlso: AX=5301h,AX=5302h,AX=5304h
|
||||
--------p-155304-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE
|
||||
AX = 5304h
|
||||
BX = device ID of system BIOS (0000h)
|
||||
Return: CF clear if successful
|
||||
CF set on error
|
||||
AH = error code (03h,09h) (see #00473)
|
||||
SeeAlso: AX=5301h,AX=5302h,AX=5303h
|
||||
--------p-155305-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - CPU IDLE
|
||||
AX = 5305h
|
||||
Return: CF clear if successful (after system leaves idle state)
|
||||
CF set on error
|
||||
AH = error code (03h,0Bh) (see #00473)
|
||||
Notes: call when the system is idle and should be suspended until the next
|
||||
system event or interrupt
|
||||
should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
if an interrupt causes the system to resume normal processing, the
|
||||
interrupt may or may not have been handled when the BIOS returns
|
||||
from this call; thus, the caller should allow interrupts on return
|
||||
interrupt handlers may not retain control if the BIOS allows
|
||||
interrupts while in idle mode even if they are able to determine
|
||||
that they were called from idle mode
|
||||
the caller should issue this call continuously in a loop until it needs
|
||||
to perform some processing of its own
|
||||
SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h
|
||||
--------p-155306-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - CPU BUSY
|
||||
AX = 5306h
|
||||
Return: CF clear if successful
|
||||
CF set on error
|
||||
AH = error code (03h,0Bh) (see #00473)
|
||||
Notes: called to ensure that the system runs at full speed even on systems
|
||||
where the BIOS is unable to recognize increased activity (especially
|
||||
if interrupts are hooked by other programs and not chained to the
|
||||
BIOS)
|
||||
this call may be made even when the system is already running at full
|
||||
speed, but it will create unnecessary overhead
|
||||
should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
SeeAlso: AX=5305h
|
||||
--------p-155307-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - SET POWER STATE
|
||||
AX = 5307h
|
||||
BX = device ID (see #00474)
|
||||
CX = system state ID (see #00475)
|
||||
Return: CF clear if successful
|
||||
CF set on error
|
||||
AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473)
|
||||
Note: should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
SeeAlso: AX=530Ch
|
||||
|
||||
(Table 00474)
|
||||
Values for APM device IDs:
|
||||
0000h system BIOS
|
||||
0001h all devices for which the system BIOS manages power
|
||||
01xxh display (01FFh for all attached display devices)
|
||||
02xxh secondary storage (02FFh for all attached secondary storage devices)
|
||||
03xxh parallel ports (03FFh for all attached parallel ports)
|
||||
04xxh serial ports (04FFh for all attached serial ports)
|
||||
---APM v1.1+ ---
|
||||
05xxh network adapters (05FFh for all attached network adapters)
|
||||
06xxh PCMCIA sockets (06FFh for all)
|
||||
0700h-7FFFh reserved
|
||||
80xxh system battery devices (APM v1.2)
|
||||
8100h-DFFFh reserved
|
||||
Exxxh OEM-defined power device IDs
|
||||
F000h-FFFFh reserved
|
||||
|
||||
(Table 00475)
|
||||
Values for system state ID:
|
||||
0000h ready (not supported for device ID 0001h)
|
||||
0001h stand-by
|
||||
0002h suspend
|
||||
0003h off (not supported for device ID 0001h in APM v1.0)
|
||||
---APM v1.1---
|
||||
0004h last request processing notification (only for device ID 0001h)
|
||||
0005h last request rejected (only for device ID 0001h)
|
||||
0006h-001Fh reserved system states
|
||||
0020h-003Fh OEM-defined system states
|
||||
0040h-007Fh OEM-defined device states
|
||||
0080h-FFFFh reserved device states
|
||||
--------p-155307CX0001-----------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY
|
||||
AX = 5307h
|
||||
CX = 0001h
|
||||
BX = 0001h (device ID for all power-managed devices)
|
||||
Return: CF clear
|
||||
Notes: puts the entire system into stand-by mode; normally called in response
|
||||
to a System Stand-by Request notification after any necessary
|
||||
processing, but may also be invoked at the caller's discretion
|
||||
should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
the stand-by state is typically exited on an interrupt
|
||||
SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh
|
||||
--------p-155307CX0002-----------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM
|
||||
AX = 5307h
|
||||
CX = 0002h
|
||||
BX = 0001h (device ID for all power-managed devices)
|
||||
Return: after system is resumed
|
||||
CF clear
|
||||
Notes: puts the entire system into a low-power suspended state; normally
|
||||
called in response to a Suspend System Request notification after
|
||||
any necessary processing, but may also be invoked at the caller's
|
||||
discretion
|
||||
should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
the caller may need to update its date and time values because the
|
||||
system could have been suspended for a long period of time
|
||||
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh
|
||||
--------p-155307CX0003-----------------------
|
||||
INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM
|
||||
AX = 5307h
|
||||
CX = 0003h
|
||||
BX = 0001h (device ID for all power-managed devices)
|
||||
Return: after system is resumed
|
||||
CF clear
|
||||
Notes: if supported by the system's power supply, turns off the system power
|
||||
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh
|
||||
--------p-155308-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT
|
||||
AX = 5308h
|
||||
BX = device ID for all devices power-managed by APM
|
||||
0001h (APM v1.1+)
|
||||
FFFFh (APM v1.0)
|
||||
CX = new state
|
||||
0000h disabled
|
||||
0001h enabled
|
||||
Return: CF clear if successful
|
||||
CF set on error
|
||||
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473)
|
||||
Notes: when power management is disabled, the system BIOS will not
|
||||
automatically power down devices, enter stand-by or suspended mode,
|
||||
or perform any power-saving actions in response to AX=5305h calls
|
||||
should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
the APM BIOS should never be both disabled and disengaged at the same
|
||||
time
|
||||
SeeAlso: AX=5309h,AX=530Dh,AX=530Fh
|
||||
--------p-155309-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS
|
||||
AX = 5309h
|
||||
BX = device ID for all devices power-managed by APM
|
||||
0001h (APM v1.1)
|
||||
FFFFh (APM v1.0)
|
||||
Return: CF clear if successful
|
||||
CF set on error
|
||||
AH = error code (03h,09h,0Bh) (see #00473)
|
||||
Note: should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
SeeAlso: AX=5308h
|
||||
--------p-15530A-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS
|
||||
AX = 530Ah
|
||||
BX = device ID
|
||||
0001h all devices power-managed by APM
|
||||
80xxh specific battery unit number XXh (01h-FFh) (APM v1.2)
|
||||
Return: CF clear if successful
|
||||
BH = AC line status
|
||||
00h off-line
|
||||
01h on-line
|
||||
02h on backup power (APM v1.1)
|
||||
FFh unknown
|
||||
other reserved
|
||||
BL = battery status (see #00476)
|
||||
CH = battery flag (APM v1.1+) (see #00477)
|
||||
CL = remaining battery life, percentage
|
||||
00h-64h (0-100) percentage of full charge
|
||||
FFh unknown
|
||||
DX = remaining battery life, time (APM v1.1) (see #00478)
|
||||
---if specific battery unit specified---
|
||||
SI = number of battery units currently installed
|
||||
CF set on error
|
||||
AH = error code (09h,0Ah) (see #00473)
|
||||
Notes: should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
supported in real mode (INT 15) and both 16-bit and 32-bit protected
|
||||
mode
|
||||
|
||||
(Table 00476)
|
||||
Values for APM v1.0+ battery status:
|
||||
00h high
|
||||
01h low
|
||||
02h critical
|
||||
03h charging
|
||||
FFh unknown
|
||||
other reserved
|
||||
SeeAlso: #00477,#00478
|
||||
|
||||
Bitfields for APM v1.1+ battery flag:
|
||||
Bit(s) Description (Table 00477)
|
||||
0 high
|
||||
1 low
|
||||
2 critical
|
||||
3 charging
|
||||
4 selected battery not present (APM v1.2)
|
||||
5-6 reserved (0)
|
||||
7 no system battery
|
||||
Note: all bits set (FFh) if unknown
|
||||
SeeAlso: #00476,#00478
|
||||
|
||||
Bitfields for APM v1.1+ remaining battery life:
|
||||
Bit(s) Description (Table 00478)
|
||||
15 time units: 0=seconds, 1=minutes
|
||||
14-0 battery life in minutes or seconds
|
||||
Note: all bits set (FFFFh) if unknown
|
||||
SeeAlso: #00476,#00477
|
||||
--------p-15530B-----------------------------
|
||||
INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT
|
||||
AX = 530Bh
|
||||
Return: CF clear if successful
|
||||
BX = event code (see #00479)
|
||||
CX = event information (APM v1.2) if BX=0003h or BX=0004h
|
||||
bit 0: PCMCIA socket was powered down in suspend state
|
||||
CF set on error
|
||||
AH = error code (03h,0Bh,80h) (see #00473)
|
||||
Notes: although power management events are often asynchronous, notification
|
||||
will not be made until polled via this call to permit software to
|
||||
only receive event notification when it is prepared to process
|
||||
power management events; since these events are not very time-
|
||||
critical, it should be sufficient to poll once or twice per second
|
||||
the critical resume notification is made after the system resumes
|
||||
from an emergency suspension; normally, the system BIOS only notifies
|
||||
its partner that it wishes to suspend and relies on the partner to
|
||||
actually request the suspension, but no notification is made on an
|
||||
emergency suspension
|
||||
should not be called from within a hardware interrupt handler to avoid
|
||||
reentrance problems
|
||||
SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND"
|
||||
|
||||
(Table 00479)
|
||||
Values for APM event code:
|
||||
0001h system stand-by request
|
||||
0002h system suspend request
|
||||
0003h normal resume system notification
|
||||
0004h critical resume system notification
|
||||
0005h battery low notification
|
||||
---APM v1.1---
|
||||
0006h power status change notification
|
||||
0007h update time notification
|
||||
0008h critical system suspend notification
|
||||
0009h user system standby request notification
|
||||
000Ah user system suspend request notification
|
||||
000Bh system standby resume notification
|
||||
---APM v1.2---
|
||||
000Ch capabilities change notification (see AX=5310h)
|
||||
------
|
||||
000Dh-00FFh reserved system events
|
||||
01xxh reserved device events
|
||||
02xxh OEM-defined APM events
|
||||
0300h-FFFFh reserved
|
||||
--------p-15530C-----------------------------
|
||||
INT 15 - Advanced Power Management v1.1+ - GET POWER STATE
|
||||
AX = 530Ch
|
||||
BX = device ID (see #00474)
|
||||
Return: CF clear if successful
|
||||
CX = system state ID (see #00475)
|
||||
CF set on error
|
||||
AH = error code (01h,09h) (see #00473)
|
||||
SeeAlso: AX=5307h
|
||||
--------p-15530D-----------------------------
|
||||
INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT
|
||||
AX = 530Dh
|
||||
BX = device ID (see #00474)
|
||||
CX = function
|
||||
0000h disable power management
|
||||
0001h enable power management
|
||||
Return: CF clear if successful
|
||||
CF set on error
|
||||
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473)
|
||||
Desc: specify whether automatic power management should be active for a
|
||||
given device
|
||||
SeeAlso: AX=5308h,AX=530Fh
|
||||
--------p-15530E-----------------------------
|
||||
INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION
|
||||
AX = 530Eh
|
||||
BX = device ID of system BIOS (0000h)
|
||||
CH = APM driver major version (BCD)
|
||||
CL = APM driver minor version (BCD) (02h for APM v1.2)
|
||||
Return: CF clear if successful
|
||||
AH = APM connection major version (BCD)
|
||||
AL = APM connection minor version (BCD)
|
||||
CF set on error
|
||||
AH = error code (03h,09h,0Bh) (see #00473)
|
||||
SeeAlso: AX=5300h,AX=5303h
|
||||
--------p-15530F-----------------------------
|
||||
INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT
|
||||
AX = 530Fh
|
||||
BX = device ID (see #00474)
|
||||
CX = function
|
||||
0000h disengage power management
|
||||
0001h engage power management
|
||||
Return: CF clear if successful
|
||||
CF set on error
|
||||
AH = error code (01h,09h) (see #00473)
|
||||
Notes: unlike AX=5308h, this call does not affect the functioning of the APM
|
||||
BIOS
|
||||
when cooperative power management is disengaged, the APM BIOS performs
|
||||
automatic power management of the system or device
|
||||
SeeAlso: AX=5308h,AX=530Dh
|
||||
--------p-155310-----------------------------
|
||||
INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES
|
||||
AX = 5310h
|
||||
BX = device ID (see #00474)
|
||||
0000h (APM BIOS)
|
||||
other reserved
|
||||
Return: CF clear if successful
|
||||
BL = number of battery units supported (00h if no system batteries)
|
||||
CX = capabilities flags (see #00480)
|
||||
CF set on error
|
||||
AH = error code (01h,09h,86h) (see #00473)
|
||||
Notes: this function is supported via the INT 15, 16-bit protected mode, and
|
||||
32-bit protected mode interfaces; it does not require that a
|
||||
connection be established prior to use
|
||||
this function will return the capabilities currently in effect, not
|
||||
any new settings which have been made but do not take effect until
|
||||
a system restart
|
||||
SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h
|
||||
|
||||
Bitfields for APM v1.2 capabilities flags:
|
||||
Bit(s) Description (Table 00480)
|
||||
15-8 reserved
|
||||
7 PCMCIA Ring Indicator will wake up system from suspend mode
|
||||
6 PCMCIA Ring Indicator will wake up system from standby mode
|
||||
5 Resume on Ring Indicator will wake up system from suspend mode
|
||||
4 Resume on Ring Indicator will wake up system from standby mode
|
||||
3 resume timer will wake up system from suspend mode
|
||||
2 resume timer will wake up system from standby mode
|
||||
1 can enter global suspend state
|
||||
0 can enter global standby state
|
||||
--------p-155311-----------------------------
|
||||
INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER
|
||||
AX = 5311h
|
||||
BX = device ID (see #00474)
|
||||
0000h (APM BIOS)
|
||||
other reserved
|
||||
CL = function
|
||||
00h disable Resume Timer
|
||||
01h get Resume Timer
|
||||
02h set Resume Timer
|
||||
CH = resume time, seconds (BCD)
|
||||
DL = resume time, minutes (BCD)
|
||||
DH = resume time, hours (BCD)
|
||||
SI = resume date (BCD), high byte = month, low byte = day
|
||||
DI = resume date, year (BCD)
|
||||
Return: CF clear if successful
|
||||
---if getting timer---
|
||||
CH = resume time, seconds (BCD)
|
||||
DL = resume time, minutes (BCD)
|
||||
DH = resume time, hours (BCD)
|
||||
SI = resume date (BCD), high byte = month, low byte = day
|
||||
DI = resume date, year (BCD)
|
||||
CF set on error
|
||||
AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473)
|
||||
Notes: this function is supported via the INT 15, 16-bit protected mode, and
|
||||
32-bit protected mode interfaces
|
||||
SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h
|
||||
--------p-155312-----------------------------
|
||||
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING
|
||||
AX = 5312h
|
||||
BX = device ID (see #00474)
|
||||
0000h (APM BIOS)
|
||||
other reserved
|
||||
CL = function
|
||||
00h disable Resume on Ring Indicator
|
||||
01h enable Resume on Ring Indicator
|
||||
02h get Resume on Ring Indicator status
|
||||
Return: CF clear if successful
|
||||
CX = resume status (0000h disabled, 0001h enabled)
|
||||
CF set on error
|
||||
AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473)
|
||||
Notes: this function is supported via the INT 15, 16-bit protected mode, and
|
||||
32-bit protected mode interfaces
|
||||
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h
|
||||
--------p-155313-----------------------------
|
||||
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS
|
||||
AX = 5313h
|
||||
BX = device ID (see #00474)
|
||||
0000h (APM BIOS)
|
||||
other reserved
|
||||
CL = function
|
||||
00h disable timer-based requests
|
||||
01h enable timer-based requests
|
||||
02h get timer-based requests status
|
||||
Return: CF clear if successful
|
||||
CX = timer-based requests status (0000h disabled, 0001h enabled)
|
||||
CF set on error
|
||||
AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473)
|
||||
Notes: this function is supported via the INT 15, 16-bit protected mode, and
|
||||
32-bit protected mode interfaces
|
||||
some BIOSes set AH on return even when successful
|
||||
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h
|
88
kernel/branches/kolibri-cfg/docs/loader_doc.txt
Normal file
88
kernel/branches/kolibri-cfg/docs/loader_doc.txt
Normal file
@ -0,0 +1,88 @@
|
||||
; (english text below)
|
||||
|
||||
;------------------------------------------
|
||||
; Èíòåðôåéñ ñîõðàíåíèÿ ïàðàìåòðîâ
|
||||
;------------------------------------------
|
||||
Åñëè ïðè ïåðåäà÷å óïðàâëåíèÿ ÿäðó çàãðóç÷èê óñòàíàâëèâàåò AX='KL',
|
||||
òî â DS:SI ÿäðî îæèäàåò äàëüíåãî óêàçàòåëÿ íà ñëåäóþùóþ ñòðóêòóðó:
|
||||
db âåðñèÿ ñòðóêòóðû, äîëæíà áûòü 1
|
||||
dw ôëàãè:
|
||||
áèò 0 óñòàíîâëåí = ïðèñóòñòâóåò îáðàç ðàìäèñêà â ïàìÿòè
|
||||
dd äàëüíèé óêàçàòåëü íà ïðîöåäóðó ñîõðàíåíèÿ ïàðàìåòðîâ
|
||||
ìîæåò áûòü 0, åñëè çàãðóç÷èê íå ïîääåðæèâàåò
|
||||
Ïðîöåäóðà ñîõðàíåíèÿ ïàðàìåòðîâ äîëæíà çàïèñàòü ïåðâûé ñåêòîð ÿäðà
|
||||
kernel.mnt íàçàä íà òî ìåñòî, îòêóäà îíà åãî ñ÷èòàëà; âîçâðàò èç
|
||||
ïðîöåäóðû îñóùåñòâëÿåòñÿ ïî retf.
|
||||
|
||||
;------------------------------------------
|
||||
; Óêàçàíèå çàãðóç÷èêîì ñèñòåìíîãî êàòàëîãà
|
||||
;------------------------------------------
|
||||
Ïåðåä ïåðåäà÷åé óïðàâëåíèÿ ÿäðó ìîãóò áûòü óñòàíîâëåíû ñëåäóþùèå ðåãèñòðû:
|
||||
CX='HA'
|
||||
DX='RD'
|
||||
Ýòî óêàçûâàåò íà òî, ÷òî ðåãèñòð BX óêàçûâàåò íà ñèñòåìíûé ðàçäåë. Êàòàëîã /kolibri/ íà
|
||||
ýòîì ðàçäåëå ÿâëÿåòñÿ ñèñòåìíûì, ê íåìó ìîæíî îáðàùàòüñÿ êàê ê /sys/
|
||||
|
||||
Âîçìîæíûå çíà÷åíèÿ ðåãèñòðà BL (óêàçûâàåò íà óñòðîéñòâî):
|
||||
'a' - Primary Master
|
||||
'b' - Primary Slave
|
||||
'c' - Secondary Master
|
||||
'd' - Secondary Slave
|
||||
'r' - RAM äèñê
|
||||
'm' - Ïðèâîäû CD-ROM
|
||||
|
||||
Âîçìîæíûå çíà÷åíèÿ ðåãèñòðà BH (óêàçûâàåò íà ðàçäåë):
|
||||
äëÿ BL='a','b','c','d','r' - óêàçûâàåò íà ðàçäåë, ãäå ðàñïîëîæåí ñèñòåìíûé êàòàëîã
|
||||
äëÿ BL='m',óêàçûâàåò íà íîìåð ôèçè÷åñêîãî óñòðîéñòâà, ñ êîòîðîãî íàäî íà÷èíàòü ïîèñê ñèñòåìíîãî êàòàëîãà.
|
||||
|
||||
ïðèìåðû çíà÷åíèé ðåãèñòðà BX:
|
||||
'a1' - /hd0/1/
|
||||
'a2' - /hd0/2/
|
||||
'b1' - /hd1/1/
|
||||
'd4' - /hd3/4/
|
||||
'm0' - ïîèñê ïî ñèäþêàì êàòàëîãà kolibri
|
||||
'r1' - /rd/1/
|
||||
|
||||
|
||||
;------------------------------------------
|
||||
; Interface for saving boot-screen settings
|
||||
;------------------------------------------
|
||||
If a loader sets AX='KL' when transferring control to the kernel,
|
||||
the kernel expects in DS:SI far pointer to the following structure:
|
||||
db structure version, must be 1
|
||||
dw flags
|
||||
bit 0 set = ramdisk image in memory is present
|
||||
dd far pointer to save settings procedure
|
||||
may be 0 if such procedure is not supported by loader
|
||||
Procedure for saving settings must write the first sector of the kernel
|
||||
kernel.mnt back to the place, from where it has been read; return from
|
||||
this procedure must be with retf.
|
||||
|
||||
;------------------------------------------
|
||||
; System directory information from loader
|
||||
;------------------------------------------
|
||||
Before transfer of control to the kernel following registers can be set:
|
||||
CX = 'HA'
|
||||
DX = 'RD'
|
||||
This indicates that the register BX identifies system partition. The folder /kolibri/ in
|
||||
this partition is system folder, it can be referenced as /sys/
|
||||
|
||||
Possible values for register BL (indicates the device):
|
||||
'a' - Primary Master
|
||||
'b' - Primary Slave
|
||||
'c' - Secondary Master
|
||||
'd' - Secondary Slave
|
||||
'r' - RAM disc
|
||||
'm' - ROM drives
|
||||
|
||||
Possible values for register BH (indicates section):
|
||||
for BL = 'a', 'b', 'c', 'd', 'r' to denote partition where the system folder
|
||||
for BL = 'm', indicates the number of physical devices, which must begin a systematic search directory.
|
||||
|
||||
Examples of register BX:
|
||||
'a1' - /hd0/1/
|
||||
'a2' - /hd0/2/
|
||||
'b1' - /hd1/1/
|
||||
'd4' - /hd3/4/
|
||||
'm0' - search directory 'kolibri' by all CD-ROMs
|
||||
'r1' - /rd/1/
|
4573
kernel/branches/kolibri-cfg/docs/sysfuncr.txt
Normal file
4573
kernel/branches/kolibri-cfg/docs/sysfuncr.txt
Normal file
File diff suppressed because it is too large
Load Diff
4528
kernel/branches/kolibri-cfg/docs/sysfuncs.txt
Normal file
4528
kernel/branches/kolibri-cfg/docs/sysfuncs.txt
Normal file
File diff suppressed because it is too large
Load Diff
326
kernel/branches/kolibri-cfg/drivers/codec.inc
Normal file
326
kernel/branches/kolibri-cfg/drivers/codec.inc
Normal file
@ -0,0 +1,326 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
AD_LOSEL equ BIT5
|
||||
AD_HPSEL equ BIT10
|
||||
|
||||
align 4
|
||||
proc detect_codec
|
||||
locals
|
||||
codec_id dd ?
|
||||
endl
|
||||
|
||||
stdcall codec_read, dword 0x7C
|
||||
shl eax, 16
|
||||
mov [codec_id], eax
|
||||
|
||||
stdcall codec_read, dword 0x7E
|
||||
or eax, [codec_id]
|
||||
|
||||
mov [codec.chip_id], eax
|
||||
and eax, 0xFFFFFF00
|
||||
|
||||
mov edi, codecs
|
||||
@@:
|
||||
mov ebx, [edi]
|
||||
test ebx, ebx
|
||||
jz .unknown
|
||||
|
||||
cmp eax, ebx
|
||||
jne .next
|
||||
mov eax, [edi+4]
|
||||
mov [codec.ac_vendor_ids], eax
|
||||
mov esi, eax
|
||||
call SysMsgBoardStr
|
||||
stdcall detect_chip, [edi+8]
|
||||
|
||||
ret
|
||||
.next:
|
||||
add edi, 12
|
||||
jmp @B
|
||||
.unknown:
|
||||
mov [codec.ac_vendor_ids], ac_unknown
|
||||
mov [codec.chip_ids], chip_unknown
|
||||
|
||||
mov esi, chip_unknown
|
||||
call SysMsgBoardStr
|
||||
mov eax, [codec.chip_id]
|
||||
call dword2str
|
||||
call SysMsgBoardStr
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc detect_chip stdcall, chip_tab:dword
|
||||
|
||||
mov eax, [codec.chip_id]
|
||||
and eax, 0xFF
|
||||
|
||||
mov edi, [chip_tab]
|
||||
@@:
|
||||
mov ebx, [edi]
|
||||
cmp ebx, 0xFF
|
||||
je .unknown
|
||||
|
||||
cmp eax,ebx
|
||||
jne .next
|
||||
mov eax, [edi+4]
|
||||
mov [codec.chip_ids], eax
|
||||
mov esi, eax
|
||||
call SysMsgBoardStr
|
||||
ret
|
||||
.next:
|
||||
add edi, 8
|
||||
jmp @b
|
||||
.unknown:
|
||||
mov [codec.chip_ids], chip_unknown
|
||||
mov esi, chip_unknown
|
||||
call SysMsgBoardStr
|
||||
mov eax, [codec.chip_id]
|
||||
call dword2str
|
||||
call SysMsgBoardStr
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc setup_codec
|
||||
|
||||
xor eax, eax
|
||||
stdcall codec_write, dword CODEC_AUX_VOL
|
||||
|
||||
mov eax, 0x0B0B
|
||||
stdcall codec_write, dword CODEC_MASTER_VOL_REG
|
||||
|
||||
mov ax, 0x08
|
||||
stdcall codec_write, dword 0x0C
|
||||
|
||||
mov ax, 0x0808
|
||||
stdcall codec_write, dword CODEC_PCM_OUT_REG
|
||||
|
||||
mov ax, 0x0808
|
||||
stdcall codec_write, dword 0x10
|
||||
|
||||
mov ax, 0x0808
|
||||
stdcall codec_write, dword 0x12
|
||||
|
||||
mov ax, 0x0808
|
||||
stdcall codec_write, dword 0x16
|
||||
|
||||
|
||||
stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG
|
||||
and eax, 0FFFFh - BIT1 ; clear DRA (BIT1)
|
||||
or eax, BIT0 ; set VRA (BIT0)
|
||||
stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG
|
||||
|
||||
stdcall set_sample_rate, dword 48000
|
||||
|
||||
.init_error:
|
||||
xor eax, eax ; exit with error
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
; param
|
||||
; eax= volume -10000 - 0 for both channels
|
||||
|
||||
align 4
|
||||
set_master_vol:
|
||||
cmp eax, 0
|
||||
jl @F
|
||||
xor eax, eax
|
||||
jmp .set
|
||||
@@:
|
||||
cmp eax, -9450
|
||||
jg .set
|
||||
mov eax, -9450 ;clamp into 6 bits
|
||||
.set:
|
||||
cdq
|
||||
mov ebx, -150
|
||||
idiv ebx
|
||||
mov ah, al
|
||||
stdcall codec_write, dword CODEC_MASTER_VOL_REG
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
align 4
|
||||
proc get_master_vol stdcall, pvol:dword
|
||||
|
||||
stdcall codec_read, dword CODEC_MASTER_VOL_REG
|
||||
and eax, 0x3F
|
||||
imul eax, -150
|
||||
mov ebx, [pvol]
|
||||
mov [ebx], eax
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc set_sample_rate stdcall, rate:dword
|
||||
mov eax, [rate]
|
||||
stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG
|
||||
ret
|
||||
endp
|
||||
|
||||
patch_AD:
|
||||
stdcall codec_read, 0x76
|
||||
or ax, BIT5+BIT10
|
||||
stdcall codec_write, 0x76
|
||||
ret
|
||||
|
||||
|
||||
align 16
|
||||
ac_unknown db 'unknown manufacturer',13,10,0
|
||||
ac_Realtek db 'Realtek Semiconductor',13,10,0
|
||||
ac_Analog db 'Analog Devices',13,10,0
|
||||
ac_CMedia db 'C-Media Electronics',13,10,0
|
||||
ac_Cirrus db 'Cirrus Logic',13,10,0
|
||||
ac_Wolfson db 'Wolfson Microelectronics',13,10,0
|
||||
ac_VIA db 'VIA Technologies',13,10,0
|
||||
ac_SigmaTel db 'SigmaTel',13,10,0
|
||||
ac_eMicro db 'eMicro',13,10,0
|
||||
|
||||
chip_unknown db 'unknown codec id ', 0
|
||||
|
||||
CHIP_ANALOG equ 0x41445300
|
||||
CHIP_REALTEK equ 0x414C4700
|
||||
CHIP_CMEDIA equ 0x434D4900
|
||||
CHIP_CIRRUS equ 0x43525900
|
||||
CHIP_WOLFSON equ 0x574D4C00
|
||||
CHIP_VIA equ 0x56494100
|
||||
CHIP_SIGMATEL equ 0x83847600
|
||||
CHIP_EMICRO equ 0x454D4300
|
||||
|
||||
align 16
|
||||
codecs dd CHIP_ANALOG, ac_Analog, chips_Analog
|
||||
dd CHIP_CMEDIA, ac_CMedia, chips_CMedia
|
||||
dd CHIP_REALTEK,ac_Realtek, chips_Realtek
|
||||
dd CHIP_CIRRUS, ac_Cirrus, chips_Cirrus
|
||||
dd CHIP_WOLFSON,ac_Wolfson, chips_Wolfson
|
||||
dd CHIP_VIA, ac_VIA, chips_VIA
|
||||
dd CHIP_SIGMATEL, ac_SigmaTel, chips_SigmaTel
|
||||
dd CHIP_EMICRO, ac_eMicro, chips_eMicro
|
||||
dd 0
|
||||
|
||||
align 16
|
||||
chips_Analog dd 0x03, chip_AD1819
|
||||
dd 0x40, chip_AD1881
|
||||
dd 0x48, chip_AD1881A
|
||||
dd 0x60, chip_AD1884
|
||||
dd 0x61, chip_AD1886
|
||||
dd 0x62, chip_AD1887
|
||||
dd 0x63, chip_AD1886A
|
||||
dd 0x70, chip_AD1980
|
||||
dd 0x72, chip_AD1981A
|
||||
dd 0x74, chip_AD1981B
|
||||
dd 0x75, chip_AD1985
|
||||
dd 0xFF
|
||||
|
||||
chips_Realtek:
|
||||
dd 0x10, chip_ALC201a
|
||||
dd 0x20, chip_ALC650
|
||||
dd 0x21, chip_ALC650D
|
||||
dd 0x22, chip_ALC650E
|
||||
dd 0x23, chip_ALC650F
|
||||
dd 0x60, chip_ALC655
|
||||
dd 0x80, chip_ALC658
|
||||
dd 0x81, chip_ALC658D
|
||||
dd 0x90, chip_ALC850
|
||||
dd 0xFF
|
||||
|
||||
chips_CMedia dd 0x41, chip_CM9738
|
||||
dd 0x61, chip_CM9739
|
||||
dd 0x69, chip_CM9780
|
||||
dd 0x78, chip_CM9761
|
||||
dd 0x82, chip_CM9761
|
||||
dd 0x83, chip_CM9761
|
||||
dd 0xFF
|
||||
|
||||
chips_Cirrus dd 0x00, chip_CS4297
|
||||
dd 0x10, chip_CS4297A
|
||||
dd 0x20, chip_CS4298
|
||||
dd 0x28, chip_CS4294
|
||||
dd 0x30, chip_CS4299
|
||||
dd 0x34, chip_CS4299D
|
||||
dd 0x48, chip_CS4201
|
||||
dd 0x58, chip_CS4205
|
||||
dd 0x60, chip_CS4291
|
||||
dd 0x70, chip_CS4202
|
||||
dd 0xFF
|
||||
|
||||
chips_Wolfson dd 0x00, chip_WM9700
|
||||
dd 0x03, chip_WM9703
|
||||
dd 0x04, chip_WM9704
|
||||
dd 0xFF
|
||||
|
||||
chips_VIA dd 0x61, chip_VIA1612A
|
||||
dd 0xFF
|
||||
|
||||
chips_SigmaTel dd 0x58, chip_STAC9758
|
||||
dd 0xFF
|
||||
|
||||
chips_eMicro dd 0x28, chip_EM28028
|
||||
dd 0xFF
|
||||
|
||||
align 16
|
||||
;Analog Devices
|
||||
chip_AD1819 db 'AD1819 ',0dh,0ah,00h
|
||||
chip_AD1881 db 'AD1881 ',0dh,0ah,00h
|
||||
chip_AD1881A db 'AD1881A',0dh,0ah,00h
|
||||
chip_AD1884 db 'AD1885 ',0dh,0ah,00h
|
||||
chip_AD1885 db 'AD1885 ',0dh,0ah,00h
|
||||
chip_AD1886 db 'AD1886 ',0dh,0ah,00h
|
||||
chip_AD1886A db 'AD1886A',0dh,0ah,00h
|
||||
chip_AD1887 db 'AD1887 ',0dh,0ah,00h
|
||||
chip_AD1980 db 'AD1980 ',0dh,0ah,00h
|
||||
chip_AD1981A db 'AD1981A',0dh,0ah,00h
|
||||
chip_AD1981B db 'AD1981B',0dh,0ah,00h
|
||||
chip_AD1985 db 'AD1985 ',0dh,0ah,00h
|
||||
|
||||
;Realtek
|
||||
chip_ALC201a db 'ALC201a',0dh,0ah,00h
|
||||
chip_ALC650 db 'ALC650 ',0dh,0ah,00h
|
||||
chip_ALC650D db 'ALC650D',0dh,0ah,00h
|
||||
chip_ALC650E db 'ALC650E',0dh,0ah,00h
|
||||
chip_ALC650F db 'ALC650F',0dh,0ah,00h
|
||||
chip_ALC655 db 'ALC655 ',0dh,0ah,00h
|
||||
chip_ALC658 db 'ALC658 ',0dh,0ah,00h
|
||||
chip_ALC658D db 'ALC658D',0dh,0ah,00h
|
||||
chip_ALC850 db 'ALC850 ',0dh,0ah,00h
|
||||
|
||||
;CMedia
|
||||
chip_CM9738 db 'CMI9738', 0dh,0ah,0
|
||||
chip_CM9739 db 'CMI9739', 0dh,0ah,0
|
||||
chip_CM9780 db 'CMI9780', 0dh,0ah,0
|
||||
chip_CM9761 db 'CMI9761', 0dh,0ah,0
|
||||
|
||||
;Cirrus
|
||||
chip_CS4297 db 'CS4297',13,10,0
|
||||
chip_CS4297A db 'CS4297A',13,10,0
|
||||
chip_CS4298 db 'CS4298',13,10,0
|
||||
chip_CS4294 db 'CS4294',13,10,0
|
||||
chip_CS4299 db 'CS4299',13,10,0
|
||||
chip_CS4299D db 'CS4299D',13,10,0
|
||||
chip_CS4201 db 'CS4201',13,10,0
|
||||
chip_CS4205 db 'CS4205',13,10,0
|
||||
chip_CS4291 db 'CS4291',13,10,0
|
||||
chip_CS4202 db 'CS4202',13,10,0
|
||||
|
||||
;Wolfson
|
||||
chip_WM9700 db 'WM9704',13,10,0
|
||||
chip_WM9703 db 'WM9703/9704',13,10,0
|
||||
chip_WM9704 db 'WM9704 (quad)',13,10,0
|
||||
|
||||
;VIA
|
||||
chip_VIA1612A db 'VIA1612A',13,10,0
|
||||
|
||||
;SigmaTel
|
||||
chip_STAC9758 db 'STAC9758,59',13,10,0
|
||||
|
||||
;eMicro
|
||||
chip_EM28028 db 'EM28028',13,10,0
|
||||
|
382
kernel/branches/kolibri-cfg/drivers/com_mouse.asm
Normal file
382
kernel/branches/kolibri-cfg/drivers/com_mouse.asm
Normal file
@ -0,0 +1,382 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; Includes source code by Kulakov Vladimir Gennadievich. ;;
|
||||
;; Modified by Mario79 and Rus. ;;
|
||||
;; 02.12.2009 <Lrz> ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;driver sceletone
|
||||
|
||||
format MS COFF
|
||||
|
||||
DEBUG equ 0
|
||||
|
||||
include 'proc32.inc'
|
||||
include 'imports.inc'
|
||||
|
||||
API_VERSION equ 5 ;debug
|
||||
|
||||
struc IOCTL
|
||||
{ .handle dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
IOCTL IOCTL
|
||||
end virtual
|
||||
|
||||
public START
|
||||
public version
|
||||
|
||||
|
||||
DRV_ENTRY equ 1
|
||||
DRV_EXIT equ -1
|
||||
STRIDE equ 4 ;size of row in devices table
|
||||
|
||||
SRV_GETVERSION equ 0
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
proc START stdcall, state:dword
|
||||
|
||||
cmp [state], 1
|
||||
jne .exit
|
||||
.entry:
|
||||
;Detect_COM_Mouse:
|
||||
if DEBUG
|
||||
mov esi, msgInit
|
||||
call Boot_Log
|
||||
end if
|
||||
mov bx, 0x3f8
|
||||
call MSMouseSearch
|
||||
cmp AL,'M'
|
||||
jne @f
|
||||
;mov [com1_mouse_detected],1
|
||||
;mov [irq_owner+4*4], 1 ; IRQ4 owner is System
|
||||
|
||||
mov dx, bx
|
||||
inc dx ; 0x3f8 + 1
|
||||
mov al, 1
|
||||
out dx, al
|
||||
|
||||
stdcall AttachIntHandler, 4, irq4_handler, dword 0
|
||||
if DEBUG
|
||||
test eax, eax
|
||||
jne .label1
|
||||
|
||||
mov esi, msg_error_attach_int_handler
|
||||
call Boot_Log
|
||||
end if
|
||||
.label1:
|
||||
; mov eax, 0
|
||||
; mov ebx, 0x3F8
|
||||
; mov ecx, 0x3FF
|
||||
xor ebx,ebx
|
||||
mov ecx, 0x3F8
|
||||
mov edx, 0x3FF
|
||||
call ReservePortArea
|
||||
|
||||
if DEBUG
|
||||
cmp eax, 1
|
||||
jne .go
|
||||
|
||||
mov esi, msg_error_reserve_ports
|
||||
call Boot_Log
|
||||
|
||||
.go:
|
||||
mov esi,boot_setmouse_type
|
||||
call Boot_Log
|
||||
end if
|
||||
@@:
|
||||
mov bx, 0x2f8
|
||||
call MSMouseSearch
|
||||
cmp AL,'M'
|
||||
jne .resume
|
||||
;mov [com2_mouse_detected],1
|
||||
;mov [irq_owner+3*4], 1 ; IRQ3 owner is System
|
||||
|
||||
stdcall AttachIntHandler, 3, irq3_handler, dword 0
|
||||
|
||||
; mov eax, 0
|
||||
; mov ebx, 0x2F8
|
||||
; mov ecx, 0x3F8
|
||||
xor ebx,ebx
|
||||
mov ecx, 0x2F8
|
||||
mov edx, 0x3F8
|
||||
|
||||
call ReservePortArea
|
||||
if DEBUG
|
||||
cmp eax, 1
|
||||
jne @f
|
||||
|
||||
mov esi, msg_error_reserve_ports
|
||||
call Boot_Log
|
||||
@@:
|
||||
|
||||
mov esi,boot_setmouse_type + 22
|
||||
call Boot_Log
|
||||
end if
|
||||
.resume:
|
||||
|
||||
stdcall RegService, my_service, service_proc
|
||||
if DEBUG
|
||||
test eax, eax
|
||||
jne @f
|
||||
|
||||
mov esi, msg_exit
|
||||
call Boot_Log
|
||||
end if
|
||||
@@:
|
||||
ret
|
||||
.fail:
|
||||
.exit:
|
||||
if DEBUG
|
||||
mov esi, msg_exit
|
||||
call Boot_Log
|
||||
end if
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
handle equ IOCTL.handle
|
||||
io_code equ IOCTL.io_code
|
||||
input equ IOCTL.input
|
||||
inp_size equ IOCTL.inp_size
|
||||
output equ IOCTL.output
|
||||
out_size equ IOCTL.out_size
|
||||
|
||||
align 4
|
||||
proc service_proc stdcall, ioctl:dword
|
||||
|
||||
mov ebx, [ioctl]
|
||||
mov eax, [ebx+io_code]
|
||||
cmp eax, SRV_GETVERSION
|
||||
jne @F
|
||||
|
||||
mov eax, [ebx+output]
|
||||
cmp [ebx+out_size], 4
|
||||
jne .fail
|
||||
mov [eax], dword API_VERSION
|
||||
xor eax, eax
|
||||
ret
|
||||
@@:
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
MSMouseSearch:
|
||||
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ
|
||||
MouseSearch:
|
||||
; Óñòàíàâëèâàåì ñêîðîñòü
|
||||
; ïðèåìà/ïåðåäà÷è 1200 áîä
|
||||
; in bx COM Port Base Address
|
||||
mov DX, bx
|
||||
add DX,3
|
||||
in AL,DX
|
||||
or AL,80h ;óñòàíîâèòü áèò DLAB
|
||||
out DX,AL
|
||||
mov DX, bx
|
||||
mov AL,60h ;1200 áîä
|
||||
out DX,AL
|
||||
inc DX
|
||||
mov AL,0
|
||||
out DX,AL
|
||||
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò,
|
||||
; ÷åòíîñòü íå êîíòðîëèðîâàòü
|
||||
mov DX, bx
|
||||
add DX,3
|
||||
mov AL,00000010b
|
||||
out DX,AL
|
||||
; Çàïðåòèòü âñå ïðåðûâàíè
|
||||
mov dx, bx
|
||||
inc dx
|
||||
mov AL,0
|
||||
out DX,AL
|
||||
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñ
|
||||
; ìûøüþ òèïà MSMouse
|
||||
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíè
|
||||
mov DX, bx
|
||||
add EDX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì
|
||||
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2
|
||||
out DX,AL
|
||||
; Îæèäàòü 5 "òèêîâ" (0,2 ñ)
|
||||
mov ecx, 0xFFFF
|
||||
loop $
|
||||
; Âêëþ÷èòü ïèòàíèå ìûøè
|
||||
mov al, 1
|
||||
out dx, al
|
||||
mov ecx, 0xFFFF
|
||||
loop $
|
||||
; Î÷èñòèòü ðåãèñòð äàííûõ
|
||||
mov dx, bx
|
||||
in AL,DX
|
||||
add edx, 4
|
||||
mov AL, 1011b ;óñòàíîâèòü DTR è RTS è OUT2
|
||||
out DX,AL
|
||||
mov ecx, 0x1FFFF
|
||||
; Öèêë îïðîñà ïîðòà
|
||||
WaitData:
|
||||
; Îæèäàòü åùå 10 "òèêîâ"
|
||||
dec ecx
|
||||
; cmp ecx,0
|
||||
jz NoMouse
|
||||
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà
|
||||
mov DX, bx
|
||||
add DX,5
|
||||
in AL,DX
|
||||
test AL,1 ;Äàííûå ãîòîâû?
|
||||
jz WaitData
|
||||
; Ââåñòè äàííûå
|
||||
mov DX, bx
|
||||
in AL,DX
|
||||
NoMouse:
|
||||
ret
|
||||
|
||||
align 4
|
||||
irq3_handler:
|
||||
mov dx, 0x2f8
|
||||
mov esi, com2_mouse
|
||||
jmp irq_handler
|
||||
|
||||
align 4
|
||||
irq4_handler:
|
||||
mov dx, 0x3f8
|
||||
mov esi, com1_mouse
|
||||
|
||||
irq_handler:
|
||||
|
||||
; in: esi -> COM_MOUSE_DATA struc, dx = base port (xF8h)
|
||||
add edx, 5 ; xFDh
|
||||
in al, dx
|
||||
test al, 1 ; Äàííûå ãîòîâû?
|
||||
jz .Error
|
||||
; Ââåñòè äàííûå
|
||||
sub edx, 5
|
||||
in al, dx
|
||||
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò
|
||||
and al, 01111111b
|
||||
|
||||
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà
|
||||
cmp [esi+COM_MOUSE_DATA.MouseByteNumber], 2
|
||||
ja .Error
|
||||
jz .ThirdByte
|
||||
jp .SecondByte
|
||||
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ
|
||||
.FirstByte:
|
||||
test al, 1000000b ; Ïåðâûé áàéò ïîñûëêè?
|
||||
jz .Error
|
||||
mov [esi+COM_MOUSE_DATA.FirstByte], al
|
||||
inc [esi+COM_MOUSE_DATA.MouseByteNumber]
|
||||
jmp .EndMouseInterrupt
|
||||
; Ñîõðàíèòü âòîðîé áàéò äàííûõ
|
||||
.SecondByte:
|
||||
test al, 1000000b
|
||||
jnz .Error
|
||||
mov [esi+COM_MOUSE_DATA.SecondByte], al
|
||||
inc [esi+COM_MOUSE_DATA.MouseByteNumber]
|
||||
jmp .EndMouseInterrupt
|
||||
; Ñîõðàíèòü òðåòèé áàéò äàííûõ
|
||||
.ThirdByte:
|
||||
test al, 1000000b
|
||||
jnz .Error
|
||||
mov [esi+COM_MOUSE_DATA.ThirdByte], al
|
||||
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0
|
||||
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ).
|
||||
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè
|
||||
mov al, [esi+COM_MOUSE_DATA.FirstByte]
|
||||
mov ah, al
|
||||
shr al, 3
|
||||
and al, 2
|
||||
shr ah, 5
|
||||
and ah, 1
|
||||
add al, ah
|
||||
movzx eax, al
|
||||
mov [BTN_DOWN], eax
|
||||
|
||||
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X
|
||||
mov al, [esi+COM_MOUSE_DATA.FirstByte]
|
||||
shl al, 6
|
||||
or al, [esi+COM_MOUSE_DATA.SecondByte]
|
||||
|
||||
cbw
|
||||
movzx eax, ax
|
||||
mov [MOUSE_X], eax
|
||||
|
||||
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y
|
||||
mov al, [esi+COM_MOUSE_DATA.FirstByte]
|
||||
and al, 00001100b
|
||||
shl al, 4
|
||||
or al, [esi+COM_MOUSE_DATA.ThirdByte]
|
||||
|
||||
cbw
|
||||
movzx eax, ax
|
||||
neg eax
|
||||
mov [MOUSE_Y], eax
|
||||
|
||||
stdcall SetMouseData, [BTN_DOWN], [MOUSE_X], [MOUSE_Y], 0, 0
|
||||
|
||||
jmp .EndMouseInterrupt
|
||||
|
||||
.Error:
|
||||
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò
|
||||
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ
|
||||
|
||||
mov [esi+COM_MOUSE_DATA.MouseByteNumber],0
|
||||
.EndMouseInterrupt:
|
||||
|
||||
ret
|
||||
|
||||
;all initialized data place here
|
||||
|
||||
align 4
|
||||
|
||||
struc COM_MOUSE_DATA {
|
||||
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà
|
||||
.MouseByteNumber db ?
|
||||
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ
|
||||
.FirstByte db ?
|
||||
.SecondByte db ?
|
||||
.ThirdByte db ?
|
||||
;.timer_ticks_com dd ?
|
||||
}
|
||||
virtual at 0
|
||||
COM_MOUSE_DATA COM_MOUSE_DATA
|
||||
end virtual
|
||||
|
||||
com1_mouse COM_MOUSE_DATA
|
||||
com2_mouse COM_MOUSE_DATA
|
||||
|
||||
MOUSE_X dd 0
|
||||
MOUSE_Y dd 0
|
||||
BTN_DOWN dd 0
|
||||
|
||||
COMPortBaseAddr dw 3F8h
|
||||
|
||||
|
||||
|
||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||
|
||||
my_service db 'COM_Mouse',0 ;max 16 chars include zero
|
||||
|
||||
if DEBUG
|
||||
msgInit db 'Preved bugoga!',13,10,0
|
||||
boot_setmouse_type db 'Detected - COM1 mouse',13,10,0
|
||||
db 'Detected - COM2 mouse',13,10,0
|
||||
msg_error_reserve_ports db 'Error reserving ports!',13,10,0
|
||||
msg_error_attach_int_handler db 'Error attach interrupt handler!',13,10,0
|
||||
msg_exit db 'Exit!',13,10,0
|
||||
end if
|
||||
|
||||
section '.data' data readable writable align 16
|
||||
|
||||
;all uninitialized data place here
|
||||
|
1166
kernel/branches/kolibri-cfg/drivers/emu10k1x.asm
Normal file
1166
kernel/branches/kolibri-cfg/drivers/emu10k1x.asm
Normal file
File diff suppressed because it is too large
Load Diff
1177
kernel/branches/kolibri-cfg/drivers/ensoniq.asm
Normal file
1177
kernel/branches/kolibri-cfg/drivers/ensoniq.asm
Normal file
File diff suppressed because it is too large
Load Diff
1061
kernel/branches/kolibri-cfg/drivers/fm801.asm
Normal file
1061
kernel/branches/kolibri-cfg/drivers/fm801.asm
Normal file
File diff suppressed because it is too large
Load Diff
95
kernel/branches/kolibri-cfg/drivers/imports.inc
Normal file
95
kernel/branches/kolibri-cfg/drivers/imports.inc
Normal file
@ -0,0 +1,95 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
macro kernel_export [name]{
|
||||
forward
|
||||
if used name
|
||||
if DEBUG
|
||||
display 'uses: ',`name,#13,#10
|
||||
end if
|
||||
extrn name
|
||||
end if
|
||||
}
|
||||
; all exported kernel functions and data
|
||||
|
||||
|
||||
kernel_export \
|
||||
RegService,\
|
||||
GetService,\
|
||||
ServiceHandler,\
|
||||
AttachIntHandler,\
|
||||
GetIntHandler,\
|
||||
FpuSave,\
|
||||
FpuRestore,\
|
||||
ReservePortArea,\
|
||||
Boot_Log,\
|
||||
\
|
||||
MutexInit,\
|
||||
MutexLock,\
|
||||
MutexUnlock,\
|
||||
\
|
||||
PciApi,\
|
||||
PciRead32,\
|
||||
PciRead16,\
|
||||
PciRead8,\
|
||||
PciWrite8,\
|
||||
PciWrite16,\
|
||||
PciWrite32,\
|
||||
\
|
||||
AllocPage,\
|
||||
AllocPages,\
|
||||
FreePage,\
|
||||
MapPage,\
|
||||
MapSpace,\
|
||||
MapIoMem,\
|
||||
GetPgAddr,\
|
||||
CommitPages,\
|
||||
ReleasePages,\
|
||||
\
|
||||
AllocKernelSpace,\
|
||||
FreeKernelSpace,\
|
||||
KernelAlloc,\
|
||||
KernelFree,\
|
||||
UserAlloc,\
|
||||
UserFree,\
|
||||
Kmalloc,\
|
||||
Kfree,\
|
||||
CreateRingBuffer,\
|
||||
\
|
||||
GetPid,\
|
||||
CreateObject,\
|
||||
DestroyObject,\
|
||||
CreateEvent,\
|
||||
RaiseEvent,\
|
||||
WaitEvent,\
|
||||
DestroyEvent,\
|
||||
ClearEvent,\
|
||||
\
|
||||
LoadCursor,\
|
||||
SelectHwCursor,\
|
||||
SetHwCursor,\
|
||||
HwCursorRestore,\
|
||||
HwCursorCreate,\
|
||||
\
|
||||
SysMsgBoardStr,\
|
||||
SysMsgBoardChar,\
|
||||
GetCurrentTask,\
|
||||
LoadFile,\
|
||||
SendEvent,\
|
||||
SetMouseData,\
|
||||
Sleep,\
|
||||
GetTimerTicks,\
|
||||
\
|
||||
strncat,\
|
||||
strncpy,\
|
||||
strncmp,\
|
||||
strnlen,\
|
||||
strchr,\
|
||||
strrchr,\
|
||||
\
|
||||
LFBAddress,\
|
||||
GetDisplay,\
|
||||
SetScreen
|
1435
kernel/branches/kolibri-cfg/drivers/infinity.asm
Normal file
1435
kernel/branches/kolibri-cfg/drivers/infinity.asm
Normal file
File diff suppressed because it is too large
Load Diff
173
kernel/branches/kolibri-cfg/drivers/main.inc
Normal file
173
kernel/branches/kolibri-cfg/drivers/main.inc
Normal file
@ -0,0 +1,173 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Serge 2006-2008
|
||||
; email: infinity_sound@mail.ru
|
||||
|
||||
|
||||
PLAY_SYNC equ 0x80000000
|
||||
|
||||
PCM_ALL equ 0
|
||||
|
||||
PCM_OUT equ 0x08000000
|
||||
PCM_RING equ 0x10000000
|
||||
PCM_STATIC equ 0x20000000
|
||||
PCM_FLOAT equ 0x40000000 ;reserved
|
||||
PCM_FILTER equ 0x80000000 ;reserved
|
||||
|
||||
PCM_2_16_48 equ 1
|
||||
PCM_1_16_48 equ 2
|
||||
|
||||
PCM_2_16_44 equ 3
|
||||
PCM_1_16_44 equ 4
|
||||
|
||||
PCM_2_16_32 equ 5
|
||||
PCM_1_16_32 equ 6
|
||||
|
||||
PCM_2_16_24 equ 7
|
||||
PCM_1_16_24 equ 8
|
||||
|
||||
PCM_2_16_22 equ 9
|
||||
PCM_1_16_22 equ 10
|
||||
|
||||
PCM_2_16_16 equ 11
|
||||
PCM_1_16_16 equ 12
|
||||
|
||||
PCM_2_16_12 equ 13
|
||||
PCM_1_16_12 equ 14
|
||||
|
||||
PCM_2_16_11 equ 15
|
||||
PCM_1_16_11 equ 16
|
||||
|
||||
PCM_2_16_8 equ 17
|
||||
PCM_1_16_8 equ 18
|
||||
|
||||
PCM_2_8_48 equ 19
|
||||
PCM_1_8_48 equ 20
|
||||
|
||||
PCM_2_8_44 equ 21
|
||||
PCM_1_8_44 equ 22
|
||||
|
||||
PCM_2_8_32 equ 23
|
||||
PCM_1_8_32 equ 24
|
||||
|
||||
PCM_2_8_24 equ 25
|
||||
PCM_1_8_24 equ 26
|
||||
|
||||
PCM_2_8_22 equ 27
|
||||
PCM_1_8_22 equ 28
|
||||
|
||||
PCM_2_8_16 equ 29
|
||||
PCM_1_8_16 equ 30
|
||||
|
||||
PCM_2_8_12 equ 31
|
||||
PCM_1_8_12 equ 32
|
||||
|
||||
PCM_2_8_11 equ 33
|
||||
PCM_1_8_11 equ 34
|
||||
|
||||
PCM_2_8_8 equ 35
|
||||
PCM_1_8_8 equ 36
|
||||
|
||||
SRV_GETVERSION equ 0
|
||||
SND_CREATE_BUFF equ 1
|
||||
SND_DESTROY_BUFF equ 2
|
||||
SND_SETFORMAT equ 3
|
||||
SND_GETFORMAT equ 4
|
||||
SND_RESET equ 5
|
||||
SND_SETPOS equ 6
|
||||
SND_GETPOS equ 7
|
||||
SND_SETBUFF equ 8
|
||||
SND_OUT equ 9
|
||||
SND_PLAY equ 10
|
||||
SND_STOP equ 11
|
||||
SND_SETVOLUME equ 12
|
||||
SND_GETVOLUME equ 13
|
||||
SND_SETPAN equ 14
|
||||
SND_GETPAN equ 15
|
||||
SND_GETBUFFSIZE equ 16
|
||||
SND_GETFREESPACE equ 17
|
||||
SND_SETTIMEBASE equ 18
|
||||
SND_GETTIMESTAMP equ 19
|
||||
|
||||
struc STREAM
|
||||
{
|
||||
.magic dd ? ;'WAVE'
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
|
||||
.size dd ?
|
||||
.str_fd dd ?
|
||||
.str_bk dd ?
|
||||
.device dd ?
|
||||
.format dd ?
|
||||
.flags dd ?
|
||||
|
||||
.out_base dd ?
|
||||
.out_wp dd ?
|
||||
.out_rp dd ?
|
||||
.out_count dd ?
|
||||
.out_top dd ? ;16*4
|
||||
|
||||
.in_base dd ?
|
||||
.in_size dd ?
|
||||
.in_wp dd ?
|
||||
.in_rp dd ?
|
||||
.in_count dd ?
|
||||
.in_free dd ?
|
||||
.in_top dd ?
|
||||
|
||||
align 8
|
||||
|
||||
.time_base dq ?
|
||||
.time_stamp dq ?
|
||||
.last_ts dd ?
|
||||
|
||||
.notify_event dd ?
|
||||
.notify_id dd ?
|
||||
|
||||
.r_size dd ?
|
||||
.r_dt dd ?
|
||||
.r_silence dd ?
|
||||
.resample dd ?
|
||||
.l_vol dd ?
|
||||
.r_vol dd ?
|
||||
.l_amp dw ?
|
||||
.r_amp dw ?
|
||||
.pan dd ?
|
||||
.l_amp_f dd ? ;float point left
|
||||
.r_amp_f dd ? ;float point right
|
||||
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
FD_OFFSET equ 24
|
||||
|
||||
virtual at 0
|
||||
STREAM STREAM
|
||||
end virtual
|
||||
|
||||
struc WAVE_HEADER
|
||||
{ .riff_id dd ?
|
||||
.riff_size dd ?
|
||||
.riff_format dd ?
|
||||
|
||||
.fmt_id dd ?
|
||||
.fmt_size dd ?
|
||||
.format_tag dw ?
|
||||
.channels dw ?
|
||||
.freq dd ?
|
||||
.bytes_sec dd ?
|
||||
.block_align dw ?
|
||||
.bits_sample dw ?
|
||||
|
||||
.data_id dd ?
|
||||
.data_size dd ?
|
||||
}
|
||||
|
247
kernel/branches/kolibri-cfg/drivers/mix_mmx.inc
Normal file
247
kernel/branches/kolibri-cfg/drivers/mix_mmx.inc
Normal file
@ -0,0 +1,247 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; params
|
||||
; edi= output
|
||||
; eax= input stream 1
|
||||
; ebx= input stream 2
|
||||
|
||||
if used mmx_mix_2
|
||||
|
||||
align 4
|
||||
mmx_mix_2:
|
||||
movq mm0, [eax]
|
||||
movq mm1, [eax+8]
|
||||
movq mm2, [eax+16]
|
||||
movq mm3, [eax+24]
|
||||
movq mm4, [eax+32]
|
||||
movq mm5, [eax+40]
|
||||
movq mm6, [eax+48]
|
||||
movq mm7, [eax+56]
|
||||
|
||||
paddsw mm0, [ebx]
|
||||
movq [edi], mm0
|
||||
paddsw mm1,[ebx+8]
|
||||
movq [edi+8], mm1
|
||||
paddsw mm2, [ebx+16]
|
||||
movq [edi+16], mm2
|
||||
paddsw mm3, [ebx+24]
|
||||
movq [edi+24], mm3
|
||||
paddsw mm4, [ebx+32]
|
||||
movq [edi+32], mm4
|
||||
paddsw mm5, [ebx+40]
|
||||
movq [edi+40], mm5
|
||||
paddsw mm6, [ebx+48]
|
||||
movq [edi+48], mm6
|
||||
paddsw mm7, [ebx+56]
|
||||
movq [edi+56], mm7
|
||||
|
||||
movq mm0, [eax+64]
|
||||
movq mm1, [eax+72]
|
||||
movq mm2, [eax+80]
|
||||
movq mm3, [eax+88]
|
||||
movq mm4, [eax+96]
|
||||
movq mm5, [eax+104]
|
||||
movq mm6, [eax+112]
|
||||
movq mm7, [eax+120]
|
||||
|
||||
paddsw mm0, [ebx+64]
|
||||
movq [edi+64], mm0
|
||||
paddsw mm1, [ebx+72]
|
||||
movq [edi+72], mm1
|
||||
paddsw mm2, [ebx+80]
|
||||
movq [edi+80], mm2
|
||||
paddsw mm3, [ebx+88]
|
||||
movq [edi+88], mm3
|
||||
paddsw mm4, [ebx+96]
|
||||
movq [edi+96], mm4
|
||||
paddsw mm5, [ecx+104]
|
||||
movq [edx+104], mm5
|
||||
paddsw mm6, [ebx+112]
|
||||
movq [edi+112], mm6
|
||||
paddsw mm7, [ebx+120]
|
||||
movq [edi+120], mm7
|
||||
ret
|
||||
|
||||
align 4
|
||||
mmx_mix_3:
|
||||
movq mm0, [eax]
|
||||
movq mm1, [eax+8]
|
||||
movq mm2, [eax+16]
|
||||
movq mm3, [eax+24]
|
||||
movq mm4, [eax+32]
|
||||
movq mm5, [eax+40]
|
||||
movq mm6, [eax+48]
|
||||
movq mm7, [eax+56]
|
||||
|
||||
paddsw mm0, [ebx]
|
||||
paddsw mm1, [ebx+8]
|
||||
paddsw mm2, [ebx+16]
|
||||
paddsw mm3, [ebx+24]
|
||||
paddsw mm4, [ebx+32]
|
||||
paddsw mm5, [ebx+40]
|
||||
paddsw mm6, [ebx+48]
|
||||
paddsw mm7, [ebx+56]
|
||||
paddsw mm0, [ecx]
|
||||
movq [edi], mm0
|
||||
paddsw mm1,[ecx+8]
|
||||
movq [edi+8], mm1
|
||||
paddsw mm2, [ecx+16]
|
||||
movq [edi+16], mm2
|
||||
paddsw mm3, [ecx+24]
|
||||
movq [edi+24], mm3
|
||||
paddsw mm4, [ecx+32]
|
||||
movq [edi+32], mm4
|
||||
paddsw mm5, [ecx+40]
|
||||
movq [edi+40], mm5
|
||||
paddsw mm6, [ecx+48]
|
||||
movq [edi+48], mm6
|
||||
paddsw mm7, [ecx+56]
|
||||
movq [edi+56], mm7
|
||||
|
||||
movq mm0, [eax+64]
|
||||
movq mm1, [eax+72]
|
||||
movq mm2, [eax+80]
|
||||
movq mm3, [eax+88]
|
||||
movq mm4, [eax+96]
|
||||
movq mm5, [eax+104]
|
||||
movq mm6, [eax+112]
|
||||
movq mm7, [eax+120]
|
||||
paddsw mm0, [ebx+64]
|
||||
paddsw mm1, [ebx+72]
|
||||
paddsw mm2, [ebx+80]
|
||||
paddsw mm3, [ebx+88]
|
||||
paddsw mm4, [ebx+96]
|
||||
paddsw mm5, [ebx+104]
|
||||
paddsw mm6, [ebx+112]
|
||||
paddsw mm7, [ebx+120]
|
||||
paddsw mm0, [ecx+64]
|
||||
movq [edi+64], mm0
|
||||
paddsw mm1, [ecx+72]
|
||||
movq [edi+72], mm1
|
||||
paddsw mm2, [ecx+80]
|
||||
movq [edi+80], mm2
|
||||
paddsw mm3, [ecx+88]
|
||||
movq [edi+88], mm3
|
||||
paddsw mm4, [ecx+96]
|
||||
movq [edi+96], mm4
|
||||
paddsw mm5, [ecx+104]
|
||||
movq [edi+104], mm5
|
||||
paddsw mm6, [ecx+112]
|
||||
movq [edi+112], mm6
|
||||
paddsw mm7, [ecx+120]
|
||||
movq [edi+120], mm7
|
||||
ret
|
||||
|
||||
align 4
|
||||
mmx_mix_4:
|
||||
|
||||
movq mm0, [eax]
|
||||
movq mm2, [eax+8]
|
||||
movq mm4, [eax+16]
|
||||
movq mm6, [eax+24]
|
||||
movq mm1, [ebx]
|
||||
movq mm3, [ebx+8]
|
||||
movq mm5, [ebx+16]
|
||||
movq mm7, [ebx+24]
|
||||
paddsw mm0, [ecx]
|
||||
paddsw mm2, [ecx+8]
|
||||
paddsw mm4, [ecx+16]
|
||||
paddsw mm6, [ecx+24]
|
||||
paddsw mm1, [edx]
|
||||
paddsw mm3, [edx+8]
|
||||
paddsw mm5, [edx+16]
|
||||
paddsw mm7, [edx+24]
|
||||
|
||||
paddsw mm0, mm1
|
||||
movq [edi], mm0
|
||||
paddsw mm2, mm3
|
||||
movq [edi+8], mm2
|
||||
paddsw mm4, mm5
|
||||
movq [edi+16], mm4
|
||||
paddsw mm5, mm6
|
||||
movq [edi+24], mm6
|
||||
|
||||
movq mm0, [eax+32]
|
||||
movq mm2, [eax+40]
|
||||
movq mm4, [eax+48]
|
||||
movq mm6, [eax+56]
|
||||
movq mm1, [ebx+32]
|
||||
movq mm3, [ebx+40]
|
||||
movq mm5, [ebx+48]
|
||||
movq mm7, [ebx+56]
|
||||
paddsw mm0, [ecx+32]
|
||||
paddsw mm2, [ecx+40]
|
||||
paddsw mm4, [ecx+48]
|
||||
paddsw mm6, [ecx+56]
|
||||
paddsw mm1, [edx+32]
|
||||
paddsw mm3, [edx+40]
|
||||
paddsw mm5, [edx+48]
|
||||
paddsw mm7, [edx+56]
|
||||
|
||||
paddsw mm0, mm1
|
||||
movq [edi+32], mm0
|
||||
paddsw mm2, mm2
|
||||
movq [edi+40], mm2
|
||||
paddsw mm4, mm5
|
||||
movq [edi+48], mm4
|
||||
paddsw mm6, mm7
|
||||
movq [edi+56], mm6
|
||||
|
||||
movq mm0, [eax+64]
|
||||
movq mm2, [eax+72]
|
||||
movq mm4, [eax+80]
|
||||
movq mm6, [eax+88]
|
||||
movq mm1, [ebx+64]
|
||||
movq mm3, [ebx+72]
|
||||
movq mm5, [ebx+80]
|
||||
movq mm7, [ebx+88]
|
||||
paddsw mm0, [ecx+64]
|
||||
paddsw mm2, [ecx+72]
|
||||
paddsw mm4, [ecx+80]
|
||||
paddsw mm6, [ecx+88]
|
||||
paddsw mm1, [edx+64]
|
||||
paddsw mm3, [edx+72]
|
||||
paddsw mm5, [edx+80]
|
||||
paddsw mm7, [edx+88]
|
||||
|
||||
paddsw mm0, mm1
|
||||
movq [edi+64], mm0
|
||||
paddsw mm2, mm3
|
||||
movq [edi+72], mm2
|
||||
paddsw mm4, mm5
|
||||
movq [edi+80], mm4
|
||||
paddsw mm6, mm5
|
||||
movq [edi+88], mm7
|
||||
|
||||
movq mm0, [eax+96]
|
||||
movq mm2, [eax+104]
|
||||
movq mm4, [eax+112]
|
||||
movq mm6, [eax+120]
|
||||
movq mm1, [ebx+96]
|
||||
movq mm3, [ebx+104]
|
||||
movq mm5, [ebx+112]
|
||||
movq mm7, [ebx+120]
|
||||
paddsw mm0, [ecx+96]
|
||||
paddsw mm2, [ecx+104]
|
||||
paddsw mm4, [ecx+112]
|
||||
paddsw mm6, [ecx+120]
|
||||
paddsw mm1, [edx+96]
|
||||
paddsw mm3, [edx+104]
|
||||
paddsw mm5, [edx+112]
|
||||
paddsw mm7, [edx+120]
|
||||
paddsw mm0, mm1
|
||||
movq [eax+96], mm0
|
||||
paddsw mm2, mm3
|
||||
movq [edi+104], mm2
|
||||
paddsw mm4, mm5
|
||||
movq [edi+112], mm4
|
||||
paddsw mm6, mm7
|
||||
movq [edi+120], mm6
|
||||
ret
|
||||
|
||||
end if
|
145
kernel/branches/kolibri-cfg/drivers/mix_sse2.inc
Normal file
145
kernel/branches/kolibri-cfg/drivers/mix_sse2.inc
Normal file
@ -0,0 +1,145 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
if used mmx128_mix_2
|
||||
|
||||
align 4
|
||||
mmx128_mix_2:
|
||||
prefetcht1 [eax+128]
|
||||
prefetcht1 [ebx+128]
|
||||
|
||||
movaps xmm0, [eax]
|
||||
movaps xmm1, [eax+16]
|
||||
movaps xmm2, [eax+32]
|
||||
movaps xmm3, [eax+48]
|
||||
movaps xmm4, [eax+64]
|
||||
movaps xmm5, [eax+80]
|
||||
movaps xmm6, [eax+96]
|
||||
movaps xmm7, [eax+112]
|
||||
|
||||
paddsw xmm0, [ebx]
|
||||
movaps [edi], xmm0
|
||||
paddsw xmm1,[ebx+16]
|
||||
movaps [edi+16], xmm1
|
||||
paddsw xmm2, [ebx+32]
|
||||
movaps [edi+32], xmm2
|
||||
paddsw xmm3, [ebx+48]
|
||||
movaps [edi+48], xmm3
|
||||
paddsw xmm4, [ebx+64]
|
||||
movaps [edi+64], xmm4
|
||||
paddsw xmm5, [ebx+80]
|
||||
movaps [edi+80], xmm5
|
||||
paddsw xmm6, [ebx+96]
|
||||
movaps [edi+96], xmm6
|
||||
paddsw xmm7, [ebx+112]
|
||||
movaps [edi+112], xmm7
|
||||
ret
|
||||
|
||||
align 4
|
||||
mmx128_mix_3:
|
||||
prefetcht1 [eax+128]
|
||||
prefetcht1 [ebx+128]
|
||||
prefetcht1 [ecx+128]
|
||||
|
||||
movaps xmm0, [eax]
|
||||
movaps xmm1, [eax+16]
|
||||
movaps xmm2, [eax+32]
|
||||
movaps xmm3, [eax+48]
|
||||
movaps xmm4, [eax+64]
|
||||
movaps xmm5, [eax+80]
|
||||
movaps xmm6, [eax+96]
|
||||
movaps xmm7, [eax+112]
|
||||
|
||||
paddsw xmm0, [ebx]
|
||||
paddsw xmm1, [ebx+16]
|
||||
paddsw xmm2, [ebx+32]
|
||||
paddsw xmm3, [ebx+48]
|
||||
paddsw xmm4, [ebx+64]
|
||||
paddsw xmm5, [ebx+80]
|
||||
paddsw xmm6, [ebx+96]
|
||||
paddsw xmm7, [ebx+112]
|
||||
|
||||
paddsw xmm0, [ecx]
|
||||
movaps [edi], xmm0
|
||||
paddsw xmm1, [ecx+16]
|
||||
movaps [edi+16], xmm1
|
||||
paddsw xmm2, [ecx+32]
|
||||
movaps [edi+32], xmm2
|
||||
paddsw xmm3, [ecx+48]
|
||||
movaps [edi+48], xmm3
|
||||
paddsw xmm4, [ecx+64]
|
||||
movaps [edi+64], xmm4
|
||||
paddsw xmm5, [ecx+80]
|
||||
movaps [edi+80], xmm5
|
||||
paddsw xmm6, [ecx+96]
|
||||
movaps [edi+96], xmm6
|
||||
paddsw xmm7, [ecx+112]
|
||||
movaps [edi+112], xmm7
|
||||
ret
|
||||
|
||||
align 4
|
||||
mmx128_mix_4:
|
||||
prefetcht1 [eax+128]
|
||||
prefetcht1 [ebx+128]
|
||||
prefetcht1 [ecx+128]
|
||||
prefetcht1 [edx+128]
|
||||
|
||||
movaps xmm0, [eax]
|
||||
movaps xmm2, [eax+16]
|
||||
movaps xmm4, [eax+32]
|
||||
movaps xmm6, [eax+48]
|
||||
movaps xmm1, [ebx]
|
||||
movaps xmm3, [ebx+16]
|
||||
movaps xmm5, [ebx+32]
|
||||
movaps xmm7, [ebx+48]
|
||||
|
||||
paddsw xmm0, [ecx]
|
||||
paddsw xmm2, [ecx+16]
|
||||
paddsw xmm4, [ecx+32]
|
||||
paddsw xmm6, [ecx+48]
|
||||
paddsw xmm1, [edx]
|
||||
paddsw xmm3, [edx+16]
|
||||
paddsw xmm5, [edx+32]
|
||||
paddsw xmm7, [edx+48]
|
||||
|
||||
paddsw xmm0, xmm1
|
||||
movaps [edi], xmm0
|
||||
paddsw xmm2, xmm3
|
||||
movaps [edi+16], xmm2
|
||||
paddsw xmm4, xmm5
|
||||
movaps [edi+32], xmm4
|
||||
paddsw xmm6, xmm7
|
||||
movaps [edi+48], xmm6
|
||||
|
||||
movaps xmm0, [eax+64]
|
||||
movaps xmm2, [eax+80]
|
||||
movaps xmm4, [eax+96]
|
||||
movaps xmm6, [eax+112]
|
||||
|
||||
movaps xmm1, [ebx+64]
|
||||
movaps xmm3, [ebx+80]
|
||||
movaps xmm5, [ebx+96]
|
||||
movaps xmm7, [ebx+112]
|
||||
paddsw xmm0, [ecx+64]
|
||||
paddsw xmm2, [ecx+80]
|
||||
paddsw xmm4, [ecx+96]
|
||||
paddsw xmm6, [ecx+112]
|
||||
|
||||
paddsw xmm1, [edx+64]
|
||||
paddsw xmm3, [edx+80]
|
||||
paddsw xmm5, [edx+96]
|
||||
paddsw xmm7, [edx+112]
|
||||
paddsw xmm0, xmm1
|
||||
movaps [edi+64], xmm0
|
||||
paddsw xmm2, xmm3
|
||||
movaps [edi+80], xmm2
|
||||
paddsw xmm4, xmm5
|
||||
movaps [edi+96], xmm4
|
||||
paddsw xmm6, xmm7
|
||||
movaps [edi+112], xmm6
|
||||
ret
|
||||
end if
|
1266
kernel/branches/kolibri-cfg/drivers/mixer.asm
Normal file
1266
kernel/branches/kolibri-cfg/drivers/mixer.asm
Normal file
File diff suppressed because it is too large
Load Diff
268
kernel/branches/kolibri-cfg/drivers/proc32.inc
Normal file
268
kernel/branches/kolibri-cfg/drivers/proc32.inc
Normal file
@ -0,0 +1,268 @@
|
||||
|
||||
; Macroinstructions for defining and calling procedures
|
||||
|
||||
macro stdcall proc,[arg] ; directly call STDCALL procedure
|
||||
{ common
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
common
|
||||
end if
|
||||
call proc }
|
||||
|
||||
macro invoke proc,[arg] ; indirectly call STDCALL procedure
|
||||
{ common
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
common
|
||||
end if
|
||||
call [proc] }
|
||||
|
||||
macro ccall proc,[arg] ; directly call CDECL procedure
|
||||
{ common
|
||||
size@ccall = 0
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
size@ccall = size@ccall+4
|
||||
common
|
||||
end if
|
||||
call proc
|
||||
if size@ccall
|
||||
add esp,size@ccall
|
||||
end if }
|
||||
|
||||
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
|
||||
{ common
|
||||
size@ccall = 0
|
||||
if ~ arg eq
|
||||
reverse
|
||||
pushd arg
|
||||
size@ccall = size@ccall+4
|
||||
common
|
||||
end if
|
||||
call [proc]
|
||||
if size@ccall
|
||||
add esp,size@ccall
|
||||
end if }
|
||||
|
||||
macro proc [args] ; define procedure
|
||||
{ common
|
||||
match name params, args>
|
||||
\{ define@proc name,<params \} }
|
||||
|
||||
prologue@proc equ prologuedef
|
||||
|
||||
macro prologuedef procname,flag,parmbytes,localbytes,reglist
|
||||
{ if parmbytes | localbytes
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
if localbytes
|
||||
sub esp,localbytes
|
||||
end if
|
||||
end if
|
||||
irps reg, reglist \{ push reg \} }
|
||||
|
||||
epilogue@proc equ epiloguedef
|
||||
|
||||
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
|
||||
{ irps reg, reglist \{ reverse pop reg \}
|
||||
if parmbytes | localbytes
|
||||
leave
|
||||
end if
|
||||
if flag and 10000b
|
||||
retn
|
||||
else
|
||||
retn parmbytes
|
||||
end if }
|
||||
|
||||
macro define@proc name,statement
|
||||
{ local params,flag,regs,parmbytes,localbytes,current
|
||||
if used name
|
||||
name:
|
||||
match =stdcall args, statement \{ params equ args
|
||||
flag = 11b \}
|
||||
match =stdcall, statement \{ params equ
|
||||
flag = 11b \}
|
||||
match =c args, statement \{ params equ args
|
||||
flag = 10001b \}
|
||||
match =c, statement \{ params equ
|
||||
flag = 10001b \}
|
||||
match =params, params \{ params equ statement
|
||||
flag = 0 \}
|
||||
virtual at ebp+8
|
||||
match =uses reglist=,args, params \{ regs equ reglist
|
||||
params equ args \}
|
||||
match =regs =uses reglist, regs params \{ regs equ reglist
|
||||
params equ \}
|
||||
match =regs, regs \{ regs equ \}
|
||||
match =,args, params \{ defargs@proc args \}
|
||||
match =args@proc args, args@proc params \{ defargs@proc args \}
|
||||
parmbytes = $ - (ebp+8)
|
||||
end virtual
|
||||
name # % = parmbytes/4
|
||||
all@vars equ
|
||||
current = 0
|
||||
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
|
||||
macro locals
|
||||
\{ virtual at ebp-localbytes+current
|
||||
macro label . \\{ deflocal@proc .,:, \\}
|
||||
struc db [val] \\{ \common deflocal@proc .,db,val \\}
|
||||
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
|
||||
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
|
||||
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
|
||||
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
|
||||
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
|
||||
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
|
||||
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
|
||||
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
|
||||
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
|
||||
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
|
||||
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
|
||||
macro endl
|
||||
\{ purge label
|
||||
restruc db,dw,dp,dd,dt,dq
|
||||
restruc rb,rw,rp,rd,rt,rq
|
||||
restruc byte,word,dword,pword,tword,qword
|
||||
current = $-(ebp-localbytes)
|
||||
end virtual \}
|
||||
macro ret operand
|
||||
\{ match any, operand \\{ retn operand \\}
|
||||
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
|
||||
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
|
||||
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
|
||||
end if \} }
|
||||
|
||||
macro defargs@proc [arg]
|
||||
{ common
|
||||
if ~ arg eq
|
||||
forward
|
||||
local ..arg,current@arg
|
||||
match argname:type, arg
|
||||
\{ current@arg equ argname
|
||||
label ..arg type
|
||||
argname equ ..arg
|
||||
if dqword eq type
|
||||
dd ?,?,?,?
|
||||
else if tbyte eq type
|
||||
dd ?,?,?
|
||||
else if qword eq type | pword eq type
|
||||
dd ?,?
|
||||
else
|
||||
dd ?
|
||||
end if \}
|
||||
match =current@arg,current@arg
|
||||
\{ current@arg equ arg
|
||||
arg equ ..arg
|
||||
..arg dd ? \}
|
||||
common
|
||||
args@proc equ current@arg
|
||||
forward
|
||||
restore current@arg
|
||||
common
|
||||
end if }
|
||||
|
||||
macro deflocal@proc name,def,[val]
|
||||
{ common
|
||||
match vars, all@vars \{ all@vars equ all@vars, \}
|
||||
all@vars equ all@vars name
|
||||
forward
|
||||
local ..var,..tmp
|
||||
..var def val
|
||||
match =?, val \{ ..tmp equ \}
|
||||
match any =dup (=?), val \{ ..tmp equ \}
|
||||
match tmp : value, ..tmp : val
|
||||
\{ tmp: end virtual
|
||||
initlocal@proc ..var,def value
|
||||
virtual at tmp\}
|
||||
common
|
||||
match first rest, ..var, \{ name equ first \} }
|
||||
|
||||
macro initlocal@proc name,def
|
||||
{ virtual at name
|
||||
def
|
||||
size@initlocal = $ - name
|
||||
end virtual
|
||||
position@initlocal = 0
|
||||
while size@initlocal > position@initlocal
|
||||
virtual at name
|
||||
def
|
||||
if size@initlocal - position@initlocal < 2
|
||||
current@initlocal = 1
|
||||
load byte@initlocal byte from name+position@initlocal
|
||||
else if size@initlocal - position@initlocal < 4
|
||||
current@initlocal = 2
|
||||
load word@initlocal word from name+position@initlocal
|
||||
else
|
||||
current@initlocal = 4
|
||||
load dword@initlocal dword from name+position@initlocal
|
||||
end if
|
||||
end virtual
|
||||
if current@initlocal = 1
|
||||
mov byte [name+position@initlocal],byte@initlocal
|
||||
else if current@initlocal = 2
|
||||
mov word [name+position@initlocal],word@initlocal
|
||||
else
|
||||
mov dword [name+position@initlocal],dword@initlocal
|
||||
end if
|
||||
position@initlocal = position@initlocal + current@initlocal
|
||||
end while }
|
||||
|
||||
macro endp
|
||||
{ purge ret,locals,endl
|
||||
finish@proc
|
||||
purge finish@proc
|
||||
restore regs@proc
|
||||
match all,args@proc \{ restore all \}
|
||||
restore args@proc
|
||||
match all,all@vars \{ restore all \} }
|
||||
|
||||
macro local [var]
|
||||
{ common
|
||||
locals
|
||||
forward done@local equ
|
||||
match varname[count]:vartype, var
|
||||
\{ match =BYTE, vartype \\{ varname rb count
|
||||
restore done@local \\}
|
||||
match =WORD, vartype \\{ varname rw count
|
||||
restore done@local \\}
|
||||
match =DWORD, vartype \\{ varname rd count
|
||||
restore done@local \\}
|
||||
match =PWORD, vartype \\{ varname rp count
|
||||
restore done@local \\}
|
||||
match =QWORD, vartype \\{ varname rq count
|
||||
restore done@local \\}
|
||||
match =TBYTE, vartype \\{ varname rt count
|
||||
restore done@local \\}
|
||||
match =DQWORD, vartype \\{ label varname dqword
|
||||
rq count+count
|
||||
restore done@local \\}
|
||||
match , done@local \\{ virtual
|
||||
varname vartype
|
||||
end virtual
|
||||
rb count*sizeof.\#vartype
|
||||
restore done@local \\} \}
|
||||
match :varname:vartype, done@local:var
|
||||
\{ match =BYTE, vartype \\{ varname db ?
|
||||
restore done@local \\}
|
||||
match =WORD, vartype \\{ varname dw ?
|
||||
restore done@local \\}
|
||||
match =DWORD, vartype \\{ varname dd ?
|
||||
restore done@local \\}
|
||||
match =PWORD, vartype \\{ varname dp ?
|
||||
restore done@local \\}
|
||||
match =QWORD, vartype \\{ varname dq ?
|
||||
restore done@local \\}
|
||||
match =TBYTE, vartype \\{ varname dt ?
|
||||
restore done@local \\}
|
||||
match =DQWORD, vartype \\{ label varname dqword
|
||||
dq ?,?
|
||||
restore done@local \\}
|
||||
match , done@local \\{ varname vartype
|
||||
restore done@local \\} \}
|
||||
match ,done@local
|
||||
\{ var
|
||||
restore done@local \}
|
||||
common
|
||||
endl }
|
50
kernel/branches/kolibri-cfg/drivers/sb16/CONFIG.INC
Normal file
50
kernel/branches/kolibri-cfg/drivers/sb16/CONFIG.INC
Normal file
@ -0,0 +1,50 @@
|
||||
;flags------------------------------------------------------------
|
||||
DEBUG equ 1 ;show messages at debug board
|
||||
use_cli_sti equ 1 ;driver become more stable (theoretically)
|
||||
|
||||
;constants--------------------------------------------------------
|
||||
API_VERSION equ 0 ;debug
|
||||
|
||||
OS_BASE equ 0x80000000
|
||||
new_app_base equ 0x0
|
||||
PROC_BASE equ (OS_BASE+0x080000)
|
||||
SB16Buffer equ (OS_BASE+0x2A0000)
|
||||
SB16_Status equ (OS_BASE+0x2B0000)
|
||||
DMAPage equ ((SB16Buffer-OS_BASE) shr 16)
|
||||
|
||||
SB16Buffer0 equ SB16Buffer
|
||||
SB16Buffer1 equ (SB16Buffer+16384)
|
||||
SB16Buffer2 equ (SB16Buffer+(2*16384))
|
||||
SB16Buffer3 equ (SB16Buffer+(3*16384))
|
||||
|
||||
sb_irq_num equ 5 ;default values for SB16, may be overrided by autodetect
|
||||
sb_dma_num equ 5 ;default values for SB16, may be overrided by autodetect
|
||||
|
||||
small_buffer equ 32768
|
||||
full_buffer equ 65536
|
||||
sb_buffer_size equ small_buffer ; FIX ring buffer overlapped events issue; full_buffer
|
||||
|
||||
__supported_buffer_sizes fix <small_buffer, full_buffer>
|
||||
|
||||
if ~(sb_buffer_size in __supported_buffer_sizes)
|
||||
display 13,10,'unsupported buffer size was selected, check config.inc',13,10
|
||||
stop
|
||||
end if
|
||||
|
||||
sb_out_rate equ 48000
|
||||
;time constant for cards older than SB16
|
||||
sb_tc equ (256-(1000000/(sb_out_rate*2)))
|
||||
|
||||
SRV_GETVERSION equ 0
|
||||
DEV_PLAY equ 1
|
||||
DEV_STOP equ 2
|
||||
DEV_CALLBACK equ 3
|
||||
DEV_SET_BUFF equ 4
|
||||
DEV_NOTIFY equ 5
|
||||
DEV_SET_MASTERVOL equ 6
|
||||
DEV_GET_MASTERVOL equ 7
|
||||
DEV_GET_INFO equ 8
|
||||
|
||||
DRV_ENTRY equ 1
|
||||
DRV_EXIT equ -1
|
||||
|
72
kernel/branches/kolibri-cfg/drivers/sb16/README.TXT
Normal file
72
kernel/branches/kolibri-cfg/drivers/sb16/README.TXT
Normal file
@ -0,0 +1,72 @@
|
||||
Nable 21.05.2008.
|
||||
This driver is my contribution (or donation) to KolibriOS. This is provided
|
||||
AS IS in hope it'll be useful, but WITHOUT ANY WARRANTY! No responcibility
|
||||
for any hardware damage or data loss. Use at your own risk!
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
;Changelog:
|
||||
;-------------------------------------------------------------------------------
|
||||
v0.2 - DEV_SET(GET)_MASTERVOL functions are unlocked and implemented.
|
||||
|
||||
v0.1 - first release.
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
;Tiny FAQ for sound driver by Nable for SB16 sound card.
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
;What is it?--------------------------------------------------------------------
|
||||
As you may know there is a sound subsystem ('INFINITY') in KolibriOS.
|
||||
This subsystem includes mixer and separate interface for soundplayer
|
||||
program and driver, so player application don't need to know what soundcard
|
||||
is installed and how to cope with it, all work with card do the driver.
|
||||
Before this time there were drivers only for AC97 integrated sound, but I
|
||||
don't have such at home and if I would upgrade my computer with a newest
|
||||
hardware, with 100% probability integrated sound will be HD Codec, nowadays
|
||||
AC97 is not actual (2008 year is at calendar). But I'm not planning to upgrade
|
||||
my computer so much now (and in next 5-6 years), writing the driver for my PCI
|
||||
ESS Maestro1 card is difficult for me (may be some time later), so I decided
|
||||
to write a driver for SB16. At first it is easy, there are many working
|
||||
examples for DOS, there are heaps of good documentation and as an ISA device
|
||||
SB16 can be programmed through I/O ports (about 5 ports are used), that is
|
||||
more easy than PCI access. Now, enough lirics, lets go to physics :-)
|
||||
If you still don't understand what stuff is it, I'll tell this in brief:
|
||||
with this driver you can play MP3 and WAV music (using AC97SND player) and
|
||||
sounds (some games and DOSBOX can produce sound output through sound
|
||||
subsystem) in KolibriOS.
|
||||
|
||||
;Yeah! I need sound in Kolibri and I have SB16 card. Whats then?----------------
|
||||
At first copy my SOUND.OBJ to /sys/drivers at your Kolibri system. Note,
|
||||
that if you have AC97 card and it's driver started - then new driver won't
|
||||
run until reboot. Then run BOARD and go to 'user' tab. Then try to run
|
||||
AC97SND player. At BOARD you will see the following (if you had a proper
|
||||
card):
|
||||
|----------------------------|
|
||||
|detecting hardware... | <- detector startup message
|
||||
|DSP found at port 220h | <- if you have a proper card, it'll be
|
||||
|DSP version 4.13 - SB16 | autodetected. Numbers may be different.
|
||||
|failed to attach IRQ5 | <- don't mention. Old kernels reserve IRQ5
|
||||
|owner's handler: 0x80D74284 | see below how to fix it.
|
||||
|----------------------------|
|
||||
At first, note that DSP version must be 4.xx or higher. Older cards are not
|
||||
supported in this first release, maybe some time later. If nothing detected
|
||||
but PNP/BIOS or some other OS detects your card - I'm sorry, it's perverted
|
||||
PNP card like OPTi16, that is like HD Codec - until you init it through
|
||||
PCI->ISA bridge (HD Codec of course through PCI->PCI bridge), map it, etc,
|
||||
you can't use it in any way. I'd rather write a PCI device driver, than
|
||||
for this extreme perversion. If your card detected and has a proper version
|
||||
but you see 'failed to attach IRQ' - delete stroke 'mov [irq_owner+4*5],1' from the
|
||||
file kernel.asm of your kernel source, save it, rebuild kernel, copy new
|
||||
kernel to /sys/ (did you rename 'kernel' to 'kernel.mnt'? You should do it),
|
||||
restart kernel (Ctrl+Alt+F12, Home). THE EASIER WAY IS TO USE A NEWER KERNEL,
|
||||
since SVN802 it's fixed.
|
||||
Now everything should be OK.
|
||||
|
||||
;It works for a part of the second and then stops, but system doesn't hang------
|
||||
Go to 'config.inc' of my driver and change 'sb_irq_num' value from 5 to 7.
|
||||
Then save, rebuild driver (compile 'sound.asm'), put 'sound' to /sys/drivers/
|
||||
(you need to rename file 'sound' to 'sound.obj'), restart kernel and try again
|
||||
to produce sound.
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
Ask your questions at KolibriOS forum: board.kolibrios.org
|
||||
I'll try to answer you if possible.
|
297
kernel/branches/kolibri-cfg/drivers/sb16/SB16.INC
Normal file
297
kernel/branches/kolibri-cfg/drivers/sb16/SB16.INC
Normal file
@ -0,0 +1,297 @@
|
||||
;--------------------------------
|
||||
; program dma
|
||||
;--------------------------------
|
||||
sb_set_dma:
|
||||
mov ebx,[sound_dma]
|
||||
lea eax,[ebx+4] ;mask required channel
|
||||
cmp bl,4
|
||||
ja .use_second_dma_controller
|
||||
jb @f
|
||||
.dma_setup_error:
|
||||
if DEBUG
|
||||
mov esi,msgErrDMAsetup
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
mov dword[esp],START.stop
|
||||
ret
|
||||
@@:
|
||||
if use_cli_sti
|
||||
cli ;here to minimize time with disabled ints
|
||||
end if
|
||||
out 0xA,al ;mask required channel
|
||||
|
||||
xor eax,eax
|
||||
out 0xC,al ;clear byte pointer flip-flop register
|
||||
|
||||
lea eax,[ebx+0x58] ;auto-init mode for channel (ebx)
|
||||
out 0xB,al ;DMA channel 0-3 mode register
|
||||
|
||||
movzx edx,byte[ebx+dma_table] ;page register
|
||||
mov al,DMAPage
|
||||
out dx,al
|
||||
|
||||
lea edx,[ebx*2] ;DMA channel 0-3 base address
|
||||
|
||||
mov al,0 ;LSB is 0
|
||||
out dx,al
|
||||
|
||||
; mov al,0 ;MSB is 0 too
|
||||
out dx,al
|
||||
|
||||
inc edx ;DMA channel 0-3 byte count
|
||||
|
||||
mov al,((sb_buffer_size-1) and 0xff)
|
||||
out dx,al
|
||||
|
||||
mov al,((sb_buffer_size-1) shr 8) ;it is the same
|
||||
out dx,al
|
||||
|
||||
mov eax,ebx ;unmask DMA channel
|
||||
out 0xA,al
|
||||
|
||||
if use_cli_sti
|
||||
sti
|
||||
end if
|
||||
ret
|
||||
|
||||
.use_second_dma_controller:
|
||||
cmp bl,7
|
||||
ja .dma_setup_error
|
||||
|
||||
sub bl,4
|
||||
sub al,4
|
||||
if use_cli_sti
|
||||
cli ;here to minimize time with disabled ints
|
||||
end if
|
||||
out 0xD4,al ;mask required channel
|
||||
|
||||
xor eax,eax
|
||||
out 0xD8,al ;clear byte pointer flip-flop register
|
||||
|
||||
lea eax,[ebx+0x58] ;auto-init mode for channel (ebx+4)
|
||||
out 0xD6,al ;DMA channel 4-7 mode register
|
||||
|
||||
movzx edx,byte[ebx+dma_table+4] ;page register
|
||||
mov al,DMAPage
|
||||
out dx,al
|
||||
|
||||
lea edx,[ebx*4+0xC0] ;DMA channel 4-7 base address
|
||||
|
||||
mov al,0 ;LSB is 0 ;for 16bit DMA this contains
|
||||
out dx,al ;A1-A8 lines of address bus, A0 is zero
|
||||
|
||||
; mov al,0 ;MSB is 0 too ;for 16bit DMA this contains
|
||||
out dx,al ;A9-A16 lines of address bus
|
||||
|
||||
inc edx
|
||||
inc edx ;DMA channel 4-7 16bit word count
|
||||
|
||||
mov al,(((sb_buffer_size/2)-1) and 0xff)
|
||||
out dx,al
|
||||
|
||||
mov al,(((sb_buffer_size/2)-1) shr 8)
|
||||
out dx,al
|
||||
|
||||
mov eax,ebx ;unmask DMA channel
|
||||
out 0xD4,al
|
||||
|
||||
if use_cli_sti
|
||||
sti
|
||||
end if
|
||||
ret
|
||||
;-------------------------------------------------------------------------------
|
||||
; out byte to SB DSP's write port
|
||||
;-------------------------------------------------------------------------------
|
||||
macro sb_out data_to_out {
|
||||
@@:
|
||||
in al,dx
|
||||
test al,al ;is DSP busy?
|
||||
js @b ;it's busy
|
||||
mov al,data_to_out ;it's free
|
||||
out dx,al
|
||||
}
|
||||
;-------------------------------------------------------------------------------
|
||||
; stop playing
|
||||
;-------------------------------------------------------------------------------
|
||||
proc sb_stop
|
||||
mov edx,[sb_base_port]
|
||||
add dl,0xC
|
||||
sb_out 0xD3 ;turn the speaker off
|
||||
sb_out 0xDA ;exit 8bit DMA
|
||||
sb_out 0xD9 ;exit 16bit DMA
|
||||
ret
|
||||
endp
|
||||
;-------------------------------------------------------------------------------
|
||||
; start playing
|
||||
;-------------------------------------------------------------------------------
|
||||
proc sb_play
|
||||
and [int_flip_flop],0
|
||||
mov edx,[sb_base_port]
|
||||
add dl,0xC
|
||||
sb_out 0xD1 ;turn speaker on
|
||||
; sb_out 0x48 ;set DSP transfer size ;for older cards, not supported
|
||||
; ;in this version
|
||||
; mov ax,32767 ;(64k)/2-1
|
||||
;@@: ;out the low byte...
|
||||
; in al,dx
|
||||
; test al,al ;is DSP busy?
|
||||
; js @b ;it's busy
|
||||
; out dx,al
|
||||
|
||||
; mov al,ah ;...then the high byte
|
||||
;@@:
|
||||
; in al,dx
|
||||
; test al,al ;is DSP busy?
|
||||
; js @b ;it's busy
|
||||
; out dx,al
|
||||
|
||||
; sb_out 0x1C ;auto-init 8bit playback
|
||||
|
||||
; 0xBXh - 16 bit DMA mode
|
||||
; ||||
|
||||
sb_out 10110110b ;bCommand
|
||||
; ||||
|
||||
; |||+-reserved
|
||||
; ||+--turn FIFO on (0 for off)
|
||||
; |+---auto-init mode on (0 for off)
|
||||
; +----A/D: 0-output, 1-input
|
||||
; +------stereo on
|
||||
; |+-----unsigned (1 for signed)
|
||||
; ||
|
||||
sb_out 00110000b ;bMode
|
||||
; || ||||
|
||||
; ---------reserved
|
||||
;wSize is a number of 16bit samples less 1. For auto-init mode each half
|
||||
;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 samples
|
||||
sb_out (((sb_buffer_size/2/2)-1) and 0xFF) ;wSize.LowByte
|
||||
sb_out (((sb_buffer_size/2/2)-1) shr 8) ;wSize.HighByte
|
||||
ret
|
||||
endp
|
||||
;-------------------------------------------------------------------------------
|
||||
; reset DSP
|
||||
;-------------------------------------------------------------------------------
|
||||
proc sb_reset
|
||||
and [int_flip_flop],0
|
||||
mov edx,[sb_base_port]
|
||||
add dl,6
|
||||
mov al,1 ;start DSP reset
|
||||
|
||||
if use_cli_sti
|
||||
cli ;here to minimize time with disabled ints
|
||||
end if
|
||||
out dx,al
|
||||
mov ecx,40 ;wait at least 3 microsec.
|
||||
@@:
|
||||
in al,dx
|
||||
loop @b
|
||||
|
||||
xor eax,eax ;stop DSP reset
|
||||
if use_cli_sti
|
||||
sti
|
||||
end if
|
||||
out dx,al
|
||||
ret
|
||||
endp
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; set the rate for playing, enable stereo
|
||||
;-------------------------------------------------------------------------------
|
||||
proc sb_setup
|
||||
mov edx,[sb_base_port]
|
||||
add dl,0xC
|
||||
sb_out 40h ;set time constant, this is for old cards
|
||||
sb_out sb_tc
|
||||
|
||||
sb_out 41h ;set sound rate, this can only SB16
|
||||
sb_out (sb_out_rate shr 8) ;first high byte (MSB)
|
||||
sb_out (sb_out_rate and 0xff) ;then low byte (LSB)
|
||||
|
||||
; mov al,0xE ;for older cards, not supported in this version
|
||||
; sub dl,(0xC-4) ;talk to SB's mixer
|
||||
; out dx,al ;select this register of the mixer
|
||||
; mov ecx,6 ;wait for the chip
|
||||
;@@:
|
||||
; in al,dx
|
||||
; loop @b
|
||||
|
||||
; inc edx ;now read the data port
|
||||
; in al,dx
|
||||
; or al,22h ;turn on stereo
|
||||
; mov ah,al
|
||||
|
||||
; mov al,0xE
|
||||
; dec edx ;talk to SB's mixer
|
||||
; out dx,al ;select this register of the mixer
|
||||
|
||||
; mov ecx,6 ;wait for the chip
|
||||
;@@:
|
||||
; in al,dx
|
||||
; loop @b
|
||||
|
||||
; inc edx ;now send data to the data port
|
||||
; mov al,ah
|
||||
; out dx,al
|
||||
|
||||
; dec edx
|
||||
; mov ecx,35 ;wait for the chip
|
||||
;@@:
|
||||
; in al,dx
|
||||
; loop @b
|
||||
ret
|
||||
endp
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; set master volume of SB mixer, note, not only SB16 but SBPro and older
|
||||
; this is the first step to more full support for hardware
|
||||
;-------------------------------------------------------------------------------
|
||||
;in: eax in range [-10000;0] - master volume for _both_ channels
|
||||
;note that x*3*17/2000 and x*3/2000*17 are not the same numbers,
|
||||
;because we count in integers
|
||||
proc sb_set_master_vol
|
||||
mov [sb_master_vol],eax
|
||||
add eax,10000 ;SB sound level rise from 0 to MAX_LEVEL
|
||||
lea eax,[eax+eax*2] ;*3
|
||||
mov ebx,2000 ;divisor
|
||||
xor edx,edx
|
||||
cmp byte[sb_DSP_version_int],4
|
||||
jae @f ;SBPro's MAX_LEVEL is 15, but we *11 because
|
||||
;volume byte looks like that: 0xLR, where L - left
|
||||
;channel volume, R - right, 0<=R,L<=15
|
||||
div ebx
|
||||
imul eax,17
|
||||
mov edx,[sb_base_port]
|
||||
push eax ;here for optimisation
|
||||
add dl,4
|
||||
mov al,0x22 ;write mixer register 0x22
|
||||
out dx,al
|
||||
in al,dx ;wait for the chip ;6
|
||||
in al,dx ;wait for the chip ;5
|
||||
in al,dx ;wait for the chip ;4
|
||||
in al,dx ;wait for the chip ;3
|
||||
in al,dx ;wait for the chip ;2
|
||||
in al,dx ;wait for the chip ;1
|
||||
pop eax ;go!
|
||||
inc edx
|
||||
out dx,al
|
||||
ret
|
||||
@@: ;SB16's MAX_LEVEL is 255
|
||||
imul eax,17
|
||||
div ebx
|
||||
mov edx,[sb_base_port]
|
||||
push eax ;here for optimisation
|
||||
add dl,4
|
||||
mov al,0x30 ;left speaker
|
||||
out dx,al
|
||||
pop eax ;<--+
|
||||
inc edx ; \/
|
||||
push eax ;here for optimisation
|
||||
out dx,al ;write
|
||||
dec edx
|
||||
mov al,0x31 ;right speaker
|
||||
out dx,al
|
||||
pop eax
|
||||
inc edx
|
||||
out dx,al ;write
|
||||
ret
|
||||
endp
|
||||
;-------------------------------------------------------------------------------
|
393
kernel/branches/kolibri-cfg/drivers/sb16/sb16.asm
Normal file
393
kernel/branches/kolibri-cfg/drivers/sb16/sb16.asm
Normal file
@ -0,0 +1,393 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
format MS COFF
|
||||
|
||||
include 'CONFIG.INC'
|
||||
|
||||
;structs----------------------------------------------------------
|
||||
struc IOCTL
|
||||
{ .handle dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
IOCTL IOCTL
|
||||
end virtual
|
||||
|
||||
;something--------------------------------------------------------
|
||||
public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
include '..\proc32.inc'
|
||||
include '..\imports.inc'
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
include 'SB16.INC'
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
proc START stdcall, state:dword
|
||||
cmp [state], 1
|
||||
jne .stop
|
||||
.entry:
|
||||
|
||||
if DEBUG
|
||||
mov esi, msgInit
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
|
||||
call detect ;returns DSP version or zero if
|
||||
test eax,eax ;SB card not found
|
||||
jz .exit
|
||||
|
||||
if DEBUG
|
||||
movzx eax,al ;major version
|
||||
mov esi,sb_DSP_description
|
||||
dec eax
|
||||
jz .sb_say_about_found_dsp
|
||||
mov dword[esi],'2.x '
|
||||
dec eax
|
||||
jz .sb_say_about_found_dsp
|
||||
mov dword[esi],'Pro '
|
||||
dec eax
|
||||
jz .sb_say_about_found_dsp
|
||||
mov dword[esi],'16 '
|
||||
.sb_say_about_found_dsp:
|
||||
mov esi,msgDSPFound
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
; xor eax,eax
|
||||
; mov ebx,[sb_base_port]
|
||||
; lea ecx,[ebx+0xF]
|
||||
xor ebx,ebx
|
||||
mov ecx,[sb_base_port]
|
||||
lea edx,[ebx+0xF]
|
||||
|
||||
call ReservePortArea ;these ports must be my!
|
||||
if DEBUG
|
||||
dec eax
|
||||
jnz @f
|
||||
mov esi,msgErrRsrvPorts
|
||||
call SysMsgBoardStr
|
||||
@@:
|
||||
end if
|
||||
|
||||
call sb_setup ;clock it, etc
|
||||
|
||||
stdcall AttachIntHandler, sb_irq_num, sb_irq, 0
|
||||
|
||||
if DEBUG
|
||||
test eax,eax
|
||||
jnz @f
|
||||
|
||||
mov esi,msgErrAtchIRQ
|
||||
call SysMsgBoardStr
|
||||
|
||||
stdcall GetIntHandler, sb_irq_num
|
||||
call SysMsgBoardNum
|
||||
|
||||
jmp .stop
|
||||
@@:
|
||||
mov esi,msgSucAtchIRQ
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
stdcall RegService, my_service, service_proc
|
||||
ret
|
||||
.stop:
|
||||
call sb_reset
|
||||
.exit:
|
||||
|
||||
if DEBUG
|
||||
mov esi,msgExit
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
handle equ IOCTL.handle
|
||||
io_code equ IOCTL.io_code
|
||||
input equ IOCTL.input
|
||||
inp_size equ IOCTL.inp_size
|
||||
output equ IOCTL.output
|
||||
out_size equ IOCTL.out_size
|
||||
|
||||
align 4
|
||||
proc service_proc stdcall, ioctl:dword
|
||||
mov edi,[ioctl]
|
||||
mov eax,[edi+io_code]
|
||||
cmp eax,SRV_GETVERSION
|
||||
jne @F
|
||||
|
||||
mov eax,[edi+output]
|
||||
cmp [edi+out_size],4
|
||||
jne .fail
|
||||
mov [eax],dword API_VERSION
|
||||
xor eax,eax
|
||||
ret
|
||||
@@:
|
||||
cmp eax,DEV_PLAY
|
||||
jne @f
|
||||
if DEBUG
|
||||
mov esi,msgPlay
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
call sb_stop ;to play smth new we must stop smth old
|
||||
|
||||
call pre_fill_data ;fill first and second half of the buffer
|
||||
call pre_fill_data ;
|
||||
|
||||
call sb_set_dma ;is it really needed here? Paranoia.
|
||||
call sb_play
|
||||
xor eax,eax ;set maximum volume
|
||||
call sb_set_master_vol
|
||||
xor eax,eax
|
||||
ret
|
||||
;@@: ;all this commented stuff in service proc
|
||||
; cmp eax,DEV_STOP ;is never used. Mixer do this virtually,
|
||||
; jne @f ;e.g. instead of stopping driver it
|
||||
;if DEBUG ;outputs silence
|
||||
; mov esi,msgStop
|
||||
; call SysMsgBoardStr
|
||||
;end if
|
||||
; call sb_stop
|
||||
; xor eax,eax
|
||||
; ret
|
||||
@@:
|
||||
cmp eax,DEV_CALLBACK
|
||||
jne @f
|
||||
if DEBUG
|
||||
mov esi,msgCallback
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
mov edi,[edi+input]
|
||||
mov eax,[edi]
|
||||
mov [callback],eax
|
||||
if DEBUG
|
||||
call SysMsgBoardNum
|
||||
end if
|
||||
xor eax,eax
|
||||
ret
|
||||
@@:
|
||||
cmp eax,DEV_SET_MASTERVOL ;Serge asked me to unlock
|
||||
jne @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it.
|
||||
;It doesn't use it _in current version_ - but in the future...
|
||||
|
||||
if DEBUG
|
||||
mov esi,msgSetVol
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
mov eax,[edi+input]
|
||||
mov eax,[eax]
|
||||
call sb_set_master_vol
|
||||
xor eax,eax
|
||||
ret
|
||||
@@:
|
||||
cmp eax,DEV_GET_MASTERVOL
|
||||
jne @F
|
||||
if DEBUG
|
||||
mov esi,msgGetVol
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
mov eax,[edi+output]
|
||||
mov edx,[sb_master_vol]
|
||||
mov [eax],edx
|
||||
xor eax,eax
|
||||
ret
|
||||
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
|
||||
restore handle
|
||||
restore io_code
|
||||
restore input
|
||||
restore inp_size
|
||||
restore output
|
||||
restore out_size
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
align 4
|
||||
proc sb_irq
|
||||
mov edx,[sb_base_port] ;tell the DSP that we have processed IRQ
|
||||
add dl,0xF ;0xF for 16 bit sound, 0xE for 8 bit sound
|
||||
in al,dx ;for non-stop sound
|
||||
|
||||
pre_fill_data:
|
||||
mov eax,int_flip_flop
|
||||
not dword[eax]
|
||||
mov eax,[eax]
|
||||
test eax,eax
|
||||
jns .fill_second_half
|
||||
|
||||
if sb_buffer_size eq small_buffer
|
||||
stdcall [callback],SB16Buffer0 ;for 32k buffer
|
||||
else if sb_buffer_size eq full_buffer
|
||||
stdcall [callback],SB16Buffer0 ;for 64k buffer
|
||||
stdcall [callback],SB16Buffer1 ;for 64k buffer
|
||||
end if
|
||||
xor eax,eax
|
||||
ret
|
||||
|
||||
.fill_second_half:
|
||||
if sb_buffer_size eq small_buffer
|
||||
stdcall [callback],SB16Buffer1 ;for 32k buffer
|
||||
else if sb_buffer_size eq full_buffer
|
||||
stdcall [callback],SB16Buffer2 ;for 64k buffer
|
||||
stdcall [callback],SB16Buffer3 ;for 64k buffer
|
||||
end if
|
||||
xor eax,eax
|
||||
ret
|
||||
endp
|
||||
;-------------------------------------------------------------------------------
|
||||
align 4
|
||||
proc detect
|
||||
.sb_detect_next_port:
|
||||
if DEBUG
|
||||
inc dword[port_second_digit_num]
|
||||
end if
|
||||
mov edx,sb_base_port
|
||||
add byte[edx],10h
|
||||
cmp byte[edx],80h
|
||||
jbe .sb_try_to_detect_at_specified_port
|
||||
;error - no SB card detected
|
||||
.sb_not_found_err:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.sb_try_to_detect_at_specified_port:
|
||||
call sb_reset
|
||||
add dl,8
|
||||
mov ecx,100
|
||||
.sb_check_port:
|
||||
in al,dx
|
||||
test al,al ;is DSP port ready to be read?
|
||||
jns .sb_port_not_ready
|
||||
|
||||
sub dl,4
|
||||
in al,dx ;check for AAh response
|
||||
add dl,4
|
||||
cmp al,0xAA
|
||||
jne .sb_port_not_ready
|
||||
.sb_card_found:
|
||||
and dl,0xF0
|
||||
add dl,0xC
|
||||
sb_out 0xE1 ;get DSP version
|
||||
add dl,2
|
||||
@@:
|
||||
in al,dx
|
||||
test al,al ;is DSP port ready to be read?
|
||||
jns @b
|
||||
sub dl,4
|
||||
in al,dx ;get major version
|
||||
ror eax,16
|
||||
add dl,4
|
||||
@@:
|
||||
in al,dx
|
||||
test al,al ;is DSP port ready to be read?
|
||||
jns @b
|
||||
sub dl,4
|
||||
in al,dx ;get minor version
|
||||
xor edx,edx
|
||||
mov dl,10
|
||||
div dl
|
||||
ror eax,16
|
||||
xor ah,ah
|
||||
mov [sb_DSP_version_int],eax ;for internal usage
|
||||
if DEBUG
|
||||
add [sb_DSP_version],eax
|
||||
end if
|
||||
ret
|
||||
|
||||
.sb_port_not_ready:
|
||||
loop .sb_check_port ;100 retries (~100 microsec.)
|
||||
jmp .sb_detect_next_port
|
||||
endp
|
||||
;-------------------------------------------------------------------------------
|
||||
if DEBUG
|
||||
proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi
|
||||
mov ebx,eax
|
||||
mov ecx,8
|
||||
mov esi,(number_to_out+1)
|
||||
.1:
|
||||
mov eax,ebx
|
||||
and eax,0xF
|
||||
add al,'0'
|
||||
cmp al,(10+'0')
|
||||
jb @f
|
||||
add al,('A'-'0'-10)
|
||||
@@:
|
||||
mov [esi+ecx],al
|
||||
shr ebx,4
|
||||
loop .1
|
||||
dec esi
|
||||
call SysMsgBoardStr
|
||||
ret
|
||||
endp
|
||||
end if
|
||||
;all initialized data place here
|
||||
align 4
|
||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||
|
||||
sb_base_port: dd 200h ;don't ask me why - see the code&docs
|
||||
|
||||
sound_dma dd sb_dma_num
|
||||
|
||||
;note that 4th DMA channel doesn't exist, it is used for cascade
|
||||
;plugging the first DMA controler to the second
|
||||
dma_table db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A
|
||||
|
||||
my_service db 'SOUND',0 ;max 16 chars include zero
|
||||
|
||||
if DEBUG
|
||||
number_to_out db '0x00000000',13,10,0
|
||||
|
||||
msgInit db 'detecting hardware...',13,10,0
|
||||
msgExit db 'exiting... May be some problems found?',13,10,0
|
||||
msgPlay db 'start play',13,10,0
|
||||
;msgStop db 'stop play',13,10,0
|
||||
msgCallback db 'set_callback received from the mixer!',13,10
|
||||
db 'callback handler is: ',0
|
||||
msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10
|
||||
db 'owner',39,'s handler: ',0
|
||||
msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0')
|
||||
db ' as hardcoded',13,10,0
|
||||
msgErrRsrvPorts db 'failed to reserve needed ports.',13,10
|
||||
db 'Driver may work unstable',13,10,0
|
||||
msgSetVol db 'DEV_SET_MASTERVOL call came',13,10,0
|
||||
msgGetVol db 'DEV_GET_MASTERVOL call came',13,10,0
|
||||
msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0
|
||||
;-------------------------------------------------------------------------------
|
||||
msgDSPFound db 'DSP found at port 2'
|
||||
label port_second_digit_num dword at $
|
||||
db '00h',13,10,'DSP version '
|
||||
sb_DSP_version: db '0.00 - SB'
|
||||
sb_DSP_description: db 32,32,32,32,13,10,0
|
||||
;-------------------------------------------------------------------------------
|
||||
end if
|
||||
|
||||
section '.data' data readable writable align 16
|
||||
;all uninitialized data place here
|
||||
|
||||
;pTempBuf rd 1
|
||||
|
||||
callback rd 1
|
||||
|
||||
int_flip_flop rd 1
|
||||
|
||||
sb_master_vol rd 1
|
||||
|
||||
sb_DSP_version_int rd 1
|
177
kernel/branches/kolibri-cfg/drivers/sceletone.asm
Normal file
177
kernel/branches/kolibri-cfg/drivers/sceletone.asm
Normal file
@ -0,0 +1,177 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;driver sceletone
|
||||
|
||||
format MS COFF
|
||||
|
||||
DEBUG equ 1
|
||||
|
||||
API_VERSION equ 0 ;debug
|
||||
|
||||
include 'proc32.inc'
|
||||
include 'imports.inc'
|
||||
|
||||
OS_BASE equ 0;
|
||||
new_app_base equ 0x60400000
|
||||
PROC_BASE equ OS_BASE+0x0080000
|
||||
|
||||
struc IOCTL
|
||||
{ .handle dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
IOCTL IOCTL
|
||||
end virtual
|
||||
|
||||
public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
DRV_ENTRY equ 1
|
||||
DRV_EXIT equ -1
|
||||
STRIDE equ 4 ;size of row in devices table
|
||||
|
||||
SRV_GETVERSION equ 0
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
proc START stdcall, state:dword
|
||||
|
||||
cmp [state], 1
|
||||
jne .exit
|
||||
.entry:
|
||||
|
||||
if DEBUG
|
||||
mov esi, msgInit
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
|
||||
stdcall RegService, my_service, service_proc
|
||||
ret
|
||||
.fail:
|
||||
.exit:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
handle equ IOCTL.handle
|
||||
io_code equ IOCTL.io_code
|
||||
input equ IOCTL.input
|
||||
inp_size equ IOCTL.inp_size
|
||||
output equ IOCTL.output
|
||||
out_size equ IOCTL.out_size
|
||||
|
||||
align 4
|
||||
proc service_proc stdcall, ioctl:dword
|
||||
|
||||
mov ebx, [ioctl]
|
||||
mov eax, [ebx+io_code]
|
||||
cmp eax, SRV_GETVERSION
|
||||
jne @F
|
||||
|
||||
mov eax, [ebx+output]
|
||||
cmp [ebx+out_size], 4
|
||||
jne .fail
|
||||
mov [eax], dword API_VERSION
|
||||
xor eax, eax
|
||||
ret
|
||||
@@:
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
|
||||
restore handle
|
||||
restore io_code
|
||||
restore input
|
||||
restore inp_size
|
||||
restore output
|
||||
restore out_size
|
||||
|
||||
align 4
|
||||
proc detect
|
||||
locals
|
||||
last_bus dd ?
|
||||
endl
|
||||
|
||||
xor eax, eax
|
||||
mov [bus], eax
|
||||
inc eax
|
||||
call PciApi
|
||||
cmp eax, -1
|
||||
je .err
|
||||
|
||||
mov [last_bus], eax
|
||||
|
||||
.next_bus:
|
||||
and [devfn], 0
|
||||
.next_dev:
|
||||
stdcall PciRead32, [bus], [devfn], dword 0
|
||||
test eax, eax
|
||||
jz .next
|
||||
cmp eax, -1
|
||||
je .next
|
||||
|
||||
mov edi, devices
|
||||
@@:
|
||||
mov ebx, [edi]
|
||||
test ebx, ebx
|
||||
jz .next
|
||||
|
||||
cmp eax, ebx
|
||||
je .found
|
||||
|
||||
add edi, STRIDE
|
||||
jmp @B
|
||||
.next:
|
||||
inc [devfn]
|
||||
cmp [devfn], 256
|
||||
jb .next_dev
|
||||
mov eax, [bus]
|
||||
inc eax
|
||||
mov [bus], eax
|
||||
cmp eax, [last_bus]
|
||||
jna .next_bus
|
||||
xor eax, eax
|
||||
ret
|
||||
.found:
|
||||
xor eax, eax
|
||||
inc eax
|
||||
ret
|
||||
.err:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
DEVICE_ID equ 1234; pci device id
|
||||
VENDOR_ID equ 5678; device vendor id
|
||||
|
||||
|
||||
;all initialized data place here
|
||||
|
||||
align 4
|
||||
devices dd (DEVICE_ID shl 16)+VENDOR_ID
|
||||
dd 0 ;terminator
|
||||
|
||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||
|
||||
my_service db 'MY_SERVICE',0 ;max 16 chars include zero
|
||||
|
||||
msgInit db 'detect hardware...',13,10,0
|
||||
msgPCI db 'PCI accsess not supported',13,10,0
|
||||
msgFail db 'device not found',13,10,0
|
||||
|
||||
section '.data' data readable writable align 16
|
||||
|
||||
;all uninitialized data place here
|
||||
|
1307
kernel/branches/kolibri-cfg/drivers/sis.asm
Normal file
1307
kernel/branches/kolibri-cfg/drivers/sis.asm
Normal file
File diff suppressed because it is too large
Load Diff
1489
kernel/branches/kolibri-cfg/drivers/sound.asm
Normal file
1489
kernel/branches/kolibri-cfg/drivers/sound.asm
Normal file
File diff suppressed because it is too large
Load Diff
976
kernel/branches/kolibri-cfg/drivers/uart.asm
Normal file
976
kernel/branches/kolibri-cfg/drivers/uart.asm
Normal file
@ -0,0 +1,976 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
format MS COFF
|
||||
|
||||
DEBUG equ 1
|
||||
|
||||
include 'proc32.inc'
|
||||
include 'imports.inc'
|
||||
|
||||
|
||||
|
||||
API_VERSION equ 0
|
||||
UART_VERSION equ API_VERSION
|
||||
|
||||
PG_SW equ 0x003
|
||||
page_tabs equ 0xFDC00000 ;hack
|
||||
|
||||
OS_BASE equ 0x80000000
|
||||
SLOT_BASE equ (OS_BASE+0x0080000)
|
||||
TASK_COUNT equ (OS_BASE+0x0003004)
|
||||
CURRENT_TASK equ (OS_BASE+0x0003000)
|
||||
|
||||
|
||||
struc APPOBJ ;common object header
|
||||
{
|
||||
.magic dd ? ;
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
};
|
||||
|
||||
virtual at 0
|
||||
APPOBJ APPOBJ
|
||||
end virtual
|
||||
|
||||
struc IOCTL
|
||||
{ .handle dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
IOCTL IOCTL
|
||||
end virtual
|
||||
|
||||
DEBUG equ 1
|
||||
|
||||
DRV_ENTRY equ 1
|
||||
DRV_EXIT equ -1
|
||||
|
||||
THR_REG equ 0; x3f8 ;transtitter/reciever
|
||||
IER_REG equ 1; x3f9 ;interrupt enable
|
||||
IIR_REG equ 2; x3fA ;interrupt info
|
||||
LCR_REG equ 3; x3FB ;line control
|
||||
MCR_REG equ 4; x3FC ;modem control
|
||||
LSR_REG equ 5; x3FD ;line status
|
||||
MSR_REG equ 6; x3FE ;modem status
|
||||
|
||||
LCR_5BIT equ 0x00
|
||||
LCR_6BIT equ 0x01
|
||||
LCR_7BIT equ 0x02
|
||||
LCR_8BIT equ 0x03
|
||||
LCR_STOP_1 equ 0x00
|
||||
LCR_STOP_2 equ 0x04
|
||||
LCR_PARITY equ 0x08
|
||||
LCR_EVEN equ 0x10
|
||||
LCR_STICK equ 0x20
|
||||
LCR_BREAK equ 0x40
|
||||
LCR_DLAB equ 0x80
|
||||
|
||||
LSR_DR equ 0x01 ;data ready
|
||||
LSR_OE equ 0x02 ;overrun error
|
||||
LSR_PE equ 0x04 ;parity error
|
||||
LSR_FE equ 0x08 ;framing error
|
||||
LSR_BI equ 0x10 ;break interrupt
|
||||
LSR_THRE equ 0x20 ;transmitter holding empty
|
||||
LSR_TEMT equ 0x40 ;transmitter empty
|
||||
LSR_FER equ 0x80 ;FIFO error
|
||||
|
||||
FCR_EFIFO equ 0x01 ;enable FIFO
|
||||
FCR_CRB equ 0x02 ;clear reciever FIFO
|
||||
FCR_CXMIT equ 0x04 ;clear transmitter FIFO
|
||||
FCR_RDY equ 0x08 ;set RXRDY and TXRDY pins
|
||||
FCR_FIFO_1 equ 0x00 ;1 byte trigger
|
||||
FCR_FIFO_4 equ 0x40 ;4 bytes trigger
|
||||
FCR_FIFO_8 equ 0x80 ;8 bytes trigger
|
||||
FCR_FIFO_14 equ 0xC0 ;14 bytes trigger
|
||||
|
||||
IIR_INTR equ 0x01 ;1= no interrupts
|
||||
|
||||
IER_RDAI equ 0x01 ;reciever data interrupt
|
||||
IER_THRI equ 0x02 ;transmitter empty interrupt
|
||||
IER_LSI equ 0x04 ;line status interrupt
|
||||
IER_MSI equ 0x08 ;modem status interrupt
|
||||
|
||||
MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0
|
||||
MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0
|
||||
MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0
|
||||
MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0; enable intr
|
||||
MCR_LOOP equ 0x10 ;lopback mode
|
||||
|
||||
MSR_DCTS equ 0x01 ;delta clear to send
|
||||
MSR_DDSR equ 0x02 ;delta data set redy
|
||||
MSR_TERI equ 0x04 ;trailinh edge of ring
|
||||
MSR_DDCD equ 0x08 ;delta carrier detect
|
||||
|
||||
|
||||
RATE_50 equ 0
|
||||
RATE_75 equ 1
|
||||
RATE_110 equ 2
|
||||
RATE_134 equ 3
|
||||
RATE_150 equ 4
|
||||
RATE_300 equ 5
|
||||
RATE_600 equ 6
|
||||
RATE_1200 equ 7
|
||||
RATE_1800 equ 8
|
||||
RATE_2000 equ 9
|
||||
RATE_2400 equ 10
|
||||
RATE_3600 equ 11
|
||||
RATE_4800 equ 12
|
||||
RATE_7200 equ 13
|
||||
RATE_9600 equ 14
|
||||
RATE_19200 equ 15
|
||||
RATE_38400 equ 16
|
||||
RATE_57600 equ 17
|
||||
RATE_115200 equ 18
|
||||
|
||||
COM_1 equ 1
|
||||
COM_2 equ 2
|
||||
COM_3 equ 3
|
||||
COM_4 equ 4
|
||||
COM_MAX equ 2 ;only two port supported
|
||||
|
||||
COM_1_BASE equ 0x3F8
|
||||
COM_2_BASE equ 0x2F8
|
||||
|
||||
COM_1_IRQ equ 4
|
||||
COM_2_IRQ equ 3
|
||||
|
||||
UART_CLOSED equ 0
|
||||
UART_TRANSMIT equ 1
|
||||
UART_STOP equ 2
|
||||
|
||||
struc UART
|
||||
{
|
||||
.lock dd ?
|
||||
.base dd ?
|
||||
.lcr_reg dd ?
|
||||
.mcr_reg dd ?
|
||||
.rate dd ?
|
||||
.mode dd ?
|
||||
.state dd ?
|
||||
|
||||
.rcvr_buff dd ?
|
||||
.rcvr_rp dd ?
|
||||
.rcvr_wp dd ?
|
||||
.rcvr_count dd ?
|
||||
.rcvr_top dd ?
|
||||
|
||||
.xmit_buff dd ?
|
||||
.xmit_rp dd ?
|
||||
.xmit_wp dd ?
|
||||
.xmit_count dd ?
|
||||
.xmit_free dd ?
|
||||
.xmit_top dd ?
|
||||
}
|
||||
virtual at 0
|
||||
UART UART
|
||||
end virtual
|
||||
|
||||
UART_SIZE equ 18*4
|
||||
|
||||
struc CONNECTION
|
||||
{
|
||||
.magic dd ? ;'CNCT'
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
|
||||
.id dd ? ;reserved
|
||||
.uart dd ? ;uart pointer
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
CONNECTION CONNECTION
|
||||
end virtual
|
||||
|
||||
CONNECTION_SIZE equ 7*4
|
||||
|
||||
public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
proc START stdcall, state:dword
|
||||
|
||||
cmp [state], 1
|
||||
jne .stop
|
||||
|
||||
mov eax, UART_SIZE
|
||||
call Kmalloc
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [com1], eax
|
||||
mov edi, eax
|
||||
mov ecx, UART_SIZE/4
|
||||
xor eax, eax
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov eax, [com1]
|
||||
mov [eax+UART.base], COM_1_BASE
|
||||
|
||||
stdcall AllocKernelSpace, 32768
|
||||
|
||||
mov edi, [com1]
|
||||
mov edx, eax
|
||||
|
||||
mov [edi+UART.rcvr_buff], eax
|
||||
add eax, 8192
|
||||
mov [edi+UART.rcvr_top], eax
|
||||
add eax, 8192
|
||||
mov [edi+UART.xmit_buff], eax
|
||||
add eax, 8192
|
||||
mov [edi+UART.xmit_top], eax
|
||||
|
||||
call AllocPage
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
shr edx, 12
|
||||
or eax, PG_SW
|
||||
mov [page_tabs+edx*4], eax
|
||||
mov [page_tabs+edx*4+8], eax
|
||||
|
||||
call AllocPage
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
or eax, PG_SW
|
||||
mov [page_tabs+edx*4+4], eax
|
||||
mov [page_tabs+edx*4+12], eax
|
||||
|
||||
call AllocPage
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
or eax, PG_SW
|
||||
mov [page_tabs+edx*4+16], eax
|
||||
mov [page_tabs+edx*4+24], eax
|
||||
|
||||
call AllocPage
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
or eax, PG_SW
|
||||
mov [page_tabs+edx*4+20], eax
|
||||
mov [page_tabs+edx*4+28], eax
|
||||
|
||||
mov eax, [edi+UART.rcvr_buff]
|
||||
invlpg [eax]
|
||||
invlpg [eax+0x1000]
|
||||
invlpg [eax+0x2000]
|
||||
invlpg [eax+0x3000]
|
||||
invlpg [eax+0x4000]
|
||||
invlpg [eax+0x5000]
|
||||
invlpg [eax+0x6000]
|
||||
invlpg [eax+0x7000]
|
||||
|
||||
mov eax, edi
|
||||
call uart_reset.internal ;eax= uart
|
||||
|
||||
stdcall AttachIntHandler, COM_1_IRQ, com_1_isr, dword 0
|
||||
stdcall RegService, sz_uart_srv, service_proc
|
||||
ret
|
||||
.fail:
|
||||
.stop:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
handle equ IOCTL.handle
|
||||
io_code equ IOCTL.io_code
|
||||
input equ IOCTL.input
|
||||
inp_size equ IOCTL.inp_size
|
||||
output equ IOCTL.output
|
||||
out_size equ IOCTL.out_size
|
||||
|
||||
SRV_GETVERSION equ 0
|
||||
PORT_OPEN equ 1
|
||||
PORT_CLOSE equ 2
|
||||
PORT_RESET equ 3
|
||||
PORT_SETMODE equ 4
|
||||
PORT_GETMODE equ 5
|
||||
PORT_SETMCR equ 6
|
||||
PORT_GETMCR equ 7
|
||||
PORT_READ equ 8
|
||||
PORT_WRITE equ 9
|
||||
|
||||
align 4
|
||||
proc service_proc stdcall, ioctl:dword
|
||||
|
||||
mov ebx, [ioctl]
|
||||
mov eax, [ebx+io_code]
|
||||
cmp eax, PORT_WRITE
|
||||
ja .fail
|
||||
|
||||
cmp eax, SRV_GETVERSION
|
||||
jne @F
|
||||
|
||||
mov eax, [ebx+output]
|
||||
cmp [ebx+out_size], 4
|
||||
jne .fail
|
||||
mov [eax], dword UART_VERSION
|
||||
xor eax, eax
|
||||
ret
|
||||
@@:
|
||||
cmp eax, PORT_OPEN
|
||||
jne @F
|
||||
|
||||
cmp [ebx+out_size], 4
|
||||
jne .fail
|
||||
|
||||
mov ebx, [ebx+input]
|
||||
mov eax, [ebx]
|
||||
call uart_open
|
||||
mov ebx, [ioctl]
|
||||
mov ebx, [ebx+output]
|
||||
mov [ebx], ecx
|
||||
ret
|
||||
@@:
|
||||
mov esi, [ebx+input] ;input buffer
|
||||
mov edi, [ebx+output]
|
||||
call [uart_func+eax*4]
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
endp
|
||||
|
||||
restore handle
|
||||
restore io_code
|
||||
restore input
|
||||
restore inp_size
|
||||
restore output
|
||||
restore out_size
|
||||
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
;
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_reset:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
; set mode 2400 bod 8-bit
|
||||
; disable DTR & RTS
|
||||
; clear FIFO
|
||||
; clear pending interrupts
|
||||
;
|
||||
; param
|
||||
; eax= uart
|
||||
|
||||
align 4
|
||||
.internal:
|
||||
mov esi, eax
|
||||
mov [eax+UART.state], UART_CLOSED
|
||||
mov edx, [eax+UART.base]
|
||||
add edx, MCR_REG
|
||||
xor eax, eax
|
||||
out dx, al ;clear DTR & RTS
|
||||
|
||||
mov eax, esi
|
||||
mov ebx, RATE_2400
|
||||
mov ecx, LCR_8BIT+LCR_STOP_1
|
||||
call uart_set_mode.internal
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, IIR_REG
|
||||
mov eax,FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14
|
||||
out dx, al
|
||||
.clear_RB:
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, LSR_REG
|
||||
in al, dx
|
||||
test eax, LSR_DR
|
||||
jz @F
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
in al, dx
|
||||
jmp .clear_RB
|
||||
@@:
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, IER_REG
|
||||
mov eax,IER_RDAI+IER_THRI+IER_LSI
|
||||
out dx, al
|
||||
.clear_IIR:
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, IIR_REG
|
||||
in al, dx
|
||||
test al, IIR_INTR
|
||||
jnz .done
|
||||
|
||||
shr eax, 1
|
||||
and eax, 3
|
||||
jnz @F
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, MSR_REG
|
||||
in al, dx
|
||||
jmp .clear_IIR
|
||||
@@:
|
||||
cmp eax, 1
|
||||
je .clear_IIR
|
||||
|
||||
cmp eax, 2
|
||||
jne @F
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
in al, dx
|
||||
jmp .clear_IIR
|
||||
@@:
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, LSR_REG
|
||||
in al, dx
|
||||
jmp .clear_IIR
|
||||
.done:
|
||||
mov edi, [esi+UART.rcvr_buff]
|
||||
mov ecx, 8192/4
|
||||
xor eax, eax
|
||||
|
||||
mov [esi+UART.rcvr_rp], edi
|
||||
mov [esi+UART.rcvr_wp], edi
|
||||
mov [esi+UART.rcvr_count], eax
|
||||
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov edi, [esi+UART.xmit_buff]
|
||||
mov ecx, 8192/4
|
||||
|
||||
mov [esi+UART.xmit_rp], edi
|
||||
mov [esi+UART.xmit_wp], edi
|
||||
mov [esi+UART.xmit_count], eax
|
||||
mov [esi+UART.xmit_free], 8192
|
||||
|
||||
rep stosd
|
||||
ret ;eax= 0
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
; +4 rate
|
||||
; +8 mode
|
||||
;
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_set_mode:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [esi+4]
|
||||
mov ecx, [esi+8]
|
||||
|
||||
; param
|
||||
; eax= uart
|
||||
; ebx= baud rate
|
||||
; ecx= mode
|
||||
|
||||
align 4
|
||||
.internal:
|
||||
cmp ebx, RATE_115200
|
||||
ja .fail
|
||||
|
||||
cmp ecx, LCR_BREAK
|
||||
jae .fail
|
||||
|
||||
mov [eax+UART.rate], ebx
|
||||
mov [eax+UART.mode], ecx
|
||||
|
||||
mov esi, eax
|
||||
mov bx, [divisor+ebx*2]
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
push edx
|
||||
add edx, LCR_REG
|
||||
in al, dx
|
||||
or al, 0x80
|
||||
out dx, al
|
||||
|
||||
pop edx
|
||||
mov al, bl
|
||||
out dx, al
|
||||
|
||||
inc dx
|
||||
mov al, bh
|
||||
out dx, al
|
||||
|
||||
add edx, LCR_REG-1
|
||||
mov eax, ecx
|
||||
out dx, al
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
; +4 modem control reg valie
|
||||
;
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_set_mcr:
|
||||
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [esi+4]
|
||||
|
||||
mov [eax+UART.mcr_reg], ebx
|
||||
mov edx, [eax+UART.base]
|
||||
add edx, MCR_REG
|
||||
mov al, bl
|
||||
out dx, al
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
; param
|
||||
; eax= port
|
||||
;
|
||||
; retval
|
||||
; ecx= connection
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_open:
|
||||
dec eax
|
||||
cmp eax, COM_MAX
|
||||
jae .fail
|
||||
|
||||
mov esi, [com1+eax*4] ;uart
|
||||
push esi
|
||||
.do_wait:
|
||||
cmp dword [esi+UART.lock],0
|
||||
je .get_lock
|
||||
; call change_task
|
||||
jmp .do_wait
|
||||
.get_lock:
|
||||
mov eax, 1
|
||||
xchg eax, [esi+UART.lock]
|
||||
test eax, eax
|
||||
jnz .do_wait
|
||||
|
||||
mov eax, esi ;uart
|
||||
call uart_reset.internal
|
||||
|
||||
mov ebx, [CURRENT_TASK]
|
||||
shl ebx, 5
|
||||
mov ebx, [CURRENT_TASK+ebx+4]
|
||||
mov eax, CONNECTION_SIZE
|
||||
call CreateObject
|
||||
pop esi ;uart
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [eax+APPOBJ.magic], 'CNCT'
|
||||
mov [eax+APPOBJ.destroy], uart_close.destroy
|
||||
mov [eax+CONNECTION.uart], esi
|
||||
mov ecx, eax
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
restore .uart
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
|
||||
align 4
|
||||
uart_close:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
.destroy:
|
||||
push [eax+CONNECTION.uart]
|
||||
call DestroyObject ;eax= object
|
||||
pop eax ;eax= uart
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [eax+UART.state], UART_CLOSED
|
||||
mov [eax+UART.lock], 0 ;release port
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
|
||||
; param
|
||||
; eax= uart
|
||||
; ebx= baud rate
|
||||
|
||||
align 4
|
||||
set_rate:
|
||||
cmp ebx, RATE_115200
|
||||
ja .fail
|
||||
|
||||
mov [eax+UART.rate], ebx
|
||||
mov bx, [divisor+ebx*2]
|
||||
|
||||
mov edx, [eax+UART.base]
|
||||
add edx, LCR_REG
|
||||
in al, dx
|
||||
push eax
|
||||
or al, 0x80
|
||||
out dx, al
|
||||
|
||||
sub edx, LCR_REG
|
||||
mov al, bl
|
||||
out dx, al
|
||||
|
||||
inc edx
|
||||
mov al, bh
|
||||
out dx, al
|
||||
|
||||
pop eax
|
||||
add edx, LCR_REG-1
|
||||
out dx, al
|
||||
.fail:
|
||||
ret
|
||||
|
||||
|
||||
; param
|
||||
; ebx= uart
|
||||
|
||||
align 4
|
||||
transmit:
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov edx, [ebx+UART.base]
|
||||
|
||||
pushfd
|
||||
cli
|
||||
|
||||
mov esi, [ebx+UART.xmit_rp]
|
||||
mov ecx, [ebx+UART.xmit_count]
|
||||
test ecx, ecx
|
||||
je .stop
|
||||
|
||||
cmp ecx, 16
|
||||
jbe @F
|
||||
mov ecx, 16
|
||||
@@:
|
||||
sub [ebx+UART.xmit_count], ecx
|
||||
add [ebx+UART.xmit_free], ecx
|
||||
cld
|
||||
@@:
|
||||
lodsb
|
||||
out dx, al
|
||||
dec ecx
|
||||
jnz @B
|
||||
|
||||
cmp esi,[ebx+UART.xmit_top]
|
||||
jb @F
|
||||
sub esi, 8192
|
||||
@@:
|
||||
mov [ebx+UART.xmit_rp], esi
|
||||
|
||||
cmp [ebx+UART.xmit_count], 0
|
||||
je .stop
|
||||
|
||||
mov [ebx+UART.state], UART_TRANSMIT
|
||||
jmp @F
|
||||
.stop:
|
||||
mov [ebx+UART.state], UART_STOP
|
||||
@@:
|
||||
popfd
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
; +4 dst buffer
|
||||
; +8 dst size
|
||||
; edi= output buffer
|
||||
; +0 bytes read
|
||||
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_read:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [esi+8] ;dst size
|
||||
mov ecx, [eax+UART.rcvr_count]
|
||||
cmp ecx, ebx
|
||||
jbe @F
|
||||
mov ecx, ebx
|
||||
@@:
|
||||
mov [edi], ecx ;bytes read
|
||||
test ecx, ecx
|
||||
jz .done
|
||||
|
||||
push ecx
|
||||
|
||||
mov edi, [esi+4] ;dst
|
||||
mov esi, [eax+UART.rcvr_rp]
|
||||
cld
|
||||
rep movsb
|
||||
pop ecx
|
||||
|
||||
cmp esi, [eax+UART.rcvr_top]
|
||||
jb @F
|
||||
sub esi, 8192
|
||||
@@:
|
||||
mov [eax+UART.rcvr_rp], esi
|
||||
sub [eax+UART.rcvr_count], ecx
|
||||
.done:
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
; +4 src buffer
|
||||
; +8 src size
|
||||
;
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_write:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [esi+4]
|
||||
mov edx, [esi+8]
|
||||
|
||||
; param
|
||||
; eax= uart
|
||||
; ebx= src
|
||||
; edx= count
|
||||
|
||||
align 4
|
||||
.internal:
|
||||
mov esi, ebx
|
||||
mov edi, [eax+UART.xmit_wp]
|
||||
.write:
|
||||
test edx, edx
|
||||
jz .fail
|
||||
.wait:
|
||||
cmp [eax+UART.xmit_free], 0
|
||||
jne .fill
|
||||
|
||||
cmp [eax+UART.state], UART_TRANSMIT
|
||||
je .wait
|
||||
|
||||
mov ebx, eax
|
||||
push edx
|
||||
call transmit
|
||||
pop edx
|
||||
mov eax, ebx
|
||||
jmp .write
|
||||
.fill:
|
||||
mov ecx, [eax+UART.xmit_free]
|
||||
cmp ecx, edx
|
||||
jbe @F
|
||||
mov ecx, edx
|
||||
@@:
|
||||
push ecx
|
||||
cld
|
||||
rep movsb
|
||||
pop ecx
|
||||
sub [eax+UART.xmit_free], ecx
|
||||
add [eax+UART.xmit_count], ecx
|
||||
sub edx, ecx
|
||||
jnz .wait
|
||||
.done:
|
||||
cmp edi, [eax+UART.xmit_top]
|
||||
jb @F
|
||||
sub edi, 8192
|
||||
@@:
|
||||
mov [eax+UART.xmit_wp], edi
|
||||
cmp [eax+UART.state], UART_TRANSMIT
|
||||
je @F
|
||||
mov ebx, eax
|
||||
call transmit
|
||||
@@:
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
com_2_isr:
|
||||
mov ebx, [com2]
|
||||
jmp com_1_isr.get_info
|
||||
align 4
|
||||
com_1_isr:
|
||||
mov ebx, [com1]
|
||||
.get_info:
|
||||
mov edx, [ebx+UART.base]
|
||||
add edx, IIR_REG
|
||||
in al, dx
|
||||
|
||||
test al, IIR_INTR
|
||||
jnz .done
|
||||
|
||||
shr eax, 1
|
||||
and eax, 3
|
||||
|
||||
call [isr_action+eax*4]
|
||||
jmp .get_info
|
||||
.done:
|
||||
ret
|
||||
|
||||
align 4
|
||||
isr_line:
|
||||
mov edx, [ebx+UART.base]
|
||||
add edx, LSR_REG
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
align 4
|
||||
isr_recieve:
|
||||
mov esi, [ebx+UART.base]
|
||||
add esi, LSR_REG
|
||||
mov edi, [ebx+UART.rcvr_wp]
|
||||
xor ecx, ecx
|
||||
cld
|
||||
.read:
|
||||
mov edx, esi
|
||||
in al, dx
|
||||
test eax, LSR_DR
|
||||
jz .done
|
||||
|
||||
mov edx, [ebx+UART.base]
|
||||
in al, dx
|
||||
stosb
|
||||
inc ecx
|
||||
jmp .read
|
||||
.done:
|
||||
cmp edi, [ebx+UART.rcvr_top]
|
||||
jb @F
|
||||
sub edi, 8192
|
||||
@@:
|
||||
mov [ebx+UART.rcvr_wp], edi
|
||||
add [ebx+UART.rcvr_count], ecx
|
||||
ret
|
||||
|
||||
align 4
|
||||
isr_modem:
|
||||
mov edx, [ebx+UART.base]
|
||||
add edx, MSR_REG
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
divisor dw 2304, 1536, 1047, 857, 768, 384
|
||||
dw 192, 96, 64, 58, 48, 32
|
||||
dw 24, 16, 12, 6, 3, 2, 1
|
||||
|
||||
align 4
|
||||
uart_func dd 0 ;SRV_GETVERSION
|
||||
dd 0 ;PORT_OPEN
|
||||
dd uart_close ;PORT_CLOSE
|
||||
dd uart_reset ;PORT_RESET
|
||||
dd uart_set_mode ;PORT_SETMODE
|
||||
dd 0 ;PORT_GETMODE
|
||||
dd uart_set_mcr ;PORT_SETMODEM
|
||||
dd 0 ;PORT_GETMODEM
|
||||
dd uart_read ;PORT_READ
|
||||
dd uart_write ;PORT_WRITE
|
||||
|
||||
isr_action dd isr_modem
|
||||
dd transmit
|
||||
dd isr_recieve
|
||||
dd isr_line
|
||||
|
||||
version dd (5 shl 16) or (UART_VERSION and 0xFFFF)
|
||||
|
||||
sz_uart_srv db 'UART',0
|
||||
|
||||
align 4
|
||||
|
||||
com1 rd 1
|
||||
com2 rd 1
|
||||
|
115
kernel/branches/kolibri-cfg/drivers/usb/urb.inc
Normal file
115
kernel/branches/kolibri-cfg/drivers/usb/urb.inc
Normal file
@ -0,0 +1,115 @@
|
||||
|
||||
struc URB
|
||||
{
|
||||
.fd dd ?
|
||||
.bk dd ?
|
||||
.dev dd ? ; pointer to associated device
|
||||
.pipe dd ? ; pipe information
|
||||
.status dd ? ; non-ISO status
|
||||
.transfer_flags dd ? ; URB_SHORT_NOT_OK | ...
|
||||
.transfer_buffer dd ? ; associated data buffer
|
||||
.transfer_dma dd ? ; dma addr for transfer_buffer
|
||||
.transfer_buffer_length dd ? ; data buffer length
|
||||
.actual_length dd ? ; actual transfer length
|
||||
.setup_packet dd ? ; setup packet (control only)
|
||||
.setup_dma dd ? ; dma addr for setup_packet
|
||||
.start_frame dd ? ; start frame (ISO)
|
||||
.number_of_packets dd ? ; number of ISO packets
|
||||
.interval dd ? ; transfer interval
|
||||
|
||||
.error_count dd ? ; number of ISO errors
|
||||
.context dd ? ; context for completion
|
||||
.complete dd ? ; (in) completion routine
|
||||
.iso_frame_desc:
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
URB URB
|
||||
end virtual
|
||||
|
||||
|
||||
struc REQ ;usb request
|
||||
{
|
||||
.request_type db ?
|
||||
.request db ?
|
||||
.value dw ?
|
||||
.index dw ?
|
||||
.length dw ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
REQ REQ
|
||||
end virtual
|
||||
|
||||
align 4
|
||||
proc usb_control_msg stdcall, dev:dword, pipe:dword, request:dword,\
|
||||
requesttype:dword, value:dword, index:dword,\
|
||||
data:dword, size:dword, timeout:dword
|
||||
|
||||
locals
|
||||
req REQ
|
||||
endl
|
||||
|
||||
lea eax, [req]
|
||||
mov ecx, [request]
|
||||
mov ebx, [requesttupe]
|
||||
mov edx, [value]
|
||||
mov esi, [index]
|
||||
mov edi, [size]
|
||||
|
||||
mov [eax+REQ.request_type], bl
|
||||
mov [eax+REQ.request], cl
|
||||
mov [eax+REQ.value], dx
|
||||
mov [eax+REQ.index], si
|
||||
mov [eax+REQ.length], di
|
||||
|
||||
stdcall usb_internal_control_msg, [dev], [pipe],\
|
||||
eax, [data], [size], [timeout]
|
||||
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
; returns status (negative) or length (positive)
|
||||
static int usb_internal_control_msg(struct usb_device *usb_dev,
|
||||
unsigned int pipe,
|
||||
struct usb_ctrlrequest *cmd,
|
||||
void *data, int len, int timeout)
|
||||
{
|
||||
struct urb *urb;
|
||||
int retv;
|
||||
int length;
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_NOIO);
|
||||
if (!urb)
|
||||
return -ENOMEM;
|
||||
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
|
||||
len, usb_api_blocking_completion, NULL);
|
||||
|
||||
retv = usb_start_wait_urb(urb, timeout, &length);
|
||||
if (retv < 0)
|
||||
return retv;
|
||||
else
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
void usb_fill_control_urb (struct urb *urb,
|
||||
struct usb_device *dev,
|
||||
unsigned int pipe,
|
||||
unsigned char *setup_packet,
|
||||
void *transfer_buffer,
|
||||
int buffer_length,
|
||||
usb_complete_t complete_fn,
|
||||
void *context)
|
||||
{
|
||||
|
||||
urb->dev = dev;
|
||||
urb->pipe = pipe;
|
||||
urb->setup_packet = setup_packet;
|
||||
urb->transfer_buffer = transfer_buffer;
|
||||
urb->transfer_buffer_length = buffer_length;
|
||||
urb->complete = complete_fn;
|
||||
urb->context = context;
|
||||
}
|
||||
|
435
kernel/branches/kolibri-cfg/drivers/usb/usb.asm
Normal file
435
kernel/branches/kolibri-cfg/drivers/usb/usb.asm
Normal file
@ -0,0 +1,435 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;driver sceletone
|
||||
|
||||
format MS COFF
|
||||
|
||||
API_VERSION equ 0 ;debug
|
||||
|
||||
include '../proc32.inc'
|
||||
include '../imports.inc'
|
||||
include 'urb.inc'
|
||||
|
||||
struc UHCI
|
||||
{
|
||||
.bus dd ?
|
||||
.devfn dd ?
|
||||
.io_base dd ?
|
||||
.mm_base dd ?
|
||||
.irq dd ?
|
||||
.flags dd ?
|
||||
.reset dd ?
|
||||
.start dd ?
|
||||
.stop dd ?
|
||||
|
||||
.port_c_suspend dd ?
|
||||
.resuming_ports dd ?
|
||||
.rh_state dd ?
|
||||
.rh_numports dd ?
|
||||
.is_stopped dd ?
|
||||
.dead dd ?
|
||||
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
UHCI UHCI
|
||||
end virtual
|
||||
|
||||
struc IOCTL
|
||||
{ .handle dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
IOCTL IOCTL
|
||||
end virtual
|
||||
|
||||
struc TD ;transfer descriptor
|
||||
{
|
||||
.link dd ?
|
||||
.status dd ?
|
||||
.token dd ?
|
||||
.buffer dd ?
|
||||
|
||||
.addr dd ?
|
||||
.frame dd ?
|
||||
.fd dd ?
|
||||
.bk dd ?
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
TD TD
|
||||
end virtual
|
||||
|
||||
public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
DEBUG equ 1
|
||||
|
||||
DRV_ENTRY equ 1
|
||||
DRV_EXIT equ -1
|
||||
STRIDE equ 4 ;size of row in devices table
|
||||
|
||||
SRV_GETVERSION equ 0
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
proc START stdcall, state:dword
|
||||
|
||||
cmp [state], 1
|
||||
jne .exit
|
||||
.entry:
|
||||
|
||||
if DEBUG
|
||||
mov esi, msgInit
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
|
||||
call init
|
||||
|
||||
stdcall RegService, my_service, service_proc
|
||||
ret
|
||||
.fail:
|
||||
.exit:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
handle equ IOCTL.handle
|
||||
io_code equ IOCTL.io_code
|
||||
input equ IOCTL.input
|
||||
inp_size equ IOCTL.inp_size
|
||||
output equ IOCTL.output
|
||||
out_size equ IOCTL.out_size
|
||||
|
||||
align 4
|
||||
proc service_proc stdcall, ioctl:dword
|
||||
|
||||
mov ebx, [ioctl]
|
||||
mov eax, [ebx+io_code]
|
||||
cmp eax, SRV_GETVERSION
|
||||
jne @F
|
||||
|
||||
mov eax, [ebx+output]
|
||||
cmp [ebx+out_size], 4
|
||||
jne .fail
|
||||
mov [eax], dword API_VERSION
|
||||
xor eax, eax
|
||||
ret
|
||||
@@:
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
|
||||
restore handle
|
||||
restore io_code
|
||||
restore input
|
||||
restore inp_size
|
||||
restore output
|
||||
restore out_size
|
||||
|
||||
align 4
|
||||
proc detect
|
||||
locals
|
||||
last_bus dd ?
|
||||
bus dd ?
|
||||
devfn dd ?
|
||||
endl
|
||||
|
||||
xor eax, eax
|
||||
mov [bus], eax
|
||||
inc eax
|
||||
call PciApi
|
||||
cmp eax, -1
|
||||
je .err
|
||||
|
||||
mov [last_bus], eax
|
||||
|
||||
.next_bus:
|
||||
and [devfn], 0
|
||||
.next_dev:
|
||||
stdcall PciRead32, [bus], [devfn], dword 0
|
||||
test eax, eax
|
||||
jz .next
|
||||
cmp eax, -1
|
||||
je .next
|
||||
|
||||
mov edi, devices
|
||||
@@:
|
||||
mov ebx, [edi]
|
||||
test ebx, ebx
|
||||
jz .next
|
||||
|
||||
cmp eax, ebx
|
||||
je .found
|
||||
|
||||
add edi, STRIDE
|
||||
jmp @B
|
||||
.next:
|
||||
inc [devfn]
|
||||
cmp [devfn], 256
|
||||
jb .next_dev
|
||||
mov eax, [bus]
|
||||
inc eax
|
||||
mov [bus], eax
|
||||
cmp eax, [last_bus]
|
||||
jna .next_bus
|
||||
xor eax, eax
|
||||
ret
|
||||
.found:
|
||||
mov eax, UHCI.sizeof
|
||||
call Kmalloc
|
||||
test eax, eax
|
||||
jz .mem_fail
|
||||
|
||||
mov ebx, [bus]
|
||||
mov [eax+UHCI.bus], ebx
|
||||
|
||||
mov ecx, [devfn]
|
||||
mov [eax+UHCI.devfn], ecx
|
||||
ret
|
||||
.mem_fail:
|
||||
if DEBUG
|
||||
mov esi, msgMemFail
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
.err:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
PCI_BASE equ 0x20
|
||||
USB_LEGKEY equ 0xC0
|
||||
|
||||
align 4
|
||||
proc init
|
||||
locals
|
||||
uhci dd ?
|
||||
endl
|
||||
|
||||
call detect
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [uhci], eax
|
||||
|
||||
stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE
|
||||
and eax, 0xFFC0
|
||||
mov esi, [uhci]
|
||||
mov [esi+UHCI.io_base], eax
|
||||
|
||||
stdcall uhci_reset, esi
|
||||
|
||||
stdcall finish_reset, [uhci]
|
||||
|
||||
.fail:
|
||||
if DEBUG
|
||||
mov esi, msgDevNotFound
|
||||
call SysMsgBoardStr
|
||||
end if
|
||||
ret
|
||||
endp
|
||||
|
||||
UHCI_USBINTR equ 4 ; interrupt register
|
||||
|
||||
UHCI_USBLEGSUP_RWC equ 0x8f00 ; the R/WC bits
|
||||
UHCI_USBLEGSUP_RO equ 0x5040 ; R/O and reserved bits
|
||||
|
||||
UHCI_USBCMD_RUN equ 0x0001 ; RUN/STOP bit
|
||||
UHCI_USBCMD_HCRESET equ 0x0002 ; Host Controller reset
|
||||
UHCI_USBCMD_EGSM equ 0x0008 ; Global Suspend Mode
|
||||
UHCI_USBCMD_CONFIGURE equ 0x0040 ; Config Flag
|
||||
UHCI_USBINTR_RESUME equ 0x0002 ; Resume interrupt enable
|
||||
|
||||
PORTSC0 equ 0x10
|
||||
PORTSC1 equ 0x12
|
||||
|
||||
|
||||
UHCI_RH_RESET equ 0
|
||||
UHCI_RH_SUSPENDED equ 1
|
||||
UHCI_RH_AUTO_STOPPED equ 2
|
||||
UHCI_RH_RESUMING equ 3
|
||||
|
||||
; In this state the HC changes from running to halted
|
||||
; so it can legally appear either way.
|
||||
UHCI_RH_SUSPENDING equ 4
|
||||
|
||||
; In the following states it's an error if the HC is halted.
|
||||
; These two must come last.
|
||||
UHCI_RH_RUNNING equ 5 ; The normal state
|
||||
UHCI_RH_RUNNING_NODEVS equ 6 ; Running with no devices
|
||||
|
||||
UHCI_IS_STOPPED equ 9999
|
||||
|
||||
align 4
|
||||
proc uhci_reset stdcall, uhci:dword
|
||||
mov esi, [uhci]
|
||||
stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY
|
||||
test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC)
|
||||
jnz .reset
|
||||
|
||||
mov edx, [esi+UHCI.io_base]
|
||||
in ax, dx
|
||||
test ax, UHCI_USBCMD_RUN
|
||||
jnz .reset
|
||||
|
||||
test ax, UHCI_USBCMD_CONFIGURE
|
||||
jz .reset
|
||||
|
||||
test ax, UHCI_USBCMD_EGSM
|
||||
jz .reset
|
||||
|
||||
add edx, UHCI_USBINTR
|
||||
in ax, dx
|
||||
test ax, not UHCI_USBINTR_RESUME
|
||||
jnz .reset
|
||||
ret
|
||||
.reset:
|
||||
stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC
|
||||
|
||||
mov edx, [esi+UHCI.io_base]
|
||||
mov ax, UHCI_USBCMD_HCRESET
|
||||
out dx, ax
|
||||
|
||||
xor eax, eax
|
||||
out dx, ax
|
||||
add edx, UHCI_USBINTR
|
||||
out dx, ax
|
||||
ret
|
||||
endp
|
||||
|
||||
proc finish_reset stdcall, uhci:dword
|
||||
|
||||
mov esi, [uhci]
|
||||
mov edx, [esi+UHCI.io_base]
|
||||
add edx, PORTSC0
|
||||
xor eax, eax
|
||||
out dx, ax
|
||||
add edx, (PORTSC1-PORTSC0)
|
||||
out dx, ax
|
||||
|
||||
mov [esi+UHCI.port_c_suspend], eax
|
||||
mov [esi+UHCI.resuming_ports], eax
|
||||
mov [esi+UHCI.rh_state], UHCI_RH_RESET
|
||||
mov [esi+UHCI.rh_numports], 2
|
||||
|
||||
mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED
|
||||
; mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT;
|
||||
; uhci_to_hcd(uhci)->poll_rh = 0;
|
||||
|
||||
mov [esi+UHCI.dead], eax ; Full reset resurrects the controller
|
||||
|
||||
ret
|
||||
endp
|
||||
|
||||
proc insert_td stdcall, td:dword, frame:dword
|
||||
|
||||
mov edi, [td]
|
||||
mov eax, [frame]
|
||||
and eax, -1024
|
||||
mov [edi+TD.frame], eax
|
||||
|
||||
mov ebx, [framelist]
|
||||
mov edx, [dma_framelist]
|
||||
shl eax, 5
|
||||
|
||||
mov ecx, [eax+ebx]
|
||||
test ecx, ecx
|
||||
jz .empty
|
||||
|
||||
mov ecx, [ecx+TD.bk] ;last TD
|
||||
|
||||
mov edx, [ecx+TD.fd]
|
||||
mov [edi+TD.fd], edx
|
||||
mov [edi+TD.bk], ecx
|
||||
mov [ecx+TD.fd], edi
|
||||
mov [edx+TD.bk], edi
|
||||
|
||||
mov eax, [ecx+TD.link]
|
||||
mov [edi+TD.link], eax
|
||||
mov ebx, [edi+TD.addr]
|
||||
mov [ecx+TD.link], ebx
|
||||
ret
|
||||
.empty:
|
||||
mov ecx, [eax+edx]
|
||||
mov [edi+TD.link], ecx
|
||||
mov [ebx+eax], edi
|
||||
mov ecx, [edi+TD.addr]
|
||||
mov [eax+edx], ecx
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
align 4
|
||||
proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\
|
||||
buf:dword, size:dword
|
||||
|
||||
locals
|
||||
count dd ?
|
||||
endl
|
||||
|
||||
mov esi, [buf]
|
||||
mov ecx, [size]
|
||||
xor eax, eax
|
||||
cld
|
||||
rep stosb
|
||||
|
||||
mov [count], 3
|
||||
@@:
|
||||
mov eax, [type]
|
||||
shl eax, 8
|
||||
add eax, [index]
|
||||
stdcall usb_control_msg, [dev],pipe,USB_REQ_GET_DESCRIPTOR,\
|
||||
USB_DIR_IN, eax,0,[buf], [size],\
|
||||
USB_CTRL_GET_TIMEOUT
|
||||
test eax, eax
|
||||
jz .next
|
||||
cmp eax, -1
|
||||
je .next
|
||||
jmp. ok
|
||||
.next:
|
||||
dec [count]
|
||||
jnz @B
|
||||
mov eax, -1
|
||||
.ok:
|
||||
ret
|
||||
endp
|
||||
|
||||
DEVICE_ID equ 0x24D2 ; pci device id
|
||||
VENDOR_ID equ 0x8086 ; device vendor id
|
||||
QEMU_USB equ 0x7020
|
||||
|
||||
;all initialized data place here
|
||||
|
||||
align 4
|
||||
devices dd (DEVICE_ID shl 16)+VENDOR_ID
|
||||
dd (QEMU_USB shl 16)+VENDOR_ID
|
||||
dd 0 ;terminator
|
||||
|
||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||
|
||||
my_service db 'UHCI',0 ;max 16 chars include zero
|
||||
|
||||
msgInit db 'detect hardware...',13,10,0
|
||||
msgPCI db 'PCI accsess not supported',13,10,0
|
||||
msgDevNotFound db 'device not found',13,10,0
|
||||
msgMemFail db 'Kmalloc failed', 10,10,0
|
||||
;msgFail db 'device not found',13,10,0
|
||||
|
||||
section '.data' data readable writable align 16
|
||||
|
||||
;all uninitialized data place here
|
||||
|
465
kernel/branches/kolibri-cfg/drivers/vidintel.asm
Normal file
465
kernel/branches/kolibri-cfg/drivers/vidintel.asm
Normal file
@ -0,0 +1,465 @@
|
||||
; Stub of videodriver for Intel videocards.
|
||||
; (c) CleverMouse
|
||||
|
||||
; When the start procedure gots control,
|
||||
; it tries to detect preferred resolution,
|
||||
; sets the detected resolution assuming 32-bpp VESA mode and exits
|
||||
; (without registering a service).
|
||||
; Detection can be overloaded with compile-time settings
|
||||
; use_predefined_mode/predefined_width/predefined_height.
|
||||
|
||||
; set predefined resolution here
|
||||
use_predefined_mode = 0;1
|
||||
predefined_width = 0;1366
|
||||
predefined_height = 0;768
|
||||
|
||||
; standard driver stuff
|
||||
format MS COFF
|
||||
|
||||
DEBUG = 1
|
||||
|
||||
include 'proc32.inc'
|
||||
include 'imports.inc'
|
||||
|
||||
public START
|
||||
public version
|
||||
|
||||
section '.flat' code readable align 16
|
||||
; the start procedure (see the description above)
|
||||
START:
|
||||
; 1. Detect device. Abort if not found.
|
||||
push esi
|
||||
call DetectDevice
|
||||
test esi, esi
|
||||
jz .return0
|
||||
; 2. Detect optimal mode unless the mode is given explicitly. Abort if failed.
|
||||
if use_predefined_mode = 0
|
||||
call DetectMode
|
||||
end if
|
||||
cmp [width], 0
|
||||
jz .return0_cleanup
|
||||
; 3. Set the detected mode.
|
||||
call SetMode
|
||||
; 4. Cleanup and return.
|
||||
.return0_cleanup:
|
||||
stdcall FreeKernelSpace, esi
|
||||
.return0:
|
||||
pop esi
|
||||
xor eax, eax
|
||||
ret 4
|
||||
|
||||
; check that there is Intel videocard
|
||||
; if so, map MMIO registers and set internal variables
|
||||
; esi points to MMIO block; NULL means no device
|
||||
DetectDevice:
|
||||
; 1. Sanity check: check that we are dealing with Intel videocard.
|
||||
; Integrated video device for Intel is always at PCI:0:2:0.
|
||||
xor esi, esi ; initialize return value to NULL
|
||||
; 1a. Get PCI VendorID and DeviceID.
|
||||
push esi
|
||||
push 10h
|
||||
push esi
|
||||
call PciRead32
|
||||
; 1b. loword(eax) = ax = VendorID, hiword(eax) = DeviceID.
|
||||
; Test whether we have Intel chipset.
|
||||
cmp ax, 8086h
|
||||
jnz .return
|
||||
; 1c. Say hi including DeviceID.
|
||||
shr eax, 10h
|
||||
push edi
|
||||
pusha
|
||||
mov edi, pciid_text
|
||||
call WriteWord
|
||||
mov esi, hellomsg
|
||||
call SysMsgBoardStr
|
||||
popa
|
||||
; 1d. Test whether we know this DeviceID.
|
||||
; If this is the case, remember the position of the device in line of Intel cards;
|
||||
; this knowledge will be useful later.
|
||||
; Tested on devices with id: 8086:0046, partially 8086:2A02.
|
||||
mov ecx, pciids_num
|
||||
mov edi, pciids
|
||||
repnz scasw
|
||||
pop edi
|
||||
jnz .return_unknown_pciid
|
||||
sub ecx, pciids_num - 1
|
||||
neg ecx
|
||||
mov [deviceType], ecx
|
||||
; 1e. Continue saying hi with positive intonation.
|
||||
pusha
|
||||
mov esi, knownmsg
|
||||
call SysMsgBoardStr
|
||||
popa
|
||||
; 2. Prepare MMIO region to control the card.
|
||||
; 2a. Read MMIO physical address from PCI config space.
|
||||
push 10h
|
||||
cmp ecx, i9xx_start
|
||||
jae @f
|
||||
mov byte [esp], 14h
|
||||
@@:
|
||||
push 10h
|
||||
push esi
|
||||
call PciRead32
|
||||
; 2b. Mask out PCI region type, lower 4 bits.
|
||||
and al, not 0xF
|
||||
; 2c. Create virtual mapping of the physical memory.
|
||||
push 1Bh
|
||||
push 100000h
|
||||
push eax
|
||||
call MapIoMem
|
||||
; 3. Return.
|
||||
xchg esi, eax
|
||||
.return:
|
||||
ret
|
||||
; 1f. If we do not know DeviceID, continue saying hi with negative intonation.
|
||||
.return_unknown_pciid:
|
||||
pusha
|
||||
mov esi, unknownmsg
|
||||
call SysMsgBoardStr
|
||||
popa
|
||||
ret
|
||||
|
||||
; Convert word in ax to hexadecimal text in edi, advance edi.
|
||||
WriteWord:
|
||||
; 1. Convert high byte.
|
||||
push eax
|
||||
mov al, ah
|
||||
call WriteByte
|
||||
pop eax
|
||||
; 2. Convert low byte.
|
||||
; Fall through to WriteByte; ret from WriteByte is ret from WriteWord too.
|
||||
|
||||
; Convert byte in al to hexadecimal text in edi, advance edi.
|
||||
WriteByte:
|
||||
; 1. Convert high nibble.
|
||||
push eax
|
||||
shr al, 4
|
||||
call WriteNibble
|
||||
pop eax
|
||||
; 2. Convert low nibble.
|
||||
and al, 0xF
|
||||
; Fall through to WriteNibble; ret from WriteNibble is ret from WriteByte too.
|
||||
|
||||
; Convert nibble in al to hexadecimal text in edi, advance edi.
|
||||
WriteNibble:
|
||||
; Obvious, isn't it?
|
||||
cmp al, 10
|
||||
sbb al, 69h
|
||||
das
|
||||
stosb
|
||||
ret
|
||||
|
||||
if use_predefined_mode = 0
|
||||
; detect resolution of the flat panel
|
||||
DetectMode:
|
||||
push esi edi
|
||||
; 1. Get the location of block of GMBUS* registers.
|
||||
; Starting with Ironlake, GMBUS* registers were moved.
|
||||
add esi, 5100h
|
||||
cmp [deviceType], ironlake_start
|
||||
jb @f
|
||||
add esi, 0xC0000
|
||||
@@:
|
||||
; 2. Initialize GMBUS engine.
|
||||
mov edi, edid
|
||||
mov ecx, 0x10000
|
||||
@@:
|
||||
test byte [esi+8+1], 80h
|
||||
loopnz @b
|
||||
jnz .fail
|
||||
mov dword [esi], 3
|
||||
test byte [esi+8+1], 4
|
||||
jz .noreset
|
||||
call ResetGMBus
|
||||
jnz .fail
|
||||
.noreset:
|
||||
; 3. Send read command.
|
||||
and dword [esi+20h], 0
|
||||
mov dword [esi+4], 4E8000A1h
|
||||
; 4. Wait for data, writing to the buffer as data arrive.
|
||||
.getdata:
|
||||
mov ecx, 0x10000
|
||||
@@:
|
||||
test byte [esi+8+1], 8
|
||||
loopz @b
|
||||
test byte [esi+8+1], 4
|
||||
jz .dataok
|
||||
call ResetGMBus
|
||||
jmp .fail
|
||||
.dataok:
|
||||
mov eax, [esi+0Ch]
|
||||
stosd
|
||||
cmp edi, edid+80h
|
||||
jb .getdata
|
||||
; 5. Wait for bus idle.
|
||||
mov ecx, 0x10000
|
||||
@@:
|
||||
test byte [esi+8+1], 2
|
||||
loopnz @b
|
||||
; 6. We got EDID; dump it if DEBUG.
|
||||
if DEBUG
|
||||
pusha
|
||||
xor ecx, ecx
|
||||
mov esi, edid
|
||||
mov edi, edid_text
|
||||
.dumploop:
|
||||
lodsb
|
||||
call WriteByte
|
||||
mov al, ' '
|
||||
stosb
|
||||
inc cl
|
||||
test cl, 15
|
||||
jnz @f
|
||||
mov byte [edi-1], 13
|
||||
mov al, 10
|
||||
stosb
|
||||
@@:
|
||||
test cl, cl
|
||||
jns .dumploop
|
||||
mov esi, edidmsg
|
||||
call SysMsgBoardStr
|
||||
popa
|
||||
end if
|
||||
; 7. Test whether EDID is good.
|
||||
; 7a. Signature: 00 FF FF FF FF FF FF 00.
|
||||
mov esi, edid
|
||||
cmp dword [esi], 0xFFFFFF00
|
||||
jnz .fail
|
||||
cmp dword [esi+4], 0x00FFFFFF
|
||||
jnz .fail
|
||||
; 7b. Checksum must be zero.
|
||||
xor edx, edx
|
||||
mov ecx, 80h
|
||||
@@:
|
||||
lodsb
|
||||
add dl, al
|
||||
loop @b
|
||||
jnz .fail
|
||||
; 8. Get width and height from EDID.
|
||||
xor eax, eax
|
||||
mov ah, [esi-80h+3Ah]
|
||||
shr ah, 4
|
||||
mov al, [esi-80h+38h]
|
||||
mov [width], eax
|
||||
mov ah, [esi-80h+3Dh]
|
||||
shr ah, 4
|
||||
mov al, [esi-80h+3Bh]
|
||||
mov [height], eax
|
||||
; 9. Return.
|
||||
.fail:
|
||||
pop edi esi
|
||||
ret
|
||||
|
||||
; reset bus, clear all errors
|
||||
ResetGMBus:
|
||||
; look into the PRM
|
||||
mov dword [esi+4], 80000000h
|
||||
mov dword [esi+4], 0
|
||||
mov ecx, 0x10000
|
||||
@@:
|
||||
test byte [esi+8+1], 2
|
||||
loopnz @b
|
||||
ret
|
||||
end if
|
||||
|
||||
; set resolution [width]*[height]
|
||||
SetMode:
|
||||
; 1. Program the registers of videocard.
|
||||
; look into the PRM
|
||||
cli
|
||||
; or byte [esi+7000Ah], 0Ch ; PIPEACONF: disable Display+Cursor Planes
|
||||
; or byte [esi+7100Ah], 0Ch ; PIPEBCONF: disable Display+Cursor Planes
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
cmp [deviceType], i965_start
|
||||
jb @f
|
||||
mov dl, 9Ch - 84h
|
||||
@@:
|
||||
; or byte [esi+71403h], 80h ; VGACNTRL: VGA Display Disable
|
||||
and byte [esi+70080h], not 27h ; CURACNTR: disable cursor A
|
||||
mov dword [esi+70084h], eax ; CURABASE: force write to CURA* regs
|
||||
and byte [esi+700C0h], not 27h ; CURBCNTR: disable cursor B
|
||||
mov dword [esi+700C4h], eax ; CURBBASE: force write to CURB* regs
|
||||
and byte [esi+70183h], not 80h ; DSPACNTR: disable Primary A Plane
|
||||
mov dword [esi+edx+70184h], eax ; DSPALINOFF/DSPASURF: force write to DSPA* regs
|
||||
and byte [esi+71183h], not 80h ; DSPBCNTR: disable Primary B Plane
|
||||
mov dword [esi+edx+71184h], eax ; DSPBLINOFF/DSPBSURF: force write to DSPB* regs
|
||||
if 1
|
||||
cmp [deviceType], ironlake_start
|
||||
jae .disable_pipes
|
||||
mov edx, 10000h
|
||||
or byte [esi+70024h], 2 ; PIPEASTAT: clear VBLANK status
|
||||
or byte [esi+71024h], 2 ; PIPEBSTAT: clear VBLANK status
|
||||
.wait_vblank_preironlake1:
|
||||
mov ecx, 1000h
|
||||
loop $
|
||||
test byte [esi+7000Bh], 80h ; PIPEACONF: pipe A active?
|
||||
jz @f
|
||||
test byte [esi+70024h], 2 ; PIPEASTAT: got VBLANK?
|
||||
jz .wait_vblank_preironlake2
|
||||
@@:
|
||||
test byte [esi+7100Bh], 80h ; PIPEBCONF: pipe B active?
|
||||
jz .disable_pipes
|
||||
test byte [esi+71024h], 2 ; PIPEBSTAT: got VBLANK?
|
||||
jnz .disable_pipes
|
||||
.wait_vblank_preironlake2:
|
||||
dec edx
|
||||
jnz .wait_vblank_preironlake1
|
||||
jmp .not_disabled
|
||||
.disable_pipes:
|
||||
end if
|
||||
and byte [esi+7000Bh], not 80h ; PIPEACONF: disable pipe
|
||||
and byte [esi+7100Bh], not 80h ; PIPEBCONF: disable pipe
|
||||
if 1
|
||||
mov edx, 10000h
|
||||
@@:
|
||||
mov ecx, 1000h
|
||||
loop $
|
||||
test byte [esi+7000Bh], 40h ; PIPEACONF: wait until pipe disabled
|
||||
jz @f
|
||||
dec edx
|
||||
jnz @b
|
||||
.not_disabled:
|
||||
sti
|
||||
jmp .return
|
||||
@@:
|
||||
test byte [esi+7100Bh], 40h ; PIPEBCONF: wait until pipe disabled
|
||||
jz @f
|
||||
mov ecx, 1000h
|
||||
loop $
|
||||
dec edx
|
||||
jnz @b
|
||||
jmp .not_disabled
|
||||
@@:
|
||||
else
|
||||
; alternative way of waiting for pipe stop, works too
|
||||
mov edx, 1000h
|
||||
.dis1:
|
||||
push dword [esi+71000h]
|
||||
push dword [esi+70000h]
|
||||
mov ecx, 10000h
|
||||
loop $
|
||||
pop eax
|
||||
xor eax, [esi+70000h]
|
||||
and eax, 1FFFh
|
||||
pop eax
|
||||
jnz .notdis1
|
||||
xor eax, [esi+71000h]
|
||||
and eax, 1FFFh
|
||||
jz .disabled
|
||||
.notdis1:
|
||||
dec edx
|
||||
jnz .dis1
|
||||
.not_disabled:
|
||||
sti
|
||||
jmp .return
|
||||
.disabled:
|
||||
end if
|
||||
lea eax, [esi+61183h]
|
||||
cmp [deviceType], ironlake_start
|
||||
jb @f
|
||||
add eax, 0xE0000 - 0x60000
|
||||
@@:
|
||||
lea edx, [esi+60000h]
|
||||
test byte [eax], 40h
|
||||
jz @f
|
||||
add edx, 1000h
|
||||
@@:
|
||||
mov eax, [width]
|
||||
dec eax
|
||||
shl eax, 16
|
||||
mov ax, word [height]
|
||||
dec eax
|
||||
mov dword [edx+1Ch], eax ; PIPEASRC: set source image size
|
||||
ror eax, 16
|
||||
mov dword [edx+10190h], eax ; for old cards
|
||||
mov ecx, [width]
|
||||
add ecx, 15
|
||||
and ecx, not 15
|
||||
shl ecx, 2
|
||||
mov dword [edx+10188h], ecx ; DSPASTRIDE: set scanline length
|
||||
and byte [esi+61233h], not 80h ; PFIT_CONTROL: disable panel fitting
|
||||
or byte [edx+1000Bh], 80h ; PIPEACONF: enable pipe
|
||||
; and byte [edx+1000Ah], not 0Ch ; PIPEACONF: enable Display+Cursor Planes
|
||||
or byte [edx+10183h], 80h ; DSPACNTR: enable Display Plane A
|
||||
sti
|
||||
; 2. Notify the kernel that resolution has changed.
|
||||
call GetDisplay
|
||||
mov edx, [width]
|
||||
mov dword [eax+8], edx
|
||||
mov edx, [height]
|
||||
mov dword [eax+0Ch], edx
|
||||
mov [eax+18h], ecx
|
||||
mov eax, [width]
|
||||
dec eax
|
||||
dec edx
|
||||
call SetScreen
|
||||
.return:
|
||||
ret
|
||||
|
||||
align 4
|
||||
hellomsg db 'Intel videocard detected, PciId=8086:'
|
||||
pciid_text db '0000'
|
||||
db ', which is ', 0
|
||||
knownmsg db 'known',13,10,0
|
||||
unknownmsg db 'unknown',13,10,0
|
||||
|
||||
if DEBUG
|
||||
edidmsg db 'EDID successfully read:',13,10
|
||||
edid_text rb 8*(16*3+1)
|
||||
db 0
|
||||
end if
|
||||
|
||||
version:
|
||||
dd 0x50005
|
||||
|
||||
width dd predefined_width
|
||||
height dd predefined_height
|
||||
|
||||
pciids:
|
||||
dw 0x3577 ; i830m
|
||||
dw 0x2562 ; 845g
|
||||
dw 0x3582 ; i855gm
|
||||
i865_start = ($ - pciids) / 2
|
||||
dw 0x2572 ; i865g
|
||||
i9xx_start = ($ - pciids) / 2
|
||||
dw 0x2582 ; i915g
|
||||
dw 0x258a ; e7221g (i915g)
|
||||
dw 0x2592 ; i915gm
|
||||
dw 0x2772 ; i945g
|
||||
dw 0x27a2 ; i945gm
|
||||
dw 0x27ae ; i945gme
|
||||
i965_start = ($ - pciids) / 2
|
||||
dw 0x2972 ; i946qz (i965g)
|
||||
dw 0x2982 ; g35g (i965g)
|
||||
dw 0x2992 ; i965q (i965g)
|
||||
dw 0x29a2 ; i965g
|
||||
dw 0x29b2 ; q35g
|
||||
dw 0x29c2 ; g33g
|
||||
dw 0x29d2 ; q33g
|
||||
dw 0x2a02 ; i965gm
|
||||
dw 0x2a12 ; i965gm
|
||||
dw 0x2a42 ; gm45
|
||||
dw 0x2e02 ; g45
|
||||
dw 0x2e12 ; g45
|
||||
dw 0x2e22 ; g45
|
||||
dw 0x2e32 ; g45
|
||||
dw 0x2e42 ; g45
|
||||
dw 0x2e92 ; g45
|
||||
dw 0xa001 ; pineview
|
||||
dw 0xa011 ; pineview
|
||||
ironlake_start = ($ - pciids) / 2
|
||||
dw 0x0042 ; ironlake_d
|
||||
dw 0x0046 ; ironlake_m
|
||||
dw 0x0102 ; sandybridge_d
|
||||
dw 0x0112 ; sandybridge_d
|
||||
dw 0x0122 ; sandybridge_d
|
||||
dw 0x0106 ; sandybridge_m
|
||||
dw 0x0116 ; sandybridge_m
|
||||
dw 0x0126 ; sandybridge_m
|
||||
dw 0x010A ; sandybridge_d
|
||||
pciids_num = ($ - pciids) / 2
|
||||
|
||||
align 4
|
||||
deviceType dd ?
|
||||
edid rb 0x80
|
736
kernel/branches/kolibri-cfg/drivers/vmode.asm
Normal file
736
kernel/branches/kolibri-cfg/drivers/vmode.asm
Normal file
@ -0,0 +1,736 @@
|
||||
;
|
||||
; MenuetOS Driver (vmode.mdr)
|
||||
; Target: Vertical Refresh Rate programming and videomode changing
|
||||
;
|
||||
; Author: Trans <<<<<13>>>>>
|
||||
; Date: 20.07.2003
|
||||
;
|
||||
; Version: 1.0
|
||||
; OS: MenuetOS
|
||||
; Compiler: FASM
|
||||
;
|
||||
|
||||
OS_BASE equ 0x80000000
|
||||
|
||||
use32
|
||||
|
||||
macro align value { rb (value-1) - ($ + value-1) mod value }
|
||||
|
||||
org OS_BASE+0x0328000
|
||||
|
||||
headerstart=$
|
||||
|
||||
mdid db 'MDAZ' ; 4 byte id
|
||||
mdhver dd 0x00 ; header version
|
||||
mdcode dd MDSTART ; start of code
|
||||
mdver dd 0x00000001 ; driver version (subversion*65536+version)
|
||||
mdname db 'Trans VideoDriver' ; 32 bytes of full driver name
|
||||
times (32-($-mdname)) db ' ' ;
|
||||
|
||||
headerlen=$-headerstart
|
||||
times (256-headerlen) db 0 ; reserved area for future
|
||||
|
||||
MDSTART: ; start of driver code ( base_adr+256 bytes)
|
||||
; ebx(=ecx in program):
|
||||
; 1 - Get DriverInfo and Driver Initial Set
|
||||
; 2 - Get Current Video Mode With Vertical Refresh Rate
|
||||
; 3 - Change Video Mode
|
||||
; 4 - Return at Start System Video Mode
|
||||
; 5 - Change vertical and horizontal size of visible screen area
|
||||
; 6 - Change Vert/Hor position visible area on screen (not complete yet)
|
||||
;
|
||||
; MAXF - ...
|
||||
MAXF=5
|
||||
|
||||
;-------Main Manager-------------
|
||||
pushad
|
||||
cmp ebx,1
|
||||
jb mdvm_00
|
||||
cmp ebx,MAXF
|
||||
ja mdvm_00
|
||||
shl ebx,2
|
||||
add ebx,mdvm_func_table
|
||||
call dword [ebx]
|
||||
mov [esp+28],eax
|
||||
mov [esp+24],ecx
|
||||
mov [esp+20],edx
|
||||
mov [esp+16],ebx
|
||||
popad
|
||||
retn
|
||||
mdvm_00:
|
||||
popad
|
||||
xor eax,eax
|
||||
dec eax
|
||||
retn
|
||||
|
||||
; ------Drivers Functions----------
|
||||
|
||||
align 4
|
||||
|
||||
; EBX=1 (in applications ECX=1)- Get DriverInfo and Driver Initial Set
|
||||
;
|
||||
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application
|
||||
; OUT:
|
||||
;
|
||||
vm_info_init:
|
||||
push ecx
|
||||
cmp [mdrvm],dword 0
|
||||
jnz .vmii_00
|
||||
call vm_safe_reg
|
||||
call vm_get_initial_videomode
|
||||
mov eax,[initvm]
|
||||
mov [currvm],eax
|
||||
call vm_search_sys_func_table
|
||||
call vm_get_cur_vert_rate
|
||||
mov [initrr],eax
|
||||
call vm_calc_pixelclock
|
||||
call vm_calc_refrate
|
||||
inc [mdrvm]
|
||||
.vmii_00:
|
||||
pop ecx
|
||||
call vm_transfer_drv_info
|
||||
mov ebx,dword [refrate]
|
||||
mov eax,dword [mdid] ;dword [systlb]
|
||||
retn
|
||||
|
||||
|
||||
align 4
|
||||
|
||||
; EBX=2 (in applications ECX=2)- Get Current Video Mode
|
||||
;
|
||||
; OUT: eax = X_screen*65536+Y_screen
|
||||
; ebx = current vertical rate
|
||||
; ecx = current video mode (number)
|
||||
vm_get_cur_mode:
|
||||
cmp [mdrvm],dword 0
|
||||
jz .vmgcm_00
|
||||
call vm_get_cur_vert_rate
|
||||
mov eax,[OS_BASE+0FE00h]
|
||||
mov ebx,[OS_BASE+0FE04h]
|
||||
shl eax,16
|
||||
add eax,ebx
|
||||
add eax,00010001h
|
||||
mov ebx,[refrate]
|
||||
mov ecx,[currvm]
|
||||
retn
|
||||
.vmgcm_00:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
retn
|
||||
|
||||
|
||||
align 4
|
||||
|
||||
; EBX=3 (in applications ECX=3)- Change Video Mode
|
||||
;
|
||||
; IN: ecx = VertRate*65536+VideoMode
|
||||
; OUT: eax = 0 if no error
|
||||
;
|
||||
vm_set_video_mode:
|
||||
cmp [mdrvm],dword 0
|
||||
jz .vmsvm_00
|
||||
call vm_set_selected_mode
|
||||
; xor eax,eax
|
||||
retn
|
||||
.vmsvm_00:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
retn
|
||||
|
||||
|
||||
align 4
|
||||
|
||||
; EBX=4 (in applications ECX=4)- Return at Start System Video Mode
|
||||
;
|
||||
; IN:
|
||||
; OUT: eax = = 0 if no error
|
||||
;
|
||||
vm_restore_init_video_mode:
|
||||
cmp [mdrvm],dword 0
|
||||
jz .vmrivm_00
|
||||
call vm_restore_reg
|
||||
xor eax,eax
|
||||
retn
|
||||
.vmrivm_00:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
retn
|
||||
|
||||
|
||||
align 4
|
||||
|
||||
; EBX=5 (in applications ECX=5)- Change vertical and horizontal size
|
||||
; of visible screen area
|
||||
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal size on 1 position
|
||||
; = 2/3 - -/+ vertical size on 1 position (8 pixels)
|
||||
; ^-^----- not complete yet
|
||||
; OUT: eax = = 0 if no error
|
||||
;
|
||||
vm_change_screen_size:
|
||||
cmp [mdrvm],dword 0
|
||||
jz .vmcss_00
|
||||
cmp cl,1
|
||||
ja .vmcss_01
|
||||
mov eax,ecx
|
||||
call vm_inc_dec_width
|
||||
xor eax,eax
|
||||
retn
|
||||
.vmcss_01:
|
||||
and ecx,01h
|
||||
mov eax,ecx
|
||||
; call vm_inc_dec_high ; not complete yet
|
||||
xor eax,eax
|
||||
retn
|
||||
.vmcss_00:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
retn
|
||||
|
||||
|
||||
align 4
|
||||
|
||||
; EBX=6 (in applications ECX=6)- Change Vert/Hor position visible area on screen
|
||||
;
|
||||
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal position on 1 point
|
||||
; = 2/3 - -/+ vertical position on 1 pixel
|
||||
; ^-^----- not complete yet
|
||||
; OUT: eax = 0 if no error
|
||||
;
|
||||
vm_change_position_screen:
|
||||
cmp [mdrvm],dword 0
|
||||
jz .vmcps_00
|
||||
; ...
|
||||
xor eax,eax
|
||||
retn
|
||||
.vmcps_00:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
retn
|
||||
|
||||
|
||||
;-----Drivers Subfunctions---------
|
||||
|
||||
;
|
||||
; Searching i40 system functions pointer table in kernel area location
|
||||
;
|
||||
vm_search_sys_func_table:
|
||||
push eax ; eax - current value
|
||||
push ecx ; ecx - will be counter of equevalent value
|
||||
push edx ; edx - last value
|
||||
push esi ; esi - current address
|
||||
xor ecx,ecx
|
||||
mov esi,OS_BASE+010000h ; Start address of kernel location
|
||||
lodsd
|
||||
mov edx,eax
|
||||
cld
|
||||
.vmssft_00:
|
||||
cmp esi,OS_BASE+30000h
|
||||
ja .vmssft_03
|
||||
inc ecx
|
||||
lodsd
|
||||
cmp edx,eax
|
||||
mov edx,eax
|
||||
je .vmssft_00
|
||||
cmp ecx,128
|
||||
ja .vmssft_02
|
||||
.vmssft_01:
|
||||
xor ecx,ecx
|
||||
jmp .vmssft_00
|
||||
.vmssft_02:
|
||||
cmp edx,0
|
||||
je .vmssft_01
|
||||
sub esi,256*4-1
|
||||
mov [systlb],esi
|
||||
xor ecx,ecx
|
||||
.vmssft_03_0:
|
||||
inc ecx
|
||||
lodsd
|
||||
cmp edx,eax
|
||||
mov edx,eax
|
||||
jne .vmssft_03_0
|
||||
mov esi,dword [systlb]
|
||||
cmp cx,60
|
||||
jae .vmssft_03
|
||||
add esi,256*4-4
|
||||
lodsb
|
||||
mov edx,eax
|
||||
jmp .vmssft_01
|
||||
.vmssft_03:
|
||||
mov [systlb],esi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
retn
|
||||
|
||||
; IN:
|
||||
; OUT: eax= vertical rate in Hz
|
||||
vm_get_cur_vert_rate:
|
||||
push edx
|
||||
push ebx
|
||||
xor eax,eax
|
||||
mov edx,eax
|
||||
mov ebx,eax
|
||||
mov dx,03DAh
|
||||
.vmgcvt_00:
|
||||
in al,dx
|
||||
test al,8
|
||||
jz .vmgcvt_00
|
||||
.vmgcvt_01:
|
||||
in al,dx
|
||||
test al,8
|
||||
jnz .vmgcvt_01
|
||||
mov ebx,edx
|
||||
rdtsc
|
||||
mov edx,ebx
|
||||
mov ebx,eax
|
||||
.vmgcvt_02:
|
||||
in al,dx
|
||||
test al,8
|
||||
jz .vmgcvt_02
|
||||
.vmgcvt_03:
|
||||
in al,dx
|
||||
test al,8
|
||||
jnz .vmgcvt_03
|
||||
rdtsc
|
||||
sub eax,ebx
|
||||
mov ebx,eax
|
||||
mov eax,[OS_BASE+0F600h]
|
||||
xor edx,edx
|
||||
div ebx
|
||||
inc eax
|
||||
mov [refrate],eax
|
||||
pop ebx
|
||||
pop edx
|
||||
retn
|
||||
|
||||
vm_calc_pixelclock:
|
||||
push ebx
|
||||
push edx
|
||||
xor eax,eax
|
||||
mov al,[_00]
|
||||
add ax,5
|
||||
shl eax,3
|
||||
xor ebx,ebx
|
||||
mov bl,[_06]
|
||||
mov bh,[_07]
|
||||
and bh,00100001b
|
||||
btr bx,13
|
||||
jnc .vmcpc_00
|
||||
or bh,2
|
||||
.vmcpc_00:
|
||||
xor edx,edx
|
||||
mul ebx
|
||||
xor edx,edx
|
||||
mul [initrr]
|
||||
mov [pclock],eax
|
||||
pop edx
|
||||
pop ebx
|
||||
retn
|
||||
|
||||
;
|
||||
; Safe of initial CRTC state
|
||||
;
|
||||
vm_safe_reg:
|
||||
push edx
|
||||
push ebx
|
||||
push ecx
|
||||
push edi
|
||||
cli
|
||||
mov dx,3d4h ; CRTC
|
||||
mov al,11h
|
||||
out dx,al
|
||||
inc dx
|
||||
in al,dx
|
||||
and al,7fh
|
||||
out dx,al ; Clear protection bit
|
||||
dec dx
|
||||
xor ecx,ecx
|
||||
mov cl,19h
|
||||
xor bl,bl
|
||||
mov edi,CRTCreg
|
||||
.vmsr_00:
|
||||
mov al,bl
|
||||
out dx,al
|
||||
inc dx
|
||||
in al,dx
|
||||
dec dx
|
||||
stosb
|
||||
inc bl
|
||||
loop .vmsr_00
|
||||
sti
|
||||
pop edi
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop edx
|
||||
retn
|
||||
|
||||
;
|
||||
; Restore of initial CRTC state
|
||||
;
|
||||
vm_restore_reg:
|
||||
push eax
|
||||
push ebx
|
||||
push edx
|
||||
push esi
|
||||
mov eax,[oldX]
|
||||
mov [OS_BASE+0FE00h],eax
|
||||
mov eax,[oldY]
|
||||
mov [OS_BASE+0FE04h],eax
|
||||
mov dx,03dah
|
||||
.vmrr_00:
|
||||
in al,dx
|
||||
test al,8
|
||||
jnz .vmrr_00
|
||||
.vmrr_01:
|
||||
in al,dx
|
||||
test al,8
|
||||
jnz .vmrr_01
|
||||
cli
|
||||
mov dx,03c4h
|
||||
mov ax,0101h
|
||||
out dx,ax
|
||||
mov dx,3d4h ; CRTC
|
||||
mov al,11h
|
||||
out dx,al
|
||||
inc dx
|
||||
in al,dx
|
||||
and al,7fh ; Clear Protection bit
|
||||
out dx,al
|
||||
dec dx
|
||||
xor ecx,ecx
|
||||
mov cl,19h
|
||||
mov esi,CRTCreg
|
||||
xor bl,bl
|
||||
.vmrr_02:
|
||||
lodsb
|
||||
mov ah,al
|
||||
mov al,bl
|
||||
out dx,ax
|
||||
inc bl
|
||||
loop .vmrr_02
|
||||
sti
|
||||
; call ref_screen
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
retn
|
||||
|
||||
; Calculate of possible vertical refrash rate
|
||||
; (light version of function)
|
||||
vm_calc_refrate:
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push edi
|
||||
push esi
|
||||
mov eax,[pclock]
|
||||
xor edx,edx
|
||||
mov edi,_m1
|
||||
mov ebx,eax
|
||||
mov ecx,(1696*1065)
|
||||
div ecx
|
||||
xor edx,edx
|
||||
stosw
|
||||
add edi,8
|
||||
mov eax,ebx
|
||||
mov ecx,(1344*804)
|
||||
div ecx
|
||||
xor edx,edx
|
||||
stosw
|
||||
add edi,8
|
||||
mov eax,ebx
|
||||
mov ecx,(1056*636)
|
||||
div ecx
|
||||
xor edx,edx
|
||||
stosw
|
||||
add edi,8
|
||||
mov eax,ebx
|
||||
mov ecx,(800*524)
|
||||
div ecx
|
||||
xor edx,edx
|
||||
stosw
|
||||
mov edi,_m1
|
||||
mov esi,edi
|
||||
mov ecx,5*4
|
||||
.vmcrr_00:
|
||||
lodsw
|
||||
cmp ax,55
|
||||
jb .vmcrr_01
|
||||
stosw
|
||||
loop .vmcrr_00
|
||||
pop esi
|
||||
pop edi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
retn
|
||||
.vmcrr_01:
|
||||
xor ax,ax
|
||||
stosw
|
||||
loop .vmcrr_00
|
||||
pop esi
|
||||
pop edi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
retn
|
||||
|
||||
vm_get_initial_videomode:
|
||||
push eax
|
||||
mov eax,dword [OS_BASE+0FE00h]
|
||||
mov [oldX],eax
|
||||
mov eax,dword [OS_BASE+0FE04h]
|
||||
mov [oldY],eax
|
||||
mov eax,dword [OS_BASE+0FE0Ch] ; initial video mode
|
||||
and ax,01FFh
|
||||
mov dword [initvm],eax
|
||||
pop eax
|
||||
retn
|
||||
|
||||
|
||||
; IN: eax = 0/1 - -/+ 1 position of width
|
||||
vm_inc_dec_width:
|
||||
push ebx
|
||||
push edx
|
||||
mov ebx,eax
|
||||
mov dx,3d4h ; CRTC
|
||||
mov al,11h
|
||||
out dx,al
|
||||
inc dx
|
||||
in al,dx
|
||||
and al,7fh ; Clear Protection bit
|
||||
out dx,al
|
||||
dec dx
|
||||
xor al,al
|
||||
out dx,al
|
||||
inc dx
|
||||
in al,dx
|
||||
dec al
|
||||
cmp bl,0
|
||||
jnz .vmidr_00
|
||||
inc al
|
||||
inc al
|
||||
.vmidr_00:
|
||||
out dx,al
|
||||
pop edx
|
||||
pop ebx
|
||||
retn
|
||||
|
||||
;
|
||||
; Copy driver info to application area
|
||||
;
|
||||
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application
|
||||
; OUT:
|
||||
vm_transfer_drv_info:
|
||||
push ecx
|
||||
push edi
|
||||
push esi
|
||||
mov eax,ecx
|
||||
xor ecx,ecx
|
||||
mov cl,32/4
|
||||
mov esi,mdname
|
||||
mov edi,drvname
|
||||
rep movsd
|
||||
mov ecx,eax
|
||||
mov eax,[mdver]
|
||||
mov [drvver],eax
|
||||
mov edi,[OS_BASE+3010h]
|
||||
mov edi,[edi+10h]
|
||||
add edi,ecx
|
||||
mov esi,drvinfo
|
||||
xor ecx,ecx
|
||||
mov cx,512
|
||||
rep movsb
|
||||
pop esi
|
||||
pop edi
|
||||
pop ecx
|
||||
retn
|
||||
|
||||
|
||||
;
|
||||
; Set selected video mode
|
||||
; (light version)
|
||||
;
|
||||
; IN: ecx = VertRate*65536+VideoMode
|
||||
;
|
||||
vm_set_selected_mode:
|
||||
push edx
|
||||
push ecx
|
||||
push esi
|
||||
ror ecx,16
|
||||
cmp cx,00h
|
||||
je .vmssm_03
|
||||
rol ecx,16
|
||||
mov eax,ecx
|
||||
shl eax,16
|
||||
shr eax,16
|
||||
mov [currvm],eax
|
||||
cmp cx,112h
|
||||
jne .vmssm_00
|
||||
mov esi,mode0
|
||||
mov ecx,639
|
||||
mov edx,479
|
||||
jmp .vmssm_st00
|
||||
.vmssm_00:
|
||||
cmp cx,115h
|
||||
jne .vmssm_01
|
||||
mov esi,mode1
|
||||
mov ecx,799
|
||||
mov edx,599
|
||||
jmp .vmssm_st00
|
||||
.vmssm_01:
|
||||
cmp cx,118h
|
||||
jne .vmssm_02
|
||||
mov esi,mode2
|
||||
mov ecx,1023
|
||||
mov edx,767
|
||||
jmp .vmssm_st00
|
||||
.vmssm_02:
|
||||
cmp cx,11Bh
|
||||
jne .vmssm_03
|
||||
mov esi,mode2
|
||||
mov ecx,1279
|
||||
mov edx,1023
|
||||
jmp .vmssm_st00
|
||||
.vmssm_03:
|
||||
xor eax,eax
|
||||
dec eax
|
||||
pop esi
|
||||
pop ecx
|
||||
pop edx
|
||||
retn
|
||||
.vmssm_st00:
|
||||
mov [OS_BASE+0FE00h],ecx
|
||||
mov [OS_BASE+0FE04h],edx
|
||||
cli
|
||||
mov dx,03c4h
|
||||
lodsw
|
||||
out dx,ax
|
||||
mov dx,03d4h
|
||||
mov al,11h
|
||||
out dx,al
|
||||
inc dx
|
||||
in al,dx
|
||||
and al,7fh
|
||||
out dx,al
|
||||
dec dx
|
||||
mov ecx,13
|
||||
.vmssm_st01:
|
||||
lodsw
|
||||
out dx,ax
|
||||
loop .vmssm_st01
|
||||
sti
|
||||
xor eax,eax
|
||||
pop esi
|
||||
pop ecx
|
||||
pop edx
|
||||
retn
|
||||
|
||||
|
||||
;------------DATA AREA---------------
|
||||
align 4
|
||||
|
||||
mdvm_func_table:
|
||||
dd MDSTART
|
||||
dd vm_info_init, vm_get_cur_mode
|
||||
dd vm_set_video_mode, vm_restore_init_video_mode
|
||||
dd vm_change_screen_size, vm_change_position_screen
|
||||
|
||||
|
||||
CRTCreg:
|
||||
_00 db ?
|
||||
_01 db ?
|
||||
_02 db ?
|
||||
_03 db ?
|
||||
_04 db ?
|
||||
_05 db ?
|
||||
_06 db ?
|
||||
_07 db ?
|
||||
_08 db ?
|
||||
_09 db ?
|
||||
_0a db ?
|
||||
_0b db ?
|
||||
_0c db ?
|
||||
_0d db ?
|
||||
_0e db ?
|
||||
_0f db ?
|
||||
_10 db ?
|
||||
_11 db ?
|
||||
_12 db ?
|
||||
_13 db ?
|
||||
_14 db ?
|
||||
_15 db ?
|
||||
_16 db ?
|
||||
_17 db ?
|
||||
_18 db ?
|
||||
_19 db ?
|
||||
|
||||
align 4
|
||||
|
||||
oldX dd ?
|
||||
oldY dd ?
|
||||
initvm dd ?
|
||||
currvm dd 0
|
||||
refrate dd 0
|
||||
initrr dd 0
|
||||
systlb dd 0
|
||||
pclock dd ?
|
||||
mdrvm dd 0 ; 0 - not drv init yet, 1 - already drv init
|
||||
|
||||
|
||||
drvinfo:
|
||||
drvname: times 32 db ' '
|
||||
drvver dd 0
|
||||
times (32-($-drvver))/4 dd 0
|
||||
drvmode dw 011Bh,0118h,0115h,0112h
|
||||
times (64-($-drvmode))/2 dw 00h
|
||||
_m1 dw 0,0,0,0,0
|
||||
_m2 dw 0,0,0,0,0
|
||||
_m3 dw 0,0,0,0,0
|
||||
_m4 dw 0,0,0,0,0
|
||||
_m5 dw 0,0,0,0,0
|
||||
times (512-($-drvinfo)) db 0
|
||||
drvinfoend:
|
||||
|
||||
|
||||
;1280x1024 - 11Bh
|
||||
mode3:
|
||||
dw 0101h
|
||||
dw 0d000h,9f01h,9f02h,9303h,0a904h,1905h,2806h,5a07h
|
||||
dw 0110h,8411h,0ff12h,0ff15h,2916h
|
||||
|
||||
;1024x768 - 118h
|
||||
mode2:
|
||||
dw 0101h
|
||||
dw 0a400h,7f01h,7f02h,8703h,8404h,9505h,2406h,0f507h
|
||||
dw 0310h,8911h,0ff12h,0ff15h,2516h
|
||||
|
||||
;800x600 - 115h
|
||||
mode1:
|
||||
dw 0101h
|
||||
dw 8000h,6301h,6302h,8303h,6a04h,1a05h,7206h,0f007h
|
||||
dw 5910h,8d11h,5712h,5715h,7316h
|
||||
|
||||
;640x480 - 112h, 12h
|
||||
mode0:
|
||||
dw 0101h
|
||||
dw 6000h,4f01h,4f02h,8303h,5304h,9f05h,00b06h,3e07h
|
||||
dw 0ea10h,8c11h,0df12h,0df15h,0c16h
|
||||
|
||||
; 640x400
|
||||
;mymode0:
|
||||
; dw 0101h
|
||||
;_0_7 dw 5f00h,4f01h,4f02h,8303h,5304h,9f05h,0BF06h,1f07h
|
||||
; dw 9c10h,8e11h,8f12h,9615h,0B916h ;,4013h
|
||||
|
||||
; 640x800
|
||||
;mymode1:
|
||||
; dw 0101h
|
||||
; dw 5f00h,4f01h,4f02h,8003h,5004h,9f05h,06006h,0FF07h
|
||||
; dw 2d10h,8f11h,2012h,2615h,05716h ;,4013h
|
||||
|
||||
|
||||
DRVM_END:
|
||||
|
1281
kernel/branches/kolibri-cfg/drivers/vt823x.asm
Normal file
1281
kernel/branches/kolibri-cfg/drivers/vt823x.asm
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user