Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40740
This commit is contained in:
parent
ccba9fd074
commit
9842d74f34
19 changed files with 2977 additions and 104 deletions
3
WhatsNew
3
WhatsNew
|
@ -3,6 +3,9 @@ This is a list of API changes in SDL's version history.
|
||||||
|
|
||||||
Version 1.0:
|
Version 1.0:
|
||||||
|
|
||||||
|
1.2.7:
|
||||||
|
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE()
|
||||||
|
|
||||||
1.2.6:
|
1.2.6:
|
||||||
Added SDL_LoadObject(), SDL_LoadFunction(), and SDL_UnloadObject()
|
Added SDL_LoadObject(), SDL_LoadFunction(), and SDL_UnloadObject()
|
||||||
|
|
||||||
|
|
|
@ -503,6 +503,7 @@ CheckNASM()
|
||||||
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/hermes"
|
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/hermes"
|
||||||
SDL_EXTRADIRS="$SDL_EXTRADIRS hermes"
|
SDL_EXTRADIRS="$SDL_EXTRADIRS hermes"
|
||||||
SDL_EXTRALIBS="$SDL_EXTRALIBS hermes/libhermes.la"
|
SDL_EXTRALIBS="$SDL_EXTRALIBS hermes/libhermes.la"
|
||||||
|
use_nasm=yes
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -2569,6 +2570,7 @@ AM_CONDITIONAL(TARGET_MINT, test $ARCH = mint)
|
||||||
# More automake conditionals
|
# More automake conditionals
|
||||||
AM_CONDITIONAL(USE_DIRECTX, test x$use_directx = xyes)
|
AM_CONDITIONAL(USE_DIRECTX, test x$use_directx = xyes)
|
||||||
AM_CONDITIONAL(USE_CLONE, test x$use_clone = xyes)
|
AM_CONDITIONAL(USE_CLONE, test x$use_clone = xyes)
|
||||||
|
AM_CONDITIONAL(HAVE_NASM, test x$use_nasm = xyes)
|
||||||
|
|
||||||
# Set conditional variables for shared and static library selection.
|
# Set conditional variables for shared and static library selection.
|
||||||
# These are not used in any Makefile.am but in sdl-config.in.
|
# These are not used in any Makefile.am but in sdl-config.in.
|
||||||
|
@ -2774,6 +2776,7 @@ src/thread/Makefile
|
||||||
src/timer/Makefile
|
src/timer/Makefile
|
||||||
src/endian/Makefile
|
src/endian/Makefile
|
||||||
src/file/Makefile
|
src/file/Makefile
|
||||||
|
src/cpuinfo/Makefile
|
||||||
src/hermes/Makefile
|
src/hermes/Makefile
|
||||||
sdl-config
|
sdl-config
|
||||||
SDL.spec
|
SDL.spec
|
||||||
|
|
|
@ -11,6 +11,7 @@ libSDLinclude_HEADERS = \
|
||||||
SDL_byteorder.h \
|
SDL_byteorder.h \
|
||||||
SDL_cdrom.h \
|
SDL_cdrom.h \
|
||||||
SDL_copying.h \
|
SDL_copying.h \
|
||||||
|
SDL_cpuinfo.h \
|
||||||
SDL_endian.h \
|
SDL_endian.h \
|
||||||
SDL_error.h \
|
SDL_error.h \
|
||||||
SDL_events.h \
|
SDL_events.h \
|
||||||
|
|
58
include/SDL_cpuinfo.h
Normal file
58
include/SDL_cpuinfo.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef SAVE_RCSID
|
||||||
|
static char rcsid =
|
||||||
|
"@(#) $Id$";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
/* CPU feature detection for SDL */
|
||||||
|
|
||||||
|
#ifndef _SDL_cpuinfo_h
|
||||||
|
#define _SDL_cpuinfo_h
|
||||||
|
|
||||||
|
#include "begin_code.h"
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This function returns true if the CPU has MMX features
|
||||||
|
*/
|
||||||
|
extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX();
|
||||||
|
|
||||||
|
/* This function returns true if the CPU has 3DNow features
|
||||||
|
*/
|
||||||
|
extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow();
|
||||||
|
|
||||||
|
/* This function returns true if the CPU has SSE features
|
||||||
|
*/
|
||||||
|
extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE();
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include "close_code.h"
|
||||||
|
|
||||||
|
#endif /* _SDL_cpuinfo_h */
|
|
@ -34,28 +34,13 @@ static char rcsid =
|
||||||
#include "SDL_audio.h"
|
#include "SDL_audio.h"
|
||||||
#include "SDL_mutex.h"
|
#include "SDL_mutex.h"
|
||||||
#include "SDL_timer.h"
|
#include "SDL_timer.h"
|
||||||
|
#include "SDL_cpuinfo.h"
|
||||||
#include "SDL_sysaudio.h"
|
#include "SDL_sysaudio.h"
|
||||||
|
#include "SDL_cpuinfo.h"
|
||||||
#include "SDL_mixer_MMX.h"
|
#include "SDL_mixer_MMX.h"
|
||||||
#include "SDL_mixer_MMX_VC.h"
|
#include "SDL_mixer_MMX_VC.h"
|
||||||
#include "SDL_mixer_m68k.h"
|
#include "SDL_mixer_m68k.h"
|
||||||
|
|
||||||
/* Function to check the CPU flags */
|
|
||||||
#define MMX_CPU 0x800000
|
|
||||||
#ifdef USE_ASMBLIT
|
|
||||||
#define CPU_Flags() Hermes_X86_CPU()
|
|
||||||
#else
|
|
||||||
#define CPU_Flags() 0L
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ASMBLIT
|
|
||||||
#define X86_ASSEMBLER
|
|
||||||
#define HermesConverterInterface void
|
|
||||||
#define HermesClearInterface void
|
|
||||||
#define STACKCALL
|
|
||||||
|
|
||||||
#include "HeadX86.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This table is used to add two sound values together and pin
|
/* This table is used to add two sound values together and pin
|
||||||
* the value to avoid overflow. (used with permission from ARDI)
|
* the value to avoid overflow. (used with permission from ARDI)
|
||||||
* Changed to use 0xFE instead of 0xFF for better sound quality.
|
* Changed to use 0xFE instead of 0xFF for better sound quality.
|
||||||
|
@ -154,7 +139,7 @@ void SDL_MixAudio (Uint8 *dst, const Uint8 *src, Uint32 len, int volume)
|
||||||
|
|
||||||
case AUDIO_S8: {
|
case AUDIO_S8: {
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
if (CPU_Flags() & MMX_CPU)
|
if (SDL_HasMMX())
|
||||||
{
|
{
|
||||||
SDL_MixAudio_MMX_S8((char*)dst,(char*)src,(unsigned int)len,(int)volume);
|
SDL_MixAudio_MMX_S8((char*)dst,(char*)src,(unsigned int)len,(int)volume);
|
||||||
}
|
}
|
||||||
|
@ -201,7 +186,7 @@ void SDL_MixAudio (Uint8 *dst, const Uint8 *src, Uint32 len, int volume)
|
||||||
|
|
||||||
case AUDIO_S16LSB: {
|
case AUDIO_S16LSB: {
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
if (CPU_Flags() & MMX_CPU)
|
if (SDL_HasMMX())
|
||||||
{
|
{
|
||||||
SDL_MixAudio_MMX_S16((char*)dst,(char*)src,(unsigned int)len,(int)volume);
|
SDL_MixAudio_MMX_S16((char*)dst,(char*)src,(unsigned int)len,(int)volume);
|
||||||
}
|
}
|
||||||
|
|
438
src/cpuinfo/COPYING.LIB
Normal file
438
src/cpuinfo/COPYING.LIB
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the library GPL. It is
|
||||||
|
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Library General Public License, applies to some
|
||||||
|
specially designated Free Software Foundation software, and to any
|
||||||
|
other libraries whose authors decide to use it. You can use it for
|
||||||
|
your libraries, 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 library, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link a program with the library, you must provide
|
||||||
|
complete object files to the recipients so that they can relink them
|
||||||
|
with the library, after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
Our method of protecting your rights has two steps: (1) copyright
|
||||||
|
the library, and (2) offer you this license which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
Also, for each distributor's protection, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
library. If the library is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original
|
||||||
|
version, 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 companies distributing free
|
||||||
|
software will individually obtain patent licenses, thus in effect
|
||||||
|
transforming the program into proprietary software. To prevent this,
|
||||||
|
we have made it clear that any patent must be licensed for everyone's
|
||||||
|
free use or not licensed at all.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary
|
||||||
|
GNU General Public License, which was designed for utility programs. This
|
||||||
|
license, the GNU Library General Public License, applies to certain
|
||||||
|
designated libraries. This license is quite different from the ordinary
|
||||||
|
one; be sure to read it in full, and don't assume that anything in it is
|
||||||
|
the same as in the ordinary license.
|
||||||
|
|
||||||
|
The reason we have a separate public license for some libraries is that
|
||||||
|
they blur the distinction we usually make between modifying or adding to a
|
||||||
|
program and simply using it. Linking a program with a library, without
|
||||||
|
changing the library, is in some sense simply using the library, and is
|
||||||
|
analogous to running a utility program or application program. However, in
|
||||||
|
a textual and legal sense, the linked executable is a combined work, a
|
||||||
|
derivative of the original library, and the ordinary General Public License
|
||||||
|
treats it as such.
|
||||||
|
|
||||||
|
Because of this blurred distinction, using the ordinary General
|
||||||
|
Public License for libraries did not effectively promote software
|
||||||
|
sharing, because most developers did not use the libraries. We
|
||||||
|
concluded that weaker conditions might promote sharing better.
|
||||||
|
|
||||||
|
However, unrestricted linking of non-free programs would deprive the
|
||||||
|
users of those programs of all benefit from the free status of the
|
||||||
|
libraries themselves. This Library General Public License is intended to
|
||||||
|
permit developers of non-free programs to use free libraries, while
|
||||||
|
preserving your freedom as a user of such programs to change the free
|
||||||
|
libraries that are incorporated in them. (We have not seen how to achieve
|
||||||
|
this as regards changes in header files, but we have achieved it as regards
|
||||||
|
changes in the actual functions of the Library.) The hope is that this
|
||||||
|
will lead to faster development of free libraries.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, while the latter only
|
||||||
|
works together with the library.
|
||||||
|
|
||||||
|
Note that it is possible for a library to be covered by the ordinary
|
||||||
|
General Public License rather than by this special one.
|
||||||
|
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library which
|
||||||
|
contains a notice placed by the copyright holder or other authorized
|
||||||
|
party saying it may be distributed under the terms of this Library
|
||||||
|
General Public License (also called "this License"). Each licensee is
|
||||||
|
addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, 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 library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete 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 distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
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 Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
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 Library, 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 Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you 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.
|
||||||
|
|
||||||
|
If distribution of 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 satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also compile or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
c) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
d) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. 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.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library 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.
|
||||||
|
|
||||||
|
9. 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 Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
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.
|
||||||
|
|
||||||
|
11. 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 Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library 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.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Library 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 Library
|
||||||
|
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 Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
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
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. 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 LIBRARY 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
|
||||||
|
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
34
src/cpuinfo/Makefile.am
Normal file
34
src/cpuinfo/Makefile.am
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
###########################################################################
|
||||||
|
#
|
||||||
|
# Some consistent rules for building asm files:
|
||||||
|
|
||||||
|
STRIP_FPIC = sh $(top_srcdir)/strip_fPIC.sh
|
||||||
|
|
||||||
|
SUFFIXES = .asm
|
||||||
|
|
||||||
|
.asm.lo:
|
||||||
|
$(LIBTOOL) --tag=CC --mode=compile $(STRIP_FPIC) $(NASM) -t -D __FLAT__ -D __NOU__ @NASMFLAGS@ $< -o $*.o
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
# The cpuinfo library target
|
||||||
|
noinst_LTLIBRARIES = libcpuinfo.la
|
||||||
|
|
||||||
|
if HAVE_NASM
|
||||||
|
ARCH_SRCS = \
|
||||||
|
gcpuinfo.c \
|
||||||
|
_cpuinfo.asm \
|
||||||
|
_pcihelp.asm
|
||||||
|
else
|
||||||
|
ARCH_SRCS =
|
||||||
|
endif
|
||||||
|
|
||||||
|
COMMON_SRCS = \
|
||||||
|
SDL_cpuinfo.c
|
||||||
|
|
||||||
|
libcpuinfo_la_SOURCES = $(ARCH_SRCS) $(COMMON_SRCS)
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
COPYING.LIB \
|
||||||
|
README
|
||||||
|
|
5
src/cpuinfo/README
Normal file
5
src/cpuinfo/README
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
This is a stripped down version of the portable CPU detection code included
|
||||||
|
in the SciTech SNAP Graphics SDK. It is redistributed under the LGPL license,
|
||||||
|
which can be found in COPYING.LIB.
|
||||||
|
|
||||||
|
You can visit SciTech Software Inc. at: http://www.scitechsoft.com/
|
96
src/cpuinfo/SDL_cpuinfo.c
Normal file
96
src/cpuinfo/SDL_cpuinfo.c
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef SAVE_RCSID
|
||||||
|
static char rcsid =
|
||||||
|
"@(#) $Id$";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CPU feature detection for SDL */
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
//#include "SDL_cpuinfo.h"
|
||||||
|
|
||||||
|
#define CPU_HAS_MMX 0x00000001
|
||||||
|
#define CPU_HAS_3DNOW 0x00000002
|
||||||
|
#define CPU_HAS_SSE 0x00000004
|
||||||
|
|
||||||
|
/* These functions come from SciTech's PM library */
|
||||||
|
extern int CPU_haveMMX();
|
||||||
|
extern int CPU_have3DNow();
|
||||||
|
extern int CPU_haveSSE();
|
||||||
|
|
||||||
|
static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
static Uint32 SDL_GetCPUFeatures()
|
||||||
|
{
|
||||||
|
if ( SDL_CPUFeatures == 0xFFFFFFFF ) {
|
||||||
|
SDL_CPUFeatures = 0;
|
||||||
|
if ( CPU_haveMMX() ) {
|
||||||
|
SDL_CPUFeatures |= CPU_HAS_MMX;
|
||||||
|
}
|
||||||
|
if ( CPU_have3DNow() ) {
|
||||||
|
SDL_CPUFeatures |= CPU_HAS_3DNOW;
|
||||||
|
}
|
||||||
|
if ( CPU_haveSSE() ) {
|
||||||
|
SDL_CPUFeatures |= CPU_HAS_SSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SDL_CPUFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_bool SDL_HasMMX()
|
||||||
|
{
|
||||||
|
if ( SDL_GetCPUFeatures() & CPU_HAS_MMX ) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_bool SDL_Has3DNow()
|
||||||
|
{
|
||||||
|
if ( SDL_GetCPUFeatures() & CPU_HAS_3DNOW ) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_bool SDL_HasSSE()
|
||||||
|
{
|
||||||
|
if ( SDL_GetCPUFeatures() & CPU_HAS_SSE ) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST_MAIN
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
printf("MMX: %d\n", SDL_HasMMX());
|
||||||
|
printf("3DNow: %d\n", SDL_Has3DNow());
|
||||||
|
printf("SSE: %d\n", SDL_HasSSE());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TEST_MAIN */
|
611
src/cpuinfo/_cpuinfo.asm
Normal file
611
src/cpuinfo/_cpuinfo.asm
Normal file
|
@ -0,0 +1,611 @@
|
||||||
|
;****************************************************************************
|
||||||
|
;*
|
||||||
|
;* SciTech OS Portability Manager Library
|
||||||
|
;*
|
||||||
|
;* ========================================================================
|
||||||
|
;*
|
||||||
|
;* Copyright (C) 1991-2002 SciTech Software, Inc. All rights reserved.
|
||||||
|
;*
|
||||||
|
;* This file may be distributed and/or modified under the terms of the
|
||||||
|
;* GNU Lesser General Public License version 2.1 as published by the Free
|
||||||
|
;* Software Foundation and appearing in the file LICENSE.LGPL included
|
||||||
|
;* in the packaging of this file.
|
||||||
|
;*
|
||||||
|
;* Licensees holding a valid Commercial License for this product from
|
||||||
|
;* SciTech Software, Inc. may use this file in accordance with the
|
||||||
|
;* Commercial License Agreement provided with the Software.
|
||||||
|
;*
|
||||||
|
;* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
|
||||||
|
;* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
;* PURPOSE.
|
||||||
|
;*
|
||||||
|
;* See http://www.scitechsoft.com/license/ for information about
|
||||||
|
;* the licensing options available and how to purchase a Commercial
|
||||||
|
;* License Agreement.
|
||||||
|
;*
|
||||||
|
;* Contact license@scitechsoft.com if any conditions of this licensing
|
||||||
|
;* are not clear to you, or you have questions about licensing options.
|
||||||
|
;*
|
||||||
|
;* ========================================================================
|
||||||
|
;*
|
||||||
|
;* Language: NASM
|
||||||
|
;* Environment: Intel 32 bit Protected Mode.
|
||||||
|
;*
|
||||||
|
;* Description: Code to determine the Intel processor type.
|
||||||
|
;*
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
include "scitech.mac"
|
||||||
|
|
||||||
|
header _cpuinfo
|
||||||
|
|
||||||
|
begdataseg _cpuinfo ; Start of data segment
|
||||||
|
|
||||||
|
cache_id db "01234567890123456"
|
||||||
|
intel_id db "GenuineIntel" ; Intel vendor ID
|
||||||
|
cyrix_id db "CyrixInstead" ; Cyrix vendor ID
|
||||||
|
amd_id db "AuthenticAMD" ; AMD vendor ID
|
||||||
|
idt_id db "CentaurHauls" ; IDT vendor ID
|
||||||
|
|
||||||
|
CPU_IDT EQU 01000h ; Flag for IDT processors
|
||||||
|
CPU_Cyrix EQU 02000h ; Flag for Cyrix processors
|
||||||
|
CPU_AMD EQU 04000h ; Flag for AMD processors
|
||||||
|
CPU_Intel EQU 08000h ; Flag for Intel processors
|
||||||
|
|
||||||
|
enddataseg _cpuinfo
|
||||||
|
|
||||||
|
begcodeseg _cpuinfo ; Start of code segment
|
||||||
|
|
||||||
|
%macro mCPU_ID 0
|
||||||
|
db 00Fh,0A2h
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro mRDTSC 0
|
||||||
|
db 00Fh,031h
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; bool _CPU_check80386(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines if we have an i386 processor.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_check80386
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
xor edx,edx ; EDX = 0, not an 80386
|
||||||
|
mov bx, sp
|
||||||
|
and sp, ~3
|
||||||
|
pushfd ; Push original EFLAGS
|
||||||
|
pop eax ; Get original EFLAGS
|
||||||
|
mov ecx, eax ; Save original EFLAGS
|
||||||
|
xor eax, 40000h ; Flip AC bit in EFLAGS
|
||||||
|
push eax ; Save new EFLAGS value on
|
||||||
|
; stack
|
||||||
|
popfd ; Replace current EFLAGS value
|
||||||
|
pushfd ; Get new EFLAGS
|
||||||
|
pop eax ; Store new EFLAGS in EAX
|
||||||
|
xor eax, ecx ; Can't toggle AC bit,
|
||||||
|
; processor=80386
|
||||||
|
jnz @@Done ; Jump if not an 80386 processor
|
||||||
|
inc edx ; We have an 80386
|
||||||
|
|
||||||
|
@@Done: push ecx
|
||||||
|
popfd
|
||||||
|
mov sp, bx
|
||||||
|
mov eax, edx
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; bool _CPU_check80486(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines if we have an i486 processor.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_check80486
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
; Distinguish between the i486 and Pentium by the ability to set the ID flag
|
||||||
|
; in the EFLAGS register. If the ID flag is set, then we can use the CPUID
|
||||||
|
; instruction to determine the final version of the chip. Otherwise we
|
||||||
|
; simply have an 80486.
|
||||||
|
|
||||||
|
; Distinguish between the i486 and Pentium by the ability to set the ID flag
|
||||||
|
; in the EFLAGS register. If the ID flag is set, then we can use the CPUID
|
||||||
|
; instruction to determine the final version of the chip. Otherwise we
|
||||||
|
; simply have an 80486.
|
||||||
|
|
||||||
|
pushfd ; Get original EFLAGS
|
||||||
|
pop eax
|
||||||
|
mov ecx, eax
|
||||||
|
xor eax, 200000h ; Flip ID bit in EFLAGS
|
||||||
|
push eax ; Save new EFLAGS value on stack
|
||||||
|
popfd ; Replace current EFLAGS value
|
||||||
|
pushfd ; Get new EFLAGS
|
||||||
|
pop eax ; Store new EFLAGS in EAX
|
||||||
|
xor eax, ecx ; Can not toggle ID bit,
|
||||||
|
jnz @@1 ; Processor=80486
|
||||||
|
mov eax,1 ; We dont have a Pentium
|
||||||
|
jmp @@Done
|
||||||
|
@@1: mov eax,0 ; We have Pentium or later
|
||||||
|
@@Done: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; bool _CPU_checkClone(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Checks if the i386 or i486 processor is a clone or genuine Intel.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_checkClone
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
mov ax,5555h ; Check to make sure this is a 32-bit processor
|
||||||
|
xor dx,dx
|
||||||
|
mov cx,2h
|
||||||
|
div cx ; Perform Division
|
||||||
|
clc
|
||||||
|
jnz @@NoClone
|
||||||
|
jmp @@Clone
|
||||||
|
@@NoClone:
|
||||||
|
stc
|
||||||
|
@@Clone:
|
||||||
|
pushfd
|
||||||
|
pop eax ; Get the flags
|
||||||
|
and eax,1
|
||||||
|
xor eax,1 ; EAX=0 is probably Intel, EAX=1 is a Clone
|
||||||
|
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; bool _CPU_haveCPUID(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines if we have support for the CPUID instruction.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_haveCPUID
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
ifdef flatmodel
|
||||||
|
pushfd ; Get original EFLAGS
|
||||||
|
pop eax
|
||||||
|
mov ecx, eax
|
||||||
|
xor eax, 200000h ; Flip ID bit in EFLAGS
|
||||||
|
push eax ; Save new EFLAGS value on stack
|
||||||
|
popfd ; Replace current EFLAGS value
|
||||||
|
pushfd ; Get new EFLAGS
|
||||||
|
pop eax ; Store new EFLAGS in EAX
|
||||||
|
xor eax, ecx ; Can not toggle ID bit,
|
||||||
|
jnz @@1 ; Processor=80486
|
||||||
|
mov eax,0 ; We dont have CPUID support
|
||||||
|
jmp @@Done
|
||||||
|
@@1: mov eax,1 ; We have CPUID support
|
||||||
|
else
|
||||||
|
mov eax,0 ; CPUID requires 32-bit pmode
|
||||||
|
endif
|
||||||
|
@@Done: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; uint _CPU_checkCPUID(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines the CPU type using the CPUID instruction.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_checkCPUID
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
xor eax, eax ; Set up for CPUID instruction
|
||||||
|
mCPU_ID ; Get and save vendor ID
|
||||||
|
cmp eax, 1 ; Make sure 1 is valid input for CPUID
|
||||||
|
jl @@Fail ; We dont have the CPUID instruction
|
||||||
|
xor eax,eax ; Assume vendor is unknown
|
||||||
|
|
||||||
|
; Check for GenuineIntel processors
|
||||||
|
|
||||||
|
LEA_L esi,intel_id
|
||||||
|
cmp [DWORD esi], ebx
|
||||||
|
jne @@NotIntel
|
||||||
|
cmp [DWORD esi+4], edx
|
||||||
|
jne @@NotIntel
|
||||||
|
cmp [DWORD esi+8], ecx
|
||||||
|
jne @@NotIntel
|
||||||
|
mov eax,CPU_Intel ; Flag that we have GenuineIntel
|
||||||
|
jmp @@FoundVendor
|
||||||
|
|
||||||
|
; Check for CyrixInstead processors
|
||||||
|
|
||||||
|
@@NotIntel:
|
||||||
|
LEA_L esi,cyrix_id
|
||||||
|
cmp [DWORD esi], ebx
|
||||||
|
jne @@NotCyrix
|
||||||
|
cmp [DWORD esi+4], edx
|
||||||
|
jne @@NotCyrix
|
||||||
|
cmp [DWORD esi+8], ecx
|
||||||
|
jne @@NotCyrix
|
||||||
|
mov eax,CPU_Cyrix ; Flag that we have CyrixInstead
|
||||||
|
jmp @@FoundVendor
|
||||||
|
|
||||||
|
; Check for AuthenticAMD processors
|
||||||
|
|
||||||
|
@@NotCyrix:
|
||||||
|
LEA_L esi,amd_id
|
||||||
|
cmp [DWORD esi], ebx
|
||||||
|
jne @@NotAMD
|
||||||
|
cmp [DWORD esi+4], edx
|
||||||
|
jne @@NotAMD
|
||||||
|
cmp [DWORD esi+8], ecx
|
||||||
|
jne @@NotAMD
|
||||||
|
mov eax,CPU_AMD ; Flag that we have AuthenticAMD
|
||||||
|
jmp @@FoundVendor
|
||||||
|
|
||||||
|
; Check for CentaurHauls processors
|
||||||
|
|
||||||
|
@@NotAMD:
|
||||||
|
LEA_L esi,idt_id
|
||||||
|
cmp [DWORD esi], ebx
|
||||||
|
jne @@NotIDT
|
||||||
|
cmp [DWORD esi+4], edx
|
||||||
|
jne @@NotIDT
|
||||||
|
cmp [DWORD esi+8], ecx
|
||||||
|
jne @@NotIDT
|
||||||
|
mov eax,CPU_IDT ; Flag that we have AuthenticIDT
|
||||||
|
jmp @@FoundVendor
|
||||||
|
|
||||||
|
@@NotIDT:
|
||||||
|
|
||||||
|
@@FoundVendor:
|
||||||
|
push eax
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
mCPU_ID ; Get family/model/stepping/features
|
||||||
|
and eax, 0F00h
|
||||||
|
shr eax, 8 ; Isolate CPU family
|
||||||
|
and eax, 0Fh
|
||||||
|
cmp eax, 0Fh ; Check for Pentium 4 which is an 0Fh!
|
||||||
|
jne @@NotP4
|
||||||
|
mov eax, 07h ; Change P4 ID to 7 for consistency
|
||||||
|
@@NotP4:
|
||||||
|
pop ecx
|
||||||
|
or eax,ecx ; Combine in the CPU vendor flag
|
||||||
|
@@Done: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
@@Fail: xor eax,eax
|
||||||
|
jmp @@Done
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; uint _CPU_getCPUIDModel(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines the CPU type using the CPUID instruction.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_getCPUIDModel
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
xor eax, eax ; Set up for CPUID instruction
|
||||||
|
mCPU_ID ; Get and save vendor ID
|
||||||
|
cmp eax, 1 ; Make sure 1 is valid input for CPUID
|
||||||
|
jl @@Fail ; We dont have the CPUID instruction
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
mCPU_ID ; Get family/model/stepping/features
|
||||||
|
and eax, 0F0h
|
||||||
|
shr eax, 4 ; Isolate model
|
||||||
|
@@Done: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
@@Fail: xor eax,eax
|
||||||
|
jmp @@Done
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; uint _CPU_getCPUIDStepping(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines the CPU type using the CPUID instruction.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_getCPUIDStepping
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
xor eax, eax ; Set up for CPUID instruction
|
||||||
|
mCPU_ID ; Get and save vendor ID
|
||||||
|
cmp eax, 1 ; Make sure 1 is valid input for CPUID
|
||||||
|
jl @@Fail ; We dont have the CPUID instruction
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
mCPU_ID ; Get family/model/stepping/features
|
||||||
|
and eax, 00Fh ; Isolate stepping
|
||||||
|
@@Done: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
@@Fail: xor eax,eax
|
||||||
|
jmp @@Done
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; uint _CPU_getCPUIDFeatures(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines the CPU type using the CPUID instruction.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_getCPUIDFeatures
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
xor eax, eax ; Set up for CPUID instruction
|
||||||
|
mCPU_ID ; Get and save vendor ID
|
||||||
|
cmp eax, 1 ; Make sure 1 is valid input for CPUID
|
||||||
|
jl @@Fail ; We dont have the CPUID instruction
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
mCPU_ID ; Get family/model/stepping/features
|
||||||
|
mov eax, edx
|
||||||
|
@@Done: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
@@Fail: xor eax,eax
|
||||||
|
jmp @@Done
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; uint _CPU_getCacheSize(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines the CPU cache size for Intel processors
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_getCacheSize
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
xor eax, eax ; Set up for CPUID instruction
|
||||||
|
mCPU_ID ; Get and save vendor ID
|
||||||
|
cmp eax,2 ; Make sure 2 is valid input for CPUID
|
||||||
|
jl @@Fail ; We dont have the CPUID instruction
|
||||||
|
mov eax,2
|
||||||
|
mCPU_ID ; Get cache descriptors
|
||||||
|
LEA_L esi,cache_id ; Get address of cache ID (-fPIC aware)
|
||||||
|
shr eax,8
|
||||||
|
mov [esi+0],eax
|
||||||
|
mov [esi+3],ebx
|
||||||
|
mov [esi+7],ecx
|
||||||
|
mov [esi+11],edx
|
||||||
|
xor eax,eax
|
||||||
|
LEA_L esi,cache_id ; Get address of cache ID (-fPIC aware)
|
||||||
|
mov edi,15
|
||||||
|
@@ScanLoop:
|
||||||
|
cmp [BYTE esi],41h
|
||||||
|
mov eax,128
|
||||||
|
je @@Done
|
||||||
|
cmp [BYTE esi],42h
|
||||||
|
mov eax,256
|
||||||
|
je @@Done
|
||||||
|
cmp [BYTE esi],43h
|
||||||
|
mov eax,512
|
||||||
|
je @@Done
|
||||||
|
cmp [BYTE esi],44h
|
||||||
|
mov eax,1024
|
||||||
|
je @@Done
|
||||||
|
cmp [BYTE esi],45h
|
||||||
|
mov eax,2048
|
||||||
|
je @@Done
|
||||||
|
inc esi
|
||||||
|
dec edi
|
||||||
|
jnz @@ScanLoop
|
||||||
|
|
||||||
|
@@Done: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
@@Fail: xor eax,eax
|
||||||
|
jmp @@Done
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; uint _CPU_have3DNow(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Determines the CPU type using the CPUID instruction.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_have3DNow
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
mov eax,80000000h ; Query for extended functions
|
||||||
|
mCPU_ID ; Get extended function limit
|
||||||
|
cmp eax,80000001h
|
||||||
|
jbe @@Fail ; Nope, we dont have function 800000001h
|
||||||
|
mov eax,80000001h ; Setup extended function 800000001h
|
||||||
|
mCPU_ID ; and get the information
|
||||||
|
test edx,80000000h ; Bit 31 is set if 3DNow! present
|
||||||
|
jz @@Fail ; Nope, we dont have 3DNow support
|
||||||
|
mov eax,1 ; Yep, we have 3DNow! support!
|
||||||
|
@@Done: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
@@Fail: xor eax,eax
|
||||||
|
jmp @@Done
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ulong _CPU_quickRDTSC(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Reads the time stamp counter and returns the low order 32-bits
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_quickRDTSC
|
||||||
|
|
||||||
|
mRDTSC
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; void _CPU_runBSFLoop(ulong interations)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Runs a loop of BSF instructions for the specified number of iterations
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_runBSFLoop
|
||||||
|
|
||||||
|
ARG iterations:ULONG
|
||||||
|
|
||||||
|
push _bp
|
||||||
|
mov _bp,_sp
|
||||||
|
push _bx
|
||||||
|
|
||||||
|
mov edx,[iterations]
|
||||||
|
mov eax,80000000h
|
||||||
|
mov ebx,edx
|
||||||
|
|
||||||
|
ALIGN 4
|
||||||
|
|
||||||
|
@@loop: bsf ecx,eax
|
||||||
|
dec ebx
|
||||||
|
jnz @@loop
|
||||||
|
|
||||||
|
pop _bx
|
||||||
|
pop _bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; void _CPU_readTimeStamp(CPU_largeInteger *time);
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Reads the time stamp counter and returns the 64-bit result.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_readTimeStamp
|
||||||
|
|
||||||
|
mRDTSC
|
||||||
|
mov ecx,[esp+4] ; Access directly without stack frame
|
||||||
|
mov [ecx],eax
|
||||||
|
mov [ecx+4],edx
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ulong _CPU_diffTime64(CPU_largeInteger *t1,CPU_largeInteger *t2,CPU_largeInteger *t)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Computes the difference between two 64-bit numbers.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_diffTime64
|
||||||
|
|
||||||
|
ARG t1:DPTR, t2:DPTR, t:DPTR
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
mov ecx,[t2]
|
||||||
|
mov eax,[ecx] ; EAX := t2.low
|
||||||
|
mov ecx,[t1]
|
||||||
|
sub eax,[ecx]
|
||||||
|
mov edx,eax ; EDX := low difference
|
||||||
|
mov ecx,[t2]
|
||||||
|
mov eax,[ecx+4] ; ECX := t2.high
|
||||||
|
mov ecx,[t1]
|
||||||
|
sbb eax,[ecx+4] ; EAX := high difference
|
||||||
|
|
||||||
|
mov ebx,[t] ; Store the result
|
||||||
|
mov [ebx],edx ; Store low part
|
||||||
|
mov [ebx+4],eax ; Store high part
|
||||||
|
mov eax,edx ; Return low part
|
||||||
|
ifndef flatmodel
|
||||||
|
shld edx,eax,16 ; Return in DX:AX
|
||||||
|
endif
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ulong _CPU_calcMicroSec(CPU_largeInteger *count,ulong freq);
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Computes the value in microseconds for the elapsed time with maximum
|
||||||
|
; precision. The formula we use is:
|
||||||
|
;
|
||||||
|
; us = (((diff * 0x100000) / freq) * 1000000) / 0x100000)
|
||||||
|
;
|
||||||
|
; The power of two multiple before the first divide allows us to scale the
|
||||||
|
; 64-bit difference using simple shifts, and then the divide brings the
|
||||||
|
; final result into the range to fit into a 32-bit integer.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_calcMicroSec
|
||||||
|
|
||||||
|
ARG count:DPTR, freq:ULONG
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
|
||||||
|
mov ecx,[count]
|
||||||
|
mov eax,[ecx] ; EAX := low part
|
||||||
|
mov edx,[ecx+4] ; EDX := high part
|
||||||
|
shld edx,eax,20
|
||||||
|
shl eax,20 ; diff * 0x100000
|
||||||
|
div [DWORD freq] ; (diff * 0x100000) / freq
|
||||||
|
mov ecx,1000000
|
||||||
|
xor edx,edx
|
||||||
|
mul ecx ; ((diff * 0x100000) / freq) * 1000000)
|
||||||
|
shrd eax,edx,20 ; ((diff * 0x100000) / freq) * 1000000) / 0x100000
|
||||||
|
ifndef flatmodel
|
||||||
|
shld edx,eax,16 ; Return in DX:AX
|
||||||
|
endif
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ulong _CPU_mulDiv(ulong a,ulong b,ulong c);
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Computes the following with 64-bit integer precision:
|
||||||
|
;
|
||||||
|
; result = (a * b) / c
|
||||||
|
;
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _CPU_mulDiv
|
||||||
|
|
||||||
|
ARG a:ULONG, b:ULONG, c:ULONG
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
mov eax,[a]
|
||||||
|
imul [ULONG b]
|
||||||
|
idiv [ULONG c]
|
||||||
|
ifndef flatmodel
|
||||||
|
shld edx,eax,16 ; Return in DX:AX
|
||||||
|
endif
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; int PM_getIOPL(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Returns current IOPL, callable from any ring, any OS, any day of the week
|
||||||
|
; (as long as it's 386 compatible). Sort of CPU information too.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart PM_getIOPL
|
||||||
|
|
||||||
|
pushfd
|
||||||
|
pop eax
|
||||||
|
and eax,0011000000000000b
|
||||||
|
shr eax,12
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
|
||||||
|
endcodeseg _cpuinfo
|
||||||
|
|
||||||
|
END
|
||||||
|
|
339
src/cpuinfo/_pcihelp.asm
Normal file
339
src/cpuinfo/_pcihelp.asm
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
;****************************************************************************
|
||||||
|
;*
|
||||||
|
;* SciTech OS Portability Manager Library
|
||||||
|
;*
|
||||||
|
;* ========================================================================
|
||||||
|
;*
|
||||||
|
;* Copyright (C) 1991-2002 SciTech Software, Inc. All rights reserved.
|
||||||
|
;*
|
||||||
|
;* This file may be distributed and/or modified under the terms of the
|
||||||
|
;* GNU Lesser General Public License version 2.1 as published by the Free
|
||||||
|
;* Software Foundation and appearing in the file LICENSE.LGPL included
|
||||||
|
;* in the packaging of this file.
|
||||||
|
;*
|
||||||
|
;* Licensees holding a valid Commercial License for this product from
|
||||||
|
;* SciTech Software, Inc. may use this file in accordance with the
|
||||||
|
;* Commercial License Agreement provided with the Software.
|
||||||
|
;*
|
||||||
|
;* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
|
||||||
|
;* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
;* PURPOSE.
|
||||||
|
;*
|
||||||
|
;* See http://www.scitechsoft.com/license/ for information about
|
||||||
|
;* the licensing options available and how to purchase a Commercial
|
||||||
|
;* License Agreement.
|
||||||
|
;*
|
||||||
|
;* Contact license@scitechsoft.com if any conditions of this licensing
|
||||||
|
;* are not clear to you, or you have questions about licensing options.
|
||||||
|
;*
|
||||||
|
;* ========================================================================
|
||||||
|
;*
|
||||||
|
;* Language: NASM
|
||||||
|
;* Environment: Any
|
||||||
|
;*
|
||||||
|
;* Description: Helper assembler functions for PCI access module.
|
||||||
|
;*
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
include "scitech.mac" ; Memory model macros
|
||||||
|
|
||||||
|
header _pcilib
|
||||||
|
|
||||||
|
begcodeseg _pcilib
|
||||||
|
|
||||||
|
ifdef flatmodel
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; uchar _ASMAPI _BIOS32_service(
|
||||||
|
; ulong service,
|
||||||
|
; ulong func,
|
||||||
|
; ulong *physBase,
|
||||||
|
; ulong *length,
|
||||||
|
; ulong *serviceOffset,
|
||||||
|
; PCIBIOS_entry entry);
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Call the BIOS32 services directory
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _BIOS32_service
|
||||||
|
|
||||||
|
ARG service:ULONG, func:ULONG, physBase:DPTR, len:DPTR, off:DPTR, entry:QWORD
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
mov eax,[service]
|
||||||
|
mov ebx,[func]
|
||||||
|
call far dword [entry]
|
||||||
|
mov esi,[physBase]
|
||||||
|
mov [esi],ebx
|
||||||
|
mov esi,[len]
|
||||||
|
mov [esi],ecx
|
||||||
|
mov esi,[off]
|
||||||
|
mov [esi],edx
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ushort _ASMAPI _PCIBIOS_isPresent(ulong i_eax,ulong *o_edx,ushort *oeax,
|
||||||
|
; uchar *o_cl,PCIBIOS_entry entry)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Call the PCI BIOS to determine if it is present.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _PCIBIOS_isPresent
|
||||||
|
|
||||||
|
ARG i_eax:ULONG, o_edx:DPTR, oeax:DPTR, o_cl:DPTR, entry:QWORD
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
mov eax,[i_eax]
|
||||||
|
ifdef flatmodel
|
||||||
|
call far dword [entry]
|
||||||
|
else
|
||||||
|
int 1Ah
|
||||||
|
endif
|
||||||
|
_les _si,[o_edx]
|
||||||
|
mov [_ES _si],edx
|
||||||
|
_les _si,[oeax]
|
||||||
|
mov [_ES _si],ax
|
||||||
|
_les _si,[o_cl]
|
||||||
|
mov [_ES _si],cl
|
||||||
|
mov ax,bx
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ulong _PCIBIOS_service(ulong r_eax,ulong r_ebx,ulong r_edi,ulong r_ecx,
|
||||||
|
; PCIBIOS_entry entry)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Call the PCI BIOS services, either via the 32-bit protected mode entry
|
||||||
|
; point or via the Int 1Ah 16-bit interrupt.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _PCIBIOS_service
|
||||||
|
|
||||||
|
ARG r_eax:ULONG, r_ebx:ULONG, r_edi:ULONG, r_ecx:ULONG, entry:QWORD
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
mov eax,[r_eax]
|
||||||
|
mov ebx,[r_ebx]
|
||||||
|
mov edi,[r_edi]
|
||||||
|
mov ecx,[r_ecx]
|
||||||
|
ifdef flatmodel
|
||||||
|
call far dword [entry]
|
||||||
|
else
|
||||||
|
int 1Ah
|
||||||
|
endif
|
||||||
|
mov eax,ecx
|
||||||
|
ifndef flatmodel
|
||||||
|
shld edx,eax,16 ; Return result in DX:AX
|
||||||
|
endif
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; int _PCIBIOS_getRouting(PCIRoutingOptionsBuffer *buf,PCIBIOS_entry entry);
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Get the routing options for PCI devices
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _PCIBIOS_getRouting
|
||||||
|
|
||||||
|
ARG buf:DPTR, entry:QWORD
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
mov eax,0B10Eh
|
||||||
|
mov bx,0
|
||||||
|
_les _di,[buf]
|
||||||
|
ifdef flatmodel
|
||||||
|
call far dword [entry]
|
||||||
|
else
|
||||||
|
int 1Ah
|
||||||
|
endif
|
||||||
|
movzx eax,ah
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ibool _PCIBIOS_setIRQ(int busDev,int intPin,int IRQ,PCIBIOS_entry entry);
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Change the IRQ routing for the PCI device
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _PCIBIOS_setIRQ
|
||||||
|
|
||||||
|
ARG busDev:UINT, intPin:UINT, IRQ:UINT, entry:QWORD
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
mov eax,0B10Fh
|
||||||
|
mov bx,[USHORT busDev]
|
||||||
|
mov cl,[BYTE intPin]
|
||||||
|
mov ch,[BYTE IRQ]
|
||||||
|
ifdef flatmodel
|
||||||
|
call far dword [entry]
|
||||||
|
else
|
||||||
|
int 1Ah
|
||||||
|
endif
|
||||||
|
mov eax,1
|
||||||
|
jnc @@1
|
||||||
|
xor eax,eax ; Function failed!
|
||||||
|
@@1: leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ulong _PCIBIOS_specialCycle(int bus,ulong data,PCIBIOS_entry entry);
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Generate a special cycle via the PCI BIOS.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _PCIBIOS_specialCycle
|
||||||
|
|
||||||
|
ARG bus:UINT, data:ULONG, entry:QWORD
|
||||||
|
|
||||||
|
enter_c
|
||||||
|
mov eax,0B106h
|
||||||
|
mov bh,[BYTE bus]
|
||||||
|
mov ecx,[data]
|
||||||
|
ifdef flatmodel
|
||||||
|
call far dword [entry]
|
||||||
|
else
|
||||||
|
int 1Ah
|
||||||
|
endif
|
||||||
|
leave_c
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ushort _PCI_getCS(void)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart _PCI_getCS
|
||||||
|
|
||||||
|
mov ax,cs
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; int PM_inpb(int port)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Reads a byte from the specified port
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart PM_inpb
|
||||||
|
|
||||||
|
ARG port:UINT
|
||||||
|
|
||||||
|
push _bp
|
||||||
|
mov _bp,_sp
|
||||||
|
xor _ax,_ax
|
||||||
|
mov _dx,[port]
|
||||||
|
in al,dx
|
||||||
|
pop _bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; int PM_inpw(int port)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Reads a word from the specified port
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart PM_inpw
|
||||||
|
|
||||||
|
ARG port:UINT
|
||||||
|
|
||||||
|
push _bp
|
||||||
|
mov _bp,_sp
|
||||||
|
xor _ax,_ax
|
||||||
|
mov _dx,[port]
|
||||||
|
in ax,dx
|
||||||
|
pop _bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; ulong PM_inpd(int port)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Reads a word from the specified port
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart PM_inpd
|
||||||
|
|
||||||
|
ARG port:UINT
|
||||||
|
|
||||||
|
push _bp
|
||||||
|
mov _bp,_sp
|
||||||
|
mov _dx,[port]
|
||||||
|
in eax,dx
|
||||||
|
ifndef flatmodel
|
||||||
|
shld edx,eax,16 ; DX:AX = result
|
||||||
|
endif
|
||||||
|
pop _bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; void PM_outpb(int port,int value)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Write a byte to the specified port.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart PM_outpb
|
||||||
|
|
||||||
|
ARG port:UINT, value:UINT
|
||||||
|
|
||||||
|
push _bp
|
||||||
|
mov _bp,_sp
|
||||||
|
mov _dx,[port]
|
||||||
|
mov _ax,[value]
|
||||||
|
out dx,al
|
||||||
|
pop _bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; void PM_outpw(int port,int value)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Write a word to the specified port.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart PM_outpw
|
||||||
|
|
||||||
|
ARG port:UINT, value:UINT
|
||||||
|
|
||||||
|
push _bp
|
||||||
|
mov _bp,_sp
|
||||||
|
mov _dx,[port]
|
||||||
|
mov _ax,[value]
|
||||||
|
out dx,ax
|
||||||
|
pop _bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; void PM_outpd(int port,ulong value)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Write a word to the specified port.
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
cprocstart PM_outpd
|
||||||
|
|
||||||
|
ARG port:UINT, value:ULONG
|
||||||
|
|
||||||
|
push _bp
|
||||||
|
mov _bp,_sp
|
||||||
|
mov _dx,[port]
|
||||||
|
mov eax,[value]
|
||||||
|
out dx,eax
|
||||||
|
pop _bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
cprocend
|
||||||
|
|
||||||
|
endcodeseg _pcilib
|
||||||
|
|
||||||
|
END
|
203
src/cpuinfo/cpuinfo.h
Normal file
203
src/cpuinfo/cpuinfo.h
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* SciTech OS Portability Manager Library
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991-2002 SciTech Software, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file may be distributed and/or modified under the terms of the
|
||||||
|
* GNU Lesser General Public License version 2.1 as published by the Free
|
||||||
|
* Software Foundation and appearing in the file LICENSE.LGPL included
|
||||||
|
* in the packaging of this file.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid Commercial License for this product from
|
||||||
|
* SciTech Software, Inc. may use this file in accordance with the
|
||||||
|
* Commercial License Agreement provided with the Software.
|
||||||
|
*
|
||||||
|
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
|
||||||
|
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
*
|
||||||
|
* See http://www.scitechsoft.com/license/ for information about
|
||||||
|
* the licensing options available and how to purchase a Commercial
|
||||||
|
* License Agreement.
|
||||||
|
*
|
||||||
|
* Contact license@scitechsoft.com if any conditions of this licensing
|
||||||
|
* are not clear to you, or you have questions about licensing options.
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* Language: ANSI C
|
||||||
|
* Environment: Any
|
||||||
|
*
|
||||||
|
* Description: Header file for PM library functions for querying the CPU
|
||||||
|
* type, CPU speed and CPU features. Includes support for
|
||||||
|
* high precision timing on Pentium based systems using the
|
||||||
|
* Read Time Stamp Counter.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CPUINFO_H
|
||||||
|
#define __CPUINFO_H
|
||||||
|
|
||||||
|
//#include "scitech.h"
|
||||||
|
#include "SDL.h"
|
||||||
|
#ifdef USE_ASMBLIT
|
||||||
|
#define __INTEL__
|
||||||
|
#endif
|
||||||
|
typedef enum {
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
} ibool;
|
||||||
|
typedef Uint8 uchar;
|
||||||
|
typedef Uint16 ushort;
|
||||||
|
typedef Uint32 uint;
|
||||||
|
typedef Uint32 ulong;
|
||||||
|
typedef Uint64 u64;
|
||||||
|
#define _ASMAPI SDLCALL
|
||||||
|
|
||||||
|
/*--------------------- Macros and type definitions -----------------------*/
|
||||||
|
|
||||||
|
/* Define the calling conventions - C always */
|
||||||
|
|
||||||
|
#define ZAPI _ASMAPI
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
REMARKS:
|
||||||
|
Defines the types of processors returned by CPU_getProcessorType.
|
||||||
|
|
||||||
|
HEADER:
|
||||||
|
cpuinfo.h
|
||||||
|
|
||||||
|
MEMBERS:
|
||||||
|
CPU_i386 - Intel 80386 processor
|
||||||
|
CPU_i486 - Intel 80486 processor
|
||||||
|
CPU_Pentium - Intel Pentium(R) processor
|
||||||
|
CPU_PentiumPro - Intel PentiumPro(R) processor
|
||||||
|
CPU_PentiumII - Intel PentiumII(R) processor
|
||||||
|
CPU_Celeron - Intel Celeron(R) processor
|
||||||
|
CPU_PentiumIII - Intel PentiumIII(R) processor
|
||||||
|
CPU_Pentium4 - Intel Pentium4(R) processor
|
||||||
|
CPU_UnkIntel - Unknown Intel processor
|
||||||
|
CPU_Cyrix6x86 - Cyrix 6x86 processor
|
||||||
|
CPU_Cyrix6x86MX - Cyrix 6x86MX processor
|
||||||
|
CPU_CyrixMediaGX - Cyrix MediaGX processor
|
||||||
|
CPU_CyrixMediaGXm - Cyrix MediaGXm processor
|
||||||
|
CPU_UnkCyrix - Unknown Cyrix processor
|
||||||
|
CPU_AMDAm486 - AMD Am486 processor
|
||||||
|
CPU_AMDAm5x86 - AMD Am5x86 processor
|
||||||
|
CPU_AMDK5 - AMD K5 processor
|
||||||
|
CPU_AMDK6 - AMD K6 processor
|
||||||
|
CPU_AMDK6_2 - AMD K6-2 processor
|
||||||
|
CPU_AMDK6_2plus - AMD K6-2+ processor
|
||||||
|
CPU_AMDK6_III - AMD K6-III processor
|
||||||
|
CPU_AMDK6_IIIplus - AMD K6-III+ processor
|
||||||
|
CPU_AMDAthlon - AMD Athlon processor
|
||||||
|
CPU_AMDDuron - AMD Duron processor
|
||||||
|
CPU_UnkAMD - Unknown AMD processor
|
||||||
|
CPU_WinChipC6 - IDT WinChip C6 processor
|
||||||
|
CPU_WinChip2 - IDT WinChip 2 processor
|
||||||
|
CPU_UnkIDT - Unknown IDT processor
|
||||||
|
CPU_ViaCyrixIII - Via Cyrix III
|
||||||
|
CPU_UnkVIA - Unknown Via processor
|
||||||
|
CPU_Alpha - DEC Alpha processor
|
||||||
|
CPU_Mips - MIPS processor
|
||||||
|
CPU_PowerPC - PowerPC processor
|
||||||
|
CPU_mask - Mask to remove flags and get CPU type
|
||||||
|
CPU_IDT - This bit is set if the processor vendor is IDT
|
||||||
|
CPU_Cyrix - This bit is set if the processor vendor is Cyrix
|
||||||
|
CPU_AMD - This bit is set if the processor vendor is AMD
|
||||||
|
CPU_Intel - This bit is set if the processor vendor is Intel
|
||||||
|
CPU_VIA - This bit is set if the processor vendor is Via
|
||||||
|
CPU_familyMask - Mask to isolate CPU family
|
||||||
|
CPU_steppingMask - Mask to isolate CPU stepping
|
||||||
|
CPU_steppingShift - Shift factor for CPU stepping
|
||||||
|
****************************************************************************/
|
||||||
|
typedef enum {
|
||||||
|
CPU_i386 = 0,
|
||||||
|
CPU_i486 = 1,
|
||||||
|
CPU_Pentium = 2,
|
||||||
|
CPU_PentiumPro = 3,
|
||||||
|
CPU_PentiumII = 4,
|
||||||
|
CPU_Celeron = 5,
|
||||||
|
CPU_PentiumIII = 6,
|
||||||
|
CPU_Pentium4 = 7,
|
||||||
|
CPU_UnkIntel = 8,
|
||||||
|
CPU_Cyrix6x86 = 100,
|
||||||
|
CPU_Cyrix6x86MX = 101,
|
||||||
|
CPU_CyrixMediaGX = 102,
|
||||||
|
CPU_CyrixMediaGXm = 104,
|
||||||
|
CPU_UnkCyrix = 105,
|
||||||
|
CPU_AMDAm486 = 200,
|
||||||
|
CPU_AMDAm5x86 = 201,
|
||||||
|
CPU_AMDK5 = 202,
|
||||||
|
CPU_AMDK6 = 203,
|
||||||
|
CPU_AMDK6_2 = 204,
|
||||||
|
CPU_AMDK6_2plus = 205,
|
||||||
|
CPU_AMDK6_III = 206,
|
||||||
|
CPU_AMDK6_IIIplus = 207,
|
||||||
|
CPU_UnkAMD = 208,
|
||||||
|
CPU_AMDAthlon = 250,
|
||||||
|
CPU_AMDDuron = 251,
|
||||||
|
CPU_WinChipC6 = 300,
|
||||||
|
CPU_WinChip2 = 301,
|
||||||
|
CPU_UnkIDT = 302,
|
||||||
|
CPU_ViaCyrixIII = 400,
|
||||||
|
CPU_UnkVIA = 401,
|
||||||
|
CPU_Alpha = 500,
|
||||||
|
CPU_Mips = 600,
|
||||||
|
CPU_PowerPC = 700,
|
||||||
|
CPU_mask = 0x00000FFF,
|
||||||
|
CPU_IDT = 0x00001000,
|
||||||
|
CPU_Cyrix = 0x00002000,
|
||||||
|
CPU_AMD = 0x00004000,
|
||||||
|
CPU_Intel = 0x00008000,
|
||||||
|
CPU_VIA = 0x00010000,
|
||||||
|
CPU_familyMask = 0x00FFF000,
|
||||||
|
CPU_steppingMask = 0x0F000000,
|
||||||
|
CPU_steppingShift = 24
|
||||||
|
} CPU_processorType;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
/****************************************************************************
|
||||||
|
REMARKS:
|
||||||
|
Defines the structure for holding 64-bit integers used for storing the values
|
||||||
|
returned by the Intel RDTSC instruction.
|
||||||
|
|
||||||
|
HEADER:
|
||||||
|
cpuinfo.h
|
||||||
|
|
||||||
|
MEMBERS:
|
||||||
|
low - Low 32-bits of the 64-bit integer
|
||||||
|
high - High 32-bits of the 64-bit integer
|
||||||
|
****************************************************************************/
|
||||||
|
typedef struct {
|
||||||
|
ulong low;
|
||||||
|
ulong high;
|
||||||
|
} CPU_largeInteger;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
/*-------------------------- Function Prototypes --------------------------*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" { /* Use "C" linkage when in C++ mode */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Routines to obtain CPU information */
|
||||||
|
|
||||||
|
uint ZAPI CPU_getProcessorType(void);
|
||||||
|
ibool ZAPI CPU_haveMMX(void);
|
||||||
|
ibool ZAPI CPU_have3DNow(void);
|
||||||
|
ibool ZAPI CPU_haveSSE(void);
|
||||||
|
ibool ZAPI CPU_haveRDTSC(void);
|
||||||
|
ulong ZAPI CPU_getProcessorSpeed(ibool accurate);
|
||||||
|
void ZAPI CPU_getProcessorSpeedInHZ(ibool accurate,CPU_largeInteger *speed);
|
||||||
|
char * ZAPI CPU_getProcessorName(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* End of "C" linkage for C++ */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CPUINFO_H */
|
||||||
|
|
436
src/cpuinfo/gcpuinfo.c
Normal file
436
src/cpuinfo/gcpuinfo.c
Normal file
|
@ -0,0 +1,436 @@
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* SciTech OS Portability Manager Library
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991-2002 SciTech Software, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file may be distributed and/or modified under the terms of the
|
||||||
|
* GNU Lesser General Public License version 2.1 as published by the Free
|
||||||
|
* Software Foundation and appearing in the file LICENSE.LGPL included
|
||||||
|
* in the packaging of this file.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid Commercial License for this product from
|
||||||
|
* SciTech Software, Inc. may use this file in accordance with the
|
||||||
|
* Commercial License Agreement provided with the Software.
|
||||||
|
*
|
||||||
|
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
|
||||||
|
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE.
|
||||||
|
*
|
||||||
|
* See http://www.scitechsoft.com/license/ for information about
|
||||||
|
* the licensing options available and how to purchase a Commercial
|
||||||
|
* License Agreement.
|
||||||
|
*
|
||||||
|
* Contact license@scitechsoft.com if any conditions of this licensing
|
||||||
|
* are not clear to you, or you have questions about licensing options.
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* Language: ANSI C
|
||||||
|
* Environment: Any
|
||||||
|
*
|
||||||
|
* Description: Main module to implement the Zen Timer support functions.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "cpuinfo.h"
|
||||||
|
//#include "pmapi.h"
|
||||||
|
//#include "oshdr.h"
|
||||||
|
|
||||||
|
/*----------------------------- Implementation ----------------------------*/
|
||||||
|
|
||||||
|
/* External Intel assembler functions */
|
||||||
|
#ifdef __INTEL__
|
||||||
|
/* {secret} */
|
||||||
|
ibool _ASMAPI _CPU_haveCPUID(void);
|
||||||
|
/* {secret} */
|
||||||
|
ibool _ASMAPI _CPU_check80386(void);
|
||||||
|
/* {secret} */
|
||||||
|
ibool _ASMAPI _CPU_check80486(void);
|
||||||
|
/* {secret} */
|
||||||
|
uint _ASMAPI _CPU_checkCPUID(void);
|
||||||
|
/* {secret} */
|
||||||
|
uint _ASMAPI _CPU_getCPUIDModel(void);
|
||||||
|
/* {secret} */
|
||||||
|
uint _ASMAPI _CPU_getCPUIDStepping(void);
|
||||||
|
/* {secret} */
|
||||||
|
uint _ASMAPI _CPU_getCPUIDFeatures(void);
|
||||||
|
/* {secret} */
|
||||||
|
uint _ASMAPI _CPU_getCacheSize(void);
|
||||||
|
/* {secret} */
|
||||||
|
uint _ASMAPI _CPU_have3DNow(void);
|
||||||
|
/* {secret} */
|
||||||
|
ibool _ASMAPI _CPU_checkClone(void);
|
||||||
|
/* {secret} */
|
||||||
|
void _ASMAPI _CPU_readTimeStamp(CPU_largeInteger *time);
|
||||||
|
/* {secret} */
|
||||||
|
void _ASMAPI _CPU_runBSFLoop(ulong iterations);
|
||||||
|
/* {secret} */
|
||||||
|
ulong _ASMAPI _CPU_mulDiv(ulong a,ulong b,ulong c);
|
||||||
|
/* {secret} */
|
||||||
|
#define CPU_HaveMMX 0x00800000
|
||||||
|
#define CPU_HaveRDTSC 0x00000010
|
||||||
|
#define CPU_HaveSSE 0x02000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*------------------------ Public interface routines ----------------------*/
|
||||||
|
|
||||||
|
#ifdef __INTEL__
|
||||||
|
extern Uint8 PM_inpb(int port);
|
||||||
|
extern void PM_outpb(int port,Uint8 val);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
REMARKS:
|
||||||
|
Read an I/O port location.
|
||||||
|
****************************************************************************/
|
||||||
|
static uchar rdinx(
|
||||||
|
int port,
|
||||||
|
int index)
|
||||||
|
{
|
||||||
|
PM_outpb(port,(uchar)index);
|
||||||
|
return PM_inpb(port+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
REMARKS:
|
||||||
|
Write an I/O port location.
|
||||||
|
****************************************************************************/
|
||||||
|
static void wrinx(
|
||||||
|
ushort port,
|
||||||
|
ushort index,
|
||||||
|
ushort value)
|
||||||
|
{
|
||||||
|
PM_outpb(port,(uchar)index);
|
||||||
|
PM_outpb(port+1,(uchar)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
REMARKS:
|
||||||
|
Enables the Cyrix CPUID instruction to properly detect MediaGX and 6x86
|
||||||
|
processors.
|
||||||
|
****************************************************************************/
|
||||||
|
static void _CPU_enableCyrixCPUID(void)
|
||||||
|
{
|
||||||
|
uchar ccr3;
|
||||||
|
|
||||||
|
//PM_init();
|
||||||
|
ccr3 = rdinx(0x22,0xC3);
|
||||||
|
wrinx(0x22,0xC3,(uchar)(ccr3 | 0x10));
|
||||||
|
wrinx(0x22,0xE8,(uchar)(rdinx(0x22,0xE8) | 0x80));
|
||||||
|
wrinx(0x22,0xC3,ccr3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
DESCRIPTION:
|
||||||
|
Returns the type of processor in the system.
|
||||||
|
|
||||||
|
HEADER:
|
||||||
|
cpuinfo.h
|
||||||
|
|
||||||
|
RETURNS:
|
||||||
|
Numerical identifier for the installed processor
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
Returns the type of processor in the system. Note that if the CPU is an
|
||||||
|
unknown Pentium family processor that we don't have an enumeration for,
|
||||||
|
the return value will be greater than or equal to the value of CPU_UnkPentium
|
||||||
|
(depending on the value returned by the CPUID instruction).
|
||||||
|
|
||||||
|
SEE ALSO:
|
||||||
|
CPU_getProcessorSpeed, CPU_haveMMX, CPU_getProcessorName
|
||||||
|
****************************************************************************/
|
||||||
|
uint ZAPI CPU_getProcessorType(void)
|
||||||
|
{
|
||||||
|
#if defined(__INTEL__)
|
||||||
|
uint cpu,vendor,model,cacheSize;
|
||||||
|
static ibool firstTime = true;
|
||||||
|
|
||||||
|
if (_CPU_haveCPUID()) {
|
||||||
|
cpu = _CPU_checkCPUID();
|
||||||
|
vendor = cpu & ~CPU_mask;
|
||||||
|
if (vendor == CPU_Intel) {
|
||||||
|
/* Check for Intel processors */
|
||||||
|
switch (cpu & CPU_mask) {
|
||||||
|
case 4: cpu = CPU_i486; break;
|
||||||
|
case 5: cpu = CPU_Pentium; break;
|
||||||
|
case 6:
|
||||||
|
if ((model = _CPU_getCPUIDModel()) == 1)
|
||||||
|
cpu = CPU_PentiumPro;
|
||||||
|
else if (model <= 6) {
|
||||||
|
cacheSize = _CPU_getCacheSize();
|
||||||
|
if ((model == 5 && cacheSize == 0) ||
|
||||||
|
(model == 5 && cacheSize == 256) ||
|
||||||
|
(model == 6 && cacheSize == 128))
|
||||||
|
cpu = CPU_Celeron;
|
||||||
|
else
|
||||||
|
cpu = CPU_PentiumII;
|
||||||
|
}
|
||||||
|
else if (model >= 7) {
|
||||||
|
/* Model 7 == Pentium III */
|
||||||
|
/* Model 8 == Celeron/Pentium III Coppermine */
|
||||||
|
cacheSize = _CPU_getCacheSize();
|
||||||
|
if ((model == 8 && cacheSize == 128))
|
||||||
|
cpu = CPU_Celeron;
|
||||||
|
else
|
||||||
|
cpu = CPU_PentiumIII;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
cpu = CPU_Pentium4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cpu = CPU_UnkIntel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vendor == CPU_Cyrix) {
|
||||||
|
/* Check for Cyrix processors */
|
||||||
|
switch (cpu & CPU_mask) {
|
||||||
|
case 4:
|
||||||
|
if ((model = _CPU_getCPUIDModel()) == 4)
|
||||||
|
cpu = CPU_CyrixMediaGX;
|
||||||
|
else
|
||||||
|
cpu = CPU_UnkCyrix;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if ((model = _CPU_getCPUIDModel()) == 2)
|
||||||
|
cpu = CPU_Cyrix6x86;
|
||||||
|
else if (model == 4)
|
||||||
|
cpu = CPU_CyrixMediaGXm;
|
||||||
|
else
|
||||||
|
cpu = CPU_UnkCyrix;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if ((model = _CPU_getCPUIDModel()) <= 1)
|
||||||
|
cpu = CPU_Cyrix6x86MX;
|
||||||
|
else
|
||||||
|
cpu = CPU_UnkCyrix;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cpu = CPU_UnkCyrix;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vendor == CPU_AMD) {
|
||||||
|
/* Check for AMD processors */
|
||||||
|
switch (cpu & CPU_mask) {
|
||||||
|
case 4:
|
||||||
|
if ((model = _CPU_getCPUIDModel()) == 0)
|
||||||
|
cpu = CPU_AMDAm5x86;
|
||||||
|
else
|
||||||
|
cpu = CPU_AMDAm486;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if ((model = _CPU_getCPUIDModel()) <= 3)
|
||||||
|
cpu = CPU_AMDK5;
|
||||||
|
else if (model <= 7)
|
||||||
|
cpu = CPU_AMDK6;
|
||||||
|
else if (model == 8)
|
||||||
|
cpu = CPU_AMDK6_2;
|
||||||
|
else if (model == 9)
|
||||||
|
cpu = CPU_AMDK6_III;
|
||||||
|
else if (model == 13) {
|
||||||
|
if (_CPU_getCPUIDStepping() <= 3)
|
||||||
|
cpu = CPU_AMDK6_IIIplus;
|
||||||
|
else
|
||||||
|
cpu = CPU_AMDK6_2plus;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cpu = CPU_UnkAMD;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if ((model = _CPU_getCPUIDModel()) == 3)
|
||||||
|
cpu = CPU_AMDDuron;
|
||||||
|
else
|
||||||
|
cpu = CPU_AMDAthlon;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cpu = CPU_UnkAMD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vendor == CPU_IDT) {
|
||||||
|
/* Check for IDT WinChip processors */
|
||||||
|
switch (cpu & CPU_mask) {
|
||||||
|
case 5:
|
||||||
|
if ((model = _CPU_getCPUIDModel()) <= 4)
|
||||||
|
cpu = CPU_WinChipC6;
|
||||||
|
else if (model == 8)
|
||||||
|
cpu = CPU_WinChip2;
|
||||||
|
else
|
||||||
|
cpu = CPU_UnkIDT;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
vendor = CPU_VIA;
|
||||||
|
if ((model = _CPU_getCPUIDModel()) <= 6)
|
||||||
|
cpu = CPU_ViaCyrixIII;
|
||||||
|
else
|
||||||
|
cpu = CPU_UnkVIA;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vendor = CPU_VIA;
|
||||||
|
cpu = CPU_UnkVIA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Assume a Pentium compatible Intel clone */
|
||||||
|
cpu = CPU_Pentium;
|
||||||
|
}
|
||||||
|
return cpu | vendor | (_CPU_getCPUIDStepping() << CPU_steppingShift);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (_CPU_check80386())
|
||||||
|
cpu = CPU_i386;
|
||||||
|
else if (_CPU_check80486()) {
|
||||||
|
/* If we get here we may have a Cyrix processor so we can try
|
||||||
|
* enabling the CPUID instruction and trying again.
|
||||||
|
*/
|
||||||
|
if (firstTime) {
|
||||||
|
firstTime = false;
|
||||||
|
_CPU_enableCyrixCPUID();
|
||||||
|
return CPU_getProcessorType();
|
||||||
|
}
|
||||||
|
cpu = CPU_i486;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cpu = CPU_Pentium;
|
||||||
|
if (!_CPU_checkClone())
|
||||||
|
return cpu | CPU_Intel;
|
||||||
|
return cpu;
|
||||||
|
}
|
||||||
|
#elif defined(__ALPHA__)
|
||||||
|
return CPU_Alpha;
|
||||||
|
#elif defined(__MIPS__)
|
||||||
|
return CPU_Mips;
|
||||||
|
#elif defined(__PPC__)
|
||||||
|
return CPU_PowerPC;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
DESCRIPTION:
|
||||||
|
Returns true if the processor supports Intel MMX extensions.
|
||||||
|
|
||||||
|
HEADER:
|
||||||
|
cpuinfo.h
|
||||||
|
|
||||||
|
RETURNS:
|
||||||
|
True if MMX is available, false if not.
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
This function determines if the processor supports the Intel MMX extended
|
||||||
|
instruction set.
|
||||||
|
|
||||||
|
SEE ALSO:
|
||||||
|
CPU_getProcessorType, CPU_getProcessorSpeed, CPU_have3DNow, CPU_haveSSE,
|
||||||
|
CPU_getProcessorName
|
||||||
|
****************************************************************************/
|
||||||
|
ibool ZAPI CPU_haveMMX(void)
|
||||||
|
{
|
||||||
|
#ifdef __INTEL__
|
||||||
|
if (_CPU_haveCPUID())
|
||||||
|
return (_CPU_getCPUIDFeatures() & CPU_HaveMMX) != 0;
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
DESCRIPTION:
|
||||||
|
Returns true if the processor supports AMD 3DNow! extensions.
|
||||||
|
|
||||||
|
HEADER:
|
||||||
|
cpuinfo.h
|
||||||
|
|
||||||
|
RETURNS:
|
||||||
|
True if 3DNow! is available, false if not.
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
This function determines if the processor supports the AMD 3DNow! extended
|
||||||
|
instruction set.
|
||||||
|
|
||||||
|
SEE ALSO:
|
||||||
|
CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_haveSSE,
|
||||||
|
CPU_getProcessorName
|
||||||
|
****************************************************************************/
|
||||||
|
ibool ZAPI CPU_have3DNow(void)
|
||||||
|
{
|
||||||
|
#ifdef __INTEL__
|
||||||
|
if (_CPU_haveCPUID())
|
||||||
|
return _CPU_have3DNow();
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
DESCRIPTION:
|
||||||
|
Returns true if the processor supports Intel SSE extensions.
|
||||||
|
|
||||||
|
HEADER:
|
||||||
|
cpuinfo.h
|
||||||
|
|
||||||
|
RETURNS:
|
||||||
|
True if Intel SSE is available, false if not.
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
This function determines if the processor supports the Intel SSE extended
|
||||||
|
instruction set.
|
||||||
|
|
||||||
|
SEE ALSO:
|
||||||
|
CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_have3DNow,
|
||||||
|
CPU_getProcessorName
|
||||||
|
****************************************************************************/
|
||||||
|
ibool ZAPI CPU_haveSSE(void)
|
||||||
|
{
|
||||||
|
#ifdef __INTEL__
|
||||||
|
if (_CPU_haveCPUID())
|
||||||
|
return (_CPU_getCPUIDFeatures() & CPU_HaveSSE) != 0;
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
RETURNS:
|
||||||
|
True if the RTSC instruction is available, false if not.
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
This function determines if the processor supports the Intel RDTSC
|
||||||
|
instruction, for high precision timing. If the processor is not an Intel or
|
||||||
|
Intel clone CPU, this function will always return false.
|
||||||
|
|
||||||
|
DESCRIPTION:
|
||||||
|
Returns true if the processor supports RDTSC extensions.
|
||||||
|
|
||||||
|
HEADER:
|
||||||
|
cpuinfo.h
|
||||||
|
|
||||||
|
RETURNS:
|
||||||
|
True if RTSC is available, false if not.
|
||||||
|
|
||||||
|
REMARKS:
|
||||||
|
This function determines if the processor supports the RDTSC instruction
|
||||||
|
for reading the processor time stamp counter.
|
||||||
|
|
||||||
|
SEE ALSO:
|
||||||
|
CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_have3DNow,
|
||||||
|
CPU_getProcessorName
|
||||||
|
****************************************************************************/
|
||||||
|
ibool ZAPI CPU_haveRDTSC(void)
|
||||||
|
{
|
||||||
|
#ifdef __INTEL__
|
||||||
|
if (_CPU_haveCPUID())
|
||||||
|
return (_CPU_getCPUIDFeatures() & CPU_HaveRDTSC) != 0;
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
714
src/cpuinfo/scitech.mac
Normal file
714
src/cpuinfo/scitech.mac
Normal file
|
@ -0,0 +1,714 @@
|
||||||
|
;****************************************************************************
|
||||||
|
;*
|
||||||
|
;* ========================================================================
|
||||||
|
;*
|
||||||
|
;* Copyright (C) 1991-2002 SciTech Software, Inc. All rights reserved.
|
||||||
|
;*
|
||||||
|
;* This file may be distributed and/or modified under the terms of the
|
||||||
|
;* GNU Lesser General Public License version 2.1 as published by the Free
|
||||||
|
;* Software Foundation and appearing in the file LICENSE.LGPL included
|
||||||
|
;* in the packaging of this file.
|
||||||
|
;*
|
||||||
|
;* Licensees holding a valid Commercial License for this product from
|
||||||
|
;* SciTech Software, Inc. may use this file in accordance with the
|
||||||
|
;* Commercial License Agreement provided with the Software.
|
||||||
|
;*
|
||||||
|
;* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
|
||||||
|
;* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
;* PURPOSE.
|
||||||
|
;*
|
||||||
|
;* See http://www.scitechsoft.com/license/ for information about
|
||||||
|
;* the licensing options available and how to purchase a Commercial
|
||||||
|
;* License Agreement.
|
||||||
|
;*
|
||||||
|
;* Contact license@scitechsoft.com if any conditions of this licensing
|
||||||
|
;* are not clear to you, or you have questions about licensing options.
|
||||||
|
;*
|
||||||
|
;* ========================================================================
|
||||||
|
;*
|
||||||
|
;* Language: NetWide Assembler (NASM)
|
||||||
|
;* Environment: Any Intel IA32 Environment
|
||||||
|
;*
|
||||||
|
;* Description: Macros to provide memory model independant assembly language
|
||||||
|
;* module for C programming. Supports the large and flat memory
|
||||||
|
;* models.
|
||||||
|
;*
|
||||||
|
;* The defines that you should use when assembling modules that
|
||||||
|
;* use this macro package are:
|
||||||
|
;*
|
||||||
|
;* __FLAT__ Assemble for 32-bit FLAT memory model
|
||||||
|
;* __NOU__ No underscore for all external C labels
|
||||||
|
;* __NOU_VAR__ No underscore for global variables only
|
||||||
|
;*
|
||||||
|
;* The default settings are for 16-bit large memory model with
|
||||||
|
;* leading underscores for symbol names.
|
||||||
|
;*
|
||||||
|
;****************************************************************************
|
||||||
|
|
||||||
|
%ifndef SCITECH_MAC
|
||||||
|
%define SCITECH_MAC
|
||||||
|
|
||||||
|
; Turn off underscores for globals if disabled for all externals
|
||||||
|
|
||||||
|
%ifdef __NOU__
|
||||||
|
%define __NOU_VAR__
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; Determine if we should use COFF style segment naming
|
||||||
|
|
||||||
|
%ifdef __MSC__
|
||||||
|
%define __COFF__
|
||||||
|
%endif
|
||||||
|
%ifdef __GNUC__
|
||||||
|
%define __COFF__
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; Define the __WINDOWS__ symbol if we are compiling for any Windows
|
||||||
|
; environment
|
||||||
|
|
||||||
|
%ifdef __WINDOWS16__
|
||||||
|
%define __WINDOWS__ 1
|
||||||
|
%endif
|
||||||
|
%ifdef __WINDOWS32__
|
||||||
|
%define __WINDOWS__ 1
|
||||||
|
%define __WINDOWS32_386__ 1
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; Macros for accessing 'generic' registers
|
||||||
|
|
||||||
|
%ifdef __FLAT__
|
||||||
|
%idefine _ax eax
|
||||||
|
%idefine _bx ebx
|
||||||
|
%idefine _cx ecx
|
||||||
|
%idefine _dx edx
|
||||||
|
%idefine _si esi
|
||||||
|
%idefine _di edi
|
||||||
|
%idefine _bp ebp
|
||||||
|
%idefine _sp esp
|
||||||
|
%idefine _es
|
||||||
|
%idefine UCHAR BYTE ; Size of a character
|
||||||
|
%idefine USHORT WORD ; Size of a short
|
||||||
|
%idefine UINT DWORD ; Size of an integer
|
||||||
|
%idefine ULONG DWORD ; Size of a long
|
||||||
|
%idefine BOOL DWORD ; Size of a boolean
|
||||||
|
%idefine DPTR DWORD ; Size of a data pointer
|
||||||
|
%idefine FDPTR FWORD ; Size of a far data pointer
|
||||||
|
%idefine NDPTR DWORD ; Size of a near data pointer
|
||||||
|
%idefine CPTR DWORD ; Size of a code pointer
|
||||||
|
%idefine FCPTR FWORD ; Size of a far code pointer
|
||||||
|
%idefine NCPTR DWORD ; Size of a near code pointer
|
||||||
|
%idefine FPTR NEAR ; Distance for function pointers
|
||||||
|
%idefine DUINT dd ; Declare a integer variable
|
||||||
|
%idefine intsize 4
|
||||||
|
%idefine flatmodel 1
|
||||||
|
%else
|
||||||
|
%idefine _ax ax
|
||||||
|
%idefine _bx bx
|
||||||
|
%idefine _cx cx
|
||||||
|
%idefine _dx dx
|
||||||
|
%idefine _si si
|
||||||
|
%idefine _di di
|
||||||
|
%idefine _bp bp
|
||||||
|
%idefine _sp sp
|
||||||
|
%idefine _es es:
|
||||||
|
%idefine UCHAR BYTE ; Size of a character
|
||||||
|
%idefine USHORT WORD ; Size of a short
|
||||||
|
%idefine UINT WORD ; Size of an integer
|
||||||
|
%idefine ULONG DWORD ; Size of a long
|
||||||
|
%idefine BOOL WORD ; Size of a boolean
|
||||||
|
%idefine DPTR DWORD ; Size of a data pointer
|
||||||
|
%idefine FDPTR DWORD ; Size of a far data pointer
|
||||||
|
%idefine NDPTR WORD ; Size of a near data pointer
|
||||||
|
%idefine CPTR DWORD ; Size of a code pointer
|
||||||
|
%idefine FCPTR DWORD ; Size of a far code pointer
|
||||||
|
%idefine NCPTR WORD ; Size of a near code pointer
|
||||||
|
%idefine FPTR FAR ; Distance for function pointers
|
||||||
|
%idefine DUINT dw ; Declare a integer variable
|
||||||
|
%idefine intsize 2
|
||||||
|
%endif
|
||||||
|
%idefine invert ~
|
||||||
|
%idefine offset
|
||||||
|
%idefine use_nasm
|
||||||
|
|
||||||
|
; Convert all jumps to near jumps, since NASM does not so this automatically
|
||||||
|
|
||||||
|
%idefine jo jo near
|
||||||
|
%idefine jno jno near
|
||||||
|
%idefine jz jz near
|
||||||
|
%idefine jnz jnz near
|
||||||
|
%idefine je je near
|
||||||
|
%idefine jne jne near
|
||||||
|
%idefine jb jb near
|
||||||
|
%idefine jbe jbe near
|
||||||
|
%idefine ja ja near
|
||||||
|
%idefine jae jae near
|
||||||
|
%idefine jl jl near
|
||||||
|
%idefine jle jle near
|
||||||
|
%idefine jg jg near
|
||||||
|
%idefine jge jge near
|
||||||
|
%idefine jc jc near
|
||||||
|
%idefine jnc jnc near
|
||||||
|
%idefine js js near
|
||||||
|
%idefine jns jns near
|
||||||
|
|
||||||
|
%ifdef DOUBLE
|
||||||
|
%idefine REAL QWORD
|
||||||
|
%idefine DREAL dq
|
||||||
|
%else
|
||||||
|
%idefine REAL DWORD
|
||||||
|
%idefine DREAL dd
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; Boolean truth values (same as those in debug.h)
|
||||||
|
|
||||||
|
%idefine False 0
|
||||||
|
%idefine True 1
|
||||||
|
%idefine No 0
|
||||||
|
%idefine Yes 1
|
||||||
|
%idefine Yes 1
|
||||||
|
|
||||||
|
; TODO: If we wish to port VxD code to NASM, we will potentially
|
||||||
|
; need special macros in here to handle this!
|
||||||
|
|
||||||
|
; Setup all correct segment definitions and attributes once at the
|
||||||
|
; beginning of the assembler module. This allows us to open/close
|
||||||
|
; code and data segments at will throughout the code as necessary.
|
||||||
|
|
||||||
|
%ifdef __PIC__
|
||||||
|
%ifdef __LINUX__
|
||||||
|
extern _GLOBAL_OFFSET_TABLE_
|
||||||
|
%else
|
||||||
|
extern __GLOBAL_OFFSET_TABLE_
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
%ifdef __COFF__
|
||||||
|
segment .text public class=CODE use32 flat
|
||||||
|
segment .data public class=DATA use32 flat
|
||||||
|
%else
|
||||||
|
%ifdef flatmodel
|
||||||
|
segment _TEXT public align=16 class=CODE use32 flat
|
||||||
|
segment _DATA public align=4 class=DATA use32 flat
|
||||||
|
%else
|
||||||
|
segment _TEXT public align=16 class=CODE use16
|
||||||
|
segment _DATA public align=4 class=DATA use16
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; Macro to be invoked at the start of all modules to set up segments for
|
||||||
|
; later use. This does nothing for 32-bit code, but for 16-bit code
|
||||||
|
; will set up a far model code segment as well for later use.
|
||||||
|
|
||||||
|
%imacro header 1
|
||||||
|
%ifndef flatmodel
|
||||||
|
segment %1_TEXT public align=16 class=CODE use16
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to begin a data segment. Segment attributes were specified in
|
||||||
|
; the header macro that is always required.
|
||||||
|
|
||||||
|
%imacro begdataseg 1
|
||||||
|
%ifdef __COFF__
|
||||||
|
segment .data
|
||||||
|
%else
|
||||||
|
segment _DATA
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to end a data segment
|
||||||
|
|
||||||
|
%imacro enddataseg 1
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to begin a code segment
|
||||||
|
|
||||||
|
%imacro begcodeseg 1
|
||||||
|
%ifdef __COFF__
|
||||||
|
segment .text
|
||||||
|
%else
|
||||||
|
%ifdef flatmodel
|
||||||
|
segment _TEXT
|
||||||
|
%else
|
||||||
|
segment %1_TEXT
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to end a code segment
|
||||||
|
|
||||||
|
%imacro endcodeseg 1
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to begin a near code segment
|
||||||
|
|
||||||
|
%imacro begcodeseg_near 0
|
||||||
|
%ifdef __COFF__
|
||||||
|
segment .text
|
||||||
|
%else
|
||||||
|
segment _TEXT
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to end a near code segment
|
||||||
|
|
||||||
|
%imacro endcodeseg_near 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro for an extern C symbol. If the C compiler requires leading
|
||||||
|
; underscores, then the underscores are added to the symbol names, otherwise
|
||||||
|
; they are left off. The symbol name is referenced in the assembler code
|
||||||
|
; using the non-underscored symbol name.
|
||||||
|
|
||||||
|
%imacro cextern 2
|
||||||
|
%ifdef __NOU_VAR__
|
||||||
|
extern %1
|
||||||
|
%else
|
||||||
|
extern _%1
|
||||||
|
%define %1 _%1
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro cexternfunc 2
|
||||||
|
%ifdef __NOU__
|
||||||
|
extern %1
|
||||||
|
%else
|
||||||
|
extern _%1
|
||||||
|
%define %1 _%1
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro for a public C symbol. If the C compiler requires leading
|
||||||
|
; underscores, then the underscores are added to the symbol names, otherwise
|
||||||
|
; they are left off. The symbol name is referenced in the assembler code
|
||||||
|
; using the non-underscored symbol name.
|
||||||
|
|
||||||
|
%imacro cpublic 1
|
||||||
|
%ifdef __NOU_VAR__
|
||||||
|
global %1
|
||||||
|
%1:
|
||||||
|
%else
|
||||||
|
global _%1
|
||||||
|
_%1:
|
||||||
|
%define %1 _%1
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro for an global C symbol. If the C compiler requires leading
|
||||||
|
; underscores, then the underscores are added to the symbol names, otherwise
|
||||||
|
; they are left off. The symbol name is referenced in the assembler code
|
||||||
|
; using the non-underscored symbol name.
|
||||||
|
|
||||||
|
%imacro cglobal 1
|
||||||
|
%ifdef __NOU_VAR__
|
||||||
|
global %1
|
||||||
|
%else
|
||||||
|
global _%1
|
||||||
|
%define %1 _%1
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro for an global C function symbol. If the C compiler requires leading
|
||||||
|
; underscores, then the underscores are added to the symbol names, otherwise
|
||||||
|
; they are left off. The symbol name is referenced in the assembler code
|
||||||
|
; using the non-underscored symbol name.
|
||||||
|
|
||||||
|
%imacro cglobalfunc 1
|
||||||
|
%ifdef __PIC__
|
||||||
|
global %1:function
|
||||||
|
%else
|
||||||
|
%ifdef __NOU__
|
||||||
|
global %1
|
||||||
|
%else
|
||||||
|
global _%1
|
||||||
|
%define %1 _%1
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to start a C callable function. This will be a far function for
|
||||||
|
; 16-bit code, and a near function for 32-bit code.
|
||||||
|
|
||||||
|
%imacro cprocstatic 1
|
||||||
|
%push cproc
|
||||||
|
%1:
|
||||||
|
%ifdef flatmodel
|
||||||
|
%stacksize flat
|
||||||
|
%define ret retn
|
||||||
|
%else
|
||||||
|
%stacksize large
|
||||||
|
%define ret retf
|
||||||
|
%endif
|
||||||
|
%assign %$localsize 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro cprocstart 1
|
||||||
|
%push cproc
|
||||||
|
cglobalfunc %1
|
||||||
|
%1:
|
||||||
|
%ifdef flatmodel
|
||||||
|
%stacksize flat
|
||||||
|
%define ret retn
|
||||||
|
%else
|
||||||
|
%stacksize large
|
||||||
|
%define ret retf
|
||||||
|
%endif
|
||||||
|
%assign %$localsize 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
|
||||||
|
; calling conventions are always _far _pascal for 16 bit DLL's, we actually
|
||||||
|
; rename this routine with an extra underscore with 'C' calling conventions
|
||||||
|
; and a small DLL stub will be provided by the high level code to call the
|
||||||
|
; assembler routine.
|
||||||
|
|
||||||
|
%imacro cprocstartdll16 1
|
||||||
|
%ifdef __WINDOWS16__
|
||||||
|
cprocstart _%1
|
||||||
|
%else
|
||||||
|
cprocstart %1
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to start a C callable near function.
|
||||||
|
|
||||||
|
%imacro cprocnear 1
|
||||||
|
%push cproc
|
||||||
|
cglobalfunc %1
|
||||||
|
%1:
|
||||||
|
%define ret retn
|
||||||
|
%ifdef flatmodel
|
||||||
|
%stacksize flat
|
||||||
|
%else
|
||||||
|
%stacksize small
|
||||||
|
%endif
|
||||||
|
%assign %$localsize 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to start a C callable far function.
|
||||||
|
|
||||||
|
%imacro cprocfar 1
|
||||||
|
%push cproc
|
||||||
|
cglobalfunc %1
|
||||||
|
%1:
|
||||||
|
%define ret retf
|
||||||
|
%ifdef flatmodel
|
||||||
|
%stacksize flat
|
||||||
|
%else
|
||||||
|
%stacksize large
|
||||||
|
%endif
|
||||||
|
%assign %$localsize 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to end a C function
|
||||||
|
|
||||||
|
%imacro cprocend 0
|
||||||
|
%pop
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macros for entering and exiting C callable functions. Note that we must
|
||||||
|
; always save and restore the SI and DI registers for C functions, and for
|
||||||
|
; 32 bit C functions we also need to save and restore EBX and clear the
|
||||||
|
; direction flag.
|
||||||
|
|
||||||
|
%imacro enter_c 0
|
||||||
|
push _bp
|
||||||
|
mov _bp,_sp
|
||||||
|
%ifnidn %$localsize,0
|
||||||
|
sub _sp,%$localsize
|
||||||
|
%endif
|
||||||
|
%ifdef flatmodel
|
||||||
|
push ebx
|
||||||
|
%endif
|
||||||
|
push _si
|
||||||
|
push _di
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro leave_c 0
|
||||||
|
pop _di
|
||||||
|
pop _si
|
||||||
|
%ifdef flatmodel
|
||||||
|
pop ebx
|
||||||
|
cld
|
||||||
|
%endif
|
||||||
|
%ifnidn %$localsize,0
|
||||||
|
mov _sp,_bp
|
||||||
|
%endif
|
||||||
|
pop _bp
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro use_ebx 0
|
||||||
|
%ifdef flatmodel
|
||||||
|
push ebx
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro unuse_ebx 0
|
||||||
|
%ifdef flatmodel
|
||||||
|
pop ebx
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
|
||||||
|
; be used in assembly routines. This evaluates to nothing in the flat memory
|
||||||
|
; model, but is saves and restores DS in the large memory model.
|
||||||
|
|
||||||
|
%imacro use_ds 0
|
||||||
|
%ifndef flatmodel
|
||||||
|
push ds
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro unuse_ds 0
|
||||||
|
%ifndef flatmodel
|
||||||
|
pop ds
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro use_es 0
|
||||||
|
%ifndef flatmodel
|
||||||
|
push es
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro unuse_es 0
|
||||||
|
%ifndef flatmodel
|
||||||
|
pop es
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macros for loading the address of a data pointer into a segment and
|
||||||
|
; index register pair. The %imacro explicitly loads DS or ES in the 16 bit
|
||||||
|
; memory model, or it simply loads the offset into the register in the flat
|
||||||
|
; memory model since DS and ES always point to all addressable memory. You
|
||||||
|
; must use the correct _REG (ie: _BX) %imacros for documentation purposes.
|
||||||
|
|
||||||
|
%imacro _lds 2
|
||||||
|
%ifdef flatmodel
|
||||||
|
mov %1,%2
|
||||||
|
%else
|
||||||
|
lds %1,%2
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro _les 2
|
||||||
|
%ifdef flatmodel
|
||||||
|
mov %1,%2
|
||||||
|
%else
|
||||||
|
les %1,%2
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macros for adding and subtracting a value from registers. Two value are
|
||||||
|
; provided, one for 16 bit modes and another for 32 bit modes (the extended
|
||||||
|
; register is used in 32 bit modes).
|
||||||
|
|
||||||
|
%imacro _add 3
|
||||||
|
%ifdef flatmodel
|
||||||
|
add e%1, %3
|
||||||
|
%else
|
||||||
|
add %1, %2
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro _sub 3
|
||||||
|
%ifdef flatmodel
|
||||||
|
sub e%1, %3
|
||||||
|
%else
|
||||||
|
sub %1, %2
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to clear the high order word for the 32 bit extended registers.
|
||||||
|
; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
|
||||||
|
; value, and will evaluate to nothing in 16 bit modes.
|
||||||
|
|
||||||
|
%imacro clrhi 1
|
||||||
|
%ifdef flatmodel
|
||||||
|
movzx e%1,%1
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro sgnhi 1
|
||||||
|
%ifdef flatmodel
|
||||||
|
movsx e%1,%1
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to load an extended register with an integer value in either mode
|
||||||
|
|
||||||
|
%imacro loadint 2
|
||||||
|
%ifdef flatmodel
|
||||||
|
mov e%1,%2
|
||||||
|
%else
|
||||||
|
xor e%1,e%1
|
||||||
|
mov %1,%2
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macros to load and store integer values with string instructions
|
||||||
|
|
||||||
|
%imacro LODSINT 0
|
||||||
|
%ifdef flatmodel
|
||||||
|
lodsd
|
||||||
|
%else
|
||||||
|
lodsw
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro STOSINT 0
|
||||||
|
%ifdef flatmodel
|
||||||
|
stosd
|
||||||
|
%else
|
||||||
|
stosw
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macros to provide resb, resw, resd compatibility with NASM
|
||||||
|
|
||||||
|
%imacro dclb 1
|
||||||
|
times %1 db 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro dclw 1
|
||||||
|
times %1 dw 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro dcld 1
|
||||||
|
times %1 dd 0
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to get the addres of the GOT for Linux/FreeBSD shared
|
||||||
|
; libraries into the EBX register.
|
||||||
|
|
||||||
|
%imacro get_GOT 1
|
||||||
|
call %%getgot
|
||||||
|
%%getgot: pop %1
|
||||||
|
add %1,_GLOBAL_OFFSET_TABLE_+$$-%%getgot wrt ..gotpc
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Macro to get the address of a *local* variable that is global to
|
||||||
|
; a single module in a manner that will work correctly when compiled
|
||||||
|
; into a Linux shared library. Note that this will *not* work for
|
||||||
|
; variables that are defined as global to all modules. For that
|
||||||
|
; use the LEA_G macro
|
||||||
|
|
||||||
|
%macro LEA_L 2
|
||||||
|
%ifdef __PIC__
|
||||||
|
get_GOT %1
|
||||||
|
lea %1,[%1+%2 wrt ..gotoff]
|
||||||
|
%else
|
||||||
|
lea %1,[%2]
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; Same macro as above but for global variables public to *all*
|
||||||
|
; modules.
|
||||||
|
|
||||||
|
%macro LEA_G 2
|
||||||
|
%ifdef __PIC__
|
||||||
|
get_GOT %1
|
||||||
|
mov %1,[%1+%2 wrt ..got]
|
||||||
|
%else
|
||||||
|
lea %1,[%2]
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; macros to declare assembler function stubs for function structures
|
||||||
|
|
||||||
|
%imacro BEGIN_STUBS_DEF 2
|
||||||
|
begdataseg _STUBS
|
||||||
|
%ifdef __NOU_VAR__
|
||||||
|
extern %1
|
||||||
|
%define STUBS_START %1
|
||||||
|
%else
|
||||||
|
extern _%1
|
||||||
|
%define STUBS_START _%1
|
||||||
|
%endif
|
||||||
|
enddataseg _STUBS
|
||||||
|
begcodeseg _STUBS
|
||||||
|
%assign off %2
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro DECLARE_STUB 1
|
||||||
|
%ifdef __PIC__
|
||||||
|
global %1:function
|
||||||
|
%1:
|
||||||
|
get_GOT eax
|
||||||
|
mov eax,[eax+STUBS_START wrt ..got]
|
||||||
|
jmp [eax+off]
|
||||||
|
%else
|
||||||
|
%ifdef __NOU__
|
||||||
|
global %1
|
||||||
|
%1:
|
||||||
|
%else
|
||||||
|
global _%1
|
||||||
|
_%1:
|
||||||
|
%endif
|
||||||
|
jmp [DWORD STUBS_START+off]
|
||||||
|
%endif
|
||||||
|
%assign off off+4
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro SKIP_STUB 1
|
||||||
|
%assign off off+4
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro DECLARE_STDCALL 2
|
||||||
|
%ifdef STDCALL_MANGLE
|
||||||
|
global _%1@%2
|
||||||
|
_%1@%2:
|
||||||
|
%else
|
||||||
|
%ifdef STDCALL_USCORE
|
||||||
|
global _%1
|
||||||
|
_%1:
|
||||||
|
%else
|
||||||
|
global %1
|
||||||
|
%1:
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
jmp [DWORD STUBS_START+off]
|
||||||
|
%assign off off+4
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro END_STUBS_DEF 0
|
||||||
|
endcodeseg _STUBS
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; macros to declare assembler import stubs for binary loadable drivers
|
||||||
|
|
||||||
|
%imacro BEGIN_IMPORTS_DEF 1
|
||||||
|
BEGIN_STUBS_DEF %1,4
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
ifndef LOCAL_DECLARE_IMP
|
||||||
|
%imacro DECLARE_IMP 2
|
||||||
|
DECLARE_STUB %1
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro DECLARE_PTR 2
|
||||||
|
DECLARE_STUB %1
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro SKIP_IMP 2
|
||||||
|
SKIP_STUB %1
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro SKIP_PTR 2
|
||||||
|
SKIP_STUB %1
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro SKIP_IMP2 1
|
||||||
|
DECLARE_STUB %1
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%imacro SKIP_IMP3 1
|
||||||
|
SKIP_STUB %1
|
||||||
|
%endmacro
|
||||||
|
endif
|
||||||
|
|
||||||
|
%imacro END_IMPORTS_DEF 0
|
||||||
|
END_STUBS_DEF
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%endif
|
||||||
|
|
|
@ -104,14 +104,7 @@ static char rcsid =
|
||||||
|
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
#include "mmx.h"
|
#include "mmx.h"
|
||||||
/* Function to check the CPU flags */
|
#include "SDL_cpuinfo.h"
|
||||||
#define MMX_CPU 0x800000
|
|
||||||
#define CPU_Flags() Hermes_X86_CPU()
|
|
||||||
#define X86_ASSEMBLER
|
|
||||||
#define HermesConverterInterface void
|
|
||||||
#define HermesClearInterface void
|
|
||||||
#define STACKCALL
|
|
||||||
#include "HeadX86.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
|
@ -657,7 +650,7 @@ do { \
|
||||||
if(alpha == 128) \
|
if(alpha == 128) \
|
||||||
blitter(2, Uint8, ALPHA_BLIT16_565_50); \
|
blitter(2, Uint8, ALPHA_BLIT16_565_50); \
|
||||||
else { \
|
else { \
|
||||||
if((CPU_Flags()&MMX_CPU)!=0) \
|
if(SDL_HasMMX()) \
|
||||||
blitter(2, Uint8, ALPHA_BLIT16_565MMX); \
|
blitter(2, Uint8, ALPHA_BLIT16_565MMX); \
|
||||||
else \
|
else \
|
||||||
blitter(2, Uint8, ALPHA_BLIT16_565); \
|
blitter(2, Uint8, ALPHA_BLIT16_565); \
|
||||||
|
@ -673,7 +666,7 @@ do { \
|
||||||
if(alpha == 128) \
|
if(alpha == 128) \
|
||||||
blitter(2, Uint8, ALPHA_BLIT16_555_50); \
|
blitter(2, Uint8, ALPHA_BLIT16_555_50); \
|
||||||
else { \
|
else { \
|
||||||
if((CPU_Flags()&MMX_CPU)!=0) \
|
if(SDL_HasMMX()) \
|
||||||
blitter(2, Uint8, ALPHA_BLIT16_555MMX); \
|
blitter(2, Uint8, ALPHA_BLIT16_555MMX); \
|
||||||
else \
|
else \
|
||||||
blitter(2, Uint8, ALPHA_BLIT16_555); \
|
blitter(2, Uint8, ALPHA_BLIT16_555); \
|
||||||
|
@ -698,14 +691,14 @@ do { \
|
||||||
|| fmt->Bmask == 0xff00)) { \
|
|| fmt->Bmask == 0xff00)) { \
|
||||||
if(alpha == 128) \
|
if(alpha == 128) \
|
||||||
{ \
|
{ \
|
||||||
if((CPU_Flags()&MMX_CPU)!=0) \
|
if(SDL_HasMMX()) \
|
||||||
blitter(4, Uint16, ALPHA_BLIT32_888_50MMX);\
|
blitter(4, Uint16, ALPHA_BLIT32_888_50MMX);\
|
||||||
else \
|
else \
|
||||||
blitter(4, Uint16, ALPHA_BLIT32_888_50);\
|
blitter(4, Uint16, ALPHA_BLIT32_888_50);\
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
if((CPU_Flags()&MMX_CPU)!=0) \
|
if(SDL_HasMMX()) \
|
||||||
blitter(4, Uint16, ALPHA_BLIT32_888MMX);\
|
blitter(4, Uint16, ALPHA_BLIT32_888MMX);\
|
||||||
else \
|
else \
|
||||||
blitter(4, Uint16, ALPHA_BLIT32_888); \
|
blitter(4, Uint16, ALPHA_BLIT32_888); \
|
||||||
|
|
|
@ -38,16 +38,8 @@ static char rcsid =
|
||||||
#include "SDL_memops.h"
|
#include "SDL_memops.h"
|
||||||
|
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
|
#include "SDL_cpuinfo.h"
|
||||||
#include "mmx.h"
|
#include "mmx.h"
|
||||||
/* Function to check the CPU flags */
|
|
||||||
#define MMX_CPU 0x800000
|
|
||||||
#define SSE_CPU 0x2000000
|
|
||||||
#define CPU_Flags() Hermes_X86_CPU()
|
|
||||||
#define X86_ASSEMBLER
|
|
||||||
#define HermesConverterInterface void
|
|
||||||
#define HermesClearInterface void
|
|
||||||
#define STACKCALL
|
|
||||||
#include "HeadX86.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The general purpose software blit routine */
|
/* The general purpose software blit routine */
|
||||||
|
@ -166,9 +158,6 @@ static void SDL_BlitCopy(SDL_BlitInfo *info)
|
||||||
Uint8 *src, *dst;
|
Uint8 *src, *dst;
|
||||||
int w, h;
|
int w, h;
|
||||||
int srcskip, dstskip;
|
int srcskip, dstskip;
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
|
||||||
Uint32 f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
w = info->d_width*info->dst->BytesPerPixel;
|
w = info->d_width*info->dst->BytesPerPixel;
|
||||||
h = info->d_height;
|
h = info->d_height;
|
||||||
|
@ -177,8 +166,7 @@ static void SDL_BlitCopy(SDL_BlitInfo *info)
|
||||||
srcskip = w+info->s_skip;
|
srcskip = w+info->s_skip;
|
||||||
dstskip = w+info->d_skip;
|
dstskip = w+info->d_skip;
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
f=CPU_Flags();
|
if(SDL_HasSSE())
|
||||||
if((f&(MMX_CPU|SSE_CPU))==(MMX_CPU|SSE_CPU))
|
|
||||||
{
|
{
|
||||||
while ( h-- ) {
|
while ( h-- ) {
|
||||||
SDL_memcpySSE(dst, src, w);
|
SDL_memcpySSE(dst, src, w);
|
||||||
|
@ -190,7 +178,7 @@ static void SDL_BlitCopy(SDL_BlitInfo *info)
|
||||||
::);
|
::);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if((f&(MMX_CPU))!=0)
|
if(SDL_HasMMX())
|
||||||
{
|
{
|
||||||
while ( h-- ) {
|
while ( h-- ) {
|
||||||
SDL_memcpyMMX(dst, src, w);
|
SDL_memcpyMMX(dst, src, w);
|
||||||
|
|
|
@ -32,16 +32,9 @@ static char rcsid =
|
||||||
#include "SDL_blit.h"
|
#include "SDL_blit.h"
|
||||||
|
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
#include "mmx.h"
|
|
||||||
/* Function to check the CPU flags */
|
/* Function to check the CPU flags */
|
||||||
#define MMX_CPU 0x800000
|
#include "SDL_cpuinfo.h"
|
||||||
#define TDNOW_CPU 0x80000000
|
#include "mmx.h"
|
||||||
#define CPU_Flags() Hermes_X86_CPU()
|
|
||||||
#define X86_ASSEMBLER
|
|
||||||
#define HermesConverterInterface void
|
|
||||||
#define HermesClearInterface void
|
|
||||||
#define STACKCALL
|
|
||||||
#include "HeadX86.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Functions to perform alpha blended blitting */
|
/* Functions to perform alpha blended blitting */
|
||||||
|
@ -1387,7 +1380,7 @@ SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index)
|
||||||
if(df->Gmask == 0x7e0)
|
if(df->Gmask == 0x7e0)
|
||||||
{
|
{
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
if((CPU_Flags()&MMX_CPU)!=0)
|
if(SDL_HasMMX())
|
||||||
return Blit565to565SurfaceAlphaMMX;
|
return Blit565to565SurfaceAlphaMMX;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1396,7 +1389,7 @@ SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index)
|
||||||
else if(df->Gmask == 0x3e0)
|
else if(df->Gmask == 0x3e0)
|
||||||
{
|
{
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
if((CPU_Flags()&MMX_CPU)!=0)
|
if(SDL_HasMMX())
|
||||||
return Blit555to555SurfaceAlphaMMX;
|
return Blit555to555SurfaceAlphaMMX;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1413,7 +1406,7 @@ SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index)
|
||||||
&& sf->BytesPerPixel == 4)
|
&& sf->BytesPerPixel == 4)
|
||||||
{
|
{
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
if((CPU_Flags()&MMX_CPU)!=0)
|
if(SDL_HasMMX())
|
||||||
return BlitRGBtoRGBSurfaceAlphaMMX;
|
return BlitRGBtoRGBSurfaceAlphaMMX;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1453,12 +1446,10 @@ SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index)
|
||||||
&& sf->BytesPerPixel == 4)
|
&& sf->BytesPerPixel == 4)
|
||||||
{
|
{
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
Uint32 f;
|
if(SDL_Has3DNow())
|
||||||
f=CPU_Flags();
|
|
||||||
if((f&(TDNOW_CPU|MMX_CPU))==(TDNOW_CPU|MMX_CPU))
|
|
||||||
return BlitRGBtoRGBPixelAlphaMMX3DNOW;
|
return BlitRGBtoRGBPixelAlphaMMX3DNOW;
|
||||||
else
|
else
|
||||||
if((f&MMX_CPU)!=0)
|
if(SDL_HasMMX())
|
||||||
return BlitRGBtoRGBPixelAlphaMMX;
|
return BlitRGBtoRGBPixelAlphaMMX;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,14 +31,7 @@ static char rcsid =
|
||||||
#include "SDL_video.h"
|
#include "SDL_video.h"
|
||||||
#include "SDL_blit.h"
|
#include "SDL_blit.h"
|
||||||
#include "SDL_byteorder.h"
|
#include "SDL_byteorder.h"
|
||||||
|
#include "SDL_cpuinfo.h"
|
||||||
/* Function to check the CPU flags */
|
|
||||||
#define MMX_CPU 0x800000
|
|
||||||
#ifdef USE_ASMBLIT
|
|
||||||
#define CPU_Flags() Hermes_X86_CPU()
|
|
||||||
#else
|
|
||||||
#define CPU_Flags() 0L
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Functions to blit from N-bit surfaces to other surfaces */
|
/* Functions to blit from N-bit surfaces to other surfaces */
|
||||||
|
|
||||||
|
@ -1429,7 +1422,7 @@ struct blit_table {
|
||||||
Uint32 srcR, srcG, srcB;
|
Uint32 srcR, srcG, srcB;
|
||||||
int dstbpp;
|
int dstbpp;
|
||||||
Uint32 dstR, dstG, dstB;
|
Uint32 dstR, dstG, dstB;
|
||||||
Uint32 cpu_flags;
|
SDL_bool cpu_mmx;
|
||||||
void *aux_data;
|
void *aux_data;
|
||||||
SDL_loblit blitfunc;
|
SDL_loblit blitfunc;
|
||||||
enum { NO_ALPHA, SET_ALPHA, COPY_ALPHA } alpha;
|
enum { NO_ALPHA, SET_ALPHA, COPY_ALPHA } alpha;
|
||||||
|
@ -1466,19 +1459,19 @@ static const struct blit_table normal_blit_3[] = {
|
||||||
static const struct blit_table normal_blit_4[] = {
|
static const struct blit_table normal_blit_4[] = {
|
||||||
#ifdef USE_ASMBLIT
|
#ifdef USE_ASMBLIT
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
|
||||||
MMX_CPU, ConvertMMXpII32_16RGB565, ConvertMMX, NO_ALPHA },
|
1, ConvertMMXpII32_16RGB565, ConvertMMX, NO_ALPHA },
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
|
||||||
0, ConvertX86p32_16RGB565, ConvertX86, NO_ALPHA },
|
0, ConvertX86p32_16RGB565, ConvertX86, NO_ALPHA },
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
|
||||||
MMX_CPU, ConvertMMXpII32_16BGR565, ConvertMMX, NO_ALPHA },
|
1, ConvertMMXpII32_16BGR565, ConvertMMX, NO_ALPHA },
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
|
||||||
0, ConvertX86p32_16BGR565, ConvertX86, NO_ALPHA },
|
0, ConvertX86p32_16BGR565, ConvertX86, NO_ALPHA },
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
|
||||||
MMX_CPU, ConvertMMXpII32_16RGB555, ConvertMMX, NO_ALPHA },
|
1, ConvertMMXpII32_16RGB555, ConvertMMX, NO_ALPHA },
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
|
||||||
0, ConvertX86p32_16RGB555, ConvertX86, NO_ALPHA },
|
0, ConvertX86p32_16RGB555, ConvertX86, NO_ALPHA },
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
|
||||||
MMX_CPU, ConvertMMXpII32_16BGR555, ConvertMMX, NO_ALPHA },
|
1, ConvertMMXpII32_16BGR555, ConvertMMX, NO_ALPHA },
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
|
||||||
0, ConvertX86p32_16BGR555, ConvertX86, NO_ALPHA },
|
0, ConvertX86p32_16BGR555, ConvertX86, NO_ALPHA },
|
||||||
{ 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF,
|
{ 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF,
|
||||||
|
@ -1581,8 +1574,7 @@ SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int blit_index)
|
||||||
dstfmt->Gmask == table[which].dstG &&
|
dstfmt->Gmask == table[which].dstG &&
|
||||||
dstfmt->Bmask == table[which].dstB &&
|
dstfmt->Bmask == table[which].dstB &&
|
||||||
(a_need & table[which].alpha) == a_need &&
|
(a_need & table[which].alpha) == a_need &&
|
||||||
(CPU_Flags()&table[which].cpu_flags) ==
|
(table[which].cpu_mmx == SDL_HasMMX()))
|
||||||
table[which].cpu_flags )
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sdata->aux_data = table[which].aux_data;
|
sdata->aux_data = table[which].aux_data;
|
||||||
|
|
|
@ -92,27 +92,11 @@ static char rcsid =
|
||||||
|
|
||||||
#include "SDL_error.h"
|
#include "SDL_error.h"
|
||||||
#include "SDL_video.h"
|
#include "SDL_video.h"
|
||||||
|
#include "SDL_cpuinfo.h"
|
||||||
#include "SDL_stretch_c.h"
|
#include "SDL_stretch_c.h"
|
||||||
#include "SDL_yuvfuncs.h"
|
#include "SDL_yuvfuncs.h"
|
||||||
#include "SDL_yuv_sw_c.h"
|
#include "SDL_yuv_sw_c.h"
|
||||||
|
|
||||||
/* Function to check the CPU flags */
|
|
||||||
#define MMX_CPU 0x800000
|
|
||||||
#ifdef USE_ASMBLIT
|
|
||||||
#define CPU_Flags() Hermes_X86_CPU()
|
|
||||||
#else
|
|
||||||
#define CPU_Flags() 0L
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ASMBLIT
|
|
||||||
#define X86_ASSEMBLER
|
|
||||||
#define HermesConverterInterface void
|
|
||||||
#define HermesClearInterface void
|
|
||||||
#define STACKCALL
|
|
||||||
|
|
||||||
#include "HeadX86.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The functions used to manipulate software video overlays */
|
/* The functions used to manipulate software video overlays */
|
||||||
static struct private_yuvhwfuncs sw_yuvfuncs = {
|
static struct private_yuvhwfuncs sw_yuvfuncs = {
|
||||||
SDL_LockYUV_SW,
|
SDL_LockYUV_SW,
|
||||||
|
@ -956,7 +940,7 @@ SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_S
|
||||||
Uint32 *r_2_pix_alloc;
|
Uint32 *r_2_pix_alloc;
|
||||||
Uint32 *g_2_pix_alloc;
|
Uint32 *g_2_pix_alloc;
|
||||||
Uint32 *b_2_pix_alloc;
|
Uint32 *b_2_pix_alloc;
|
||||||
int i, cpu_mmx;
|
int i;
|
||||||
int CR, CB;
|
int CR, CB;
|
||||||
Uint32 Rmask, Gmask, Bmask;
|
Uint32 Rmask, Gmask, Bmask;
|
||||||
|
|
||||||
|
@ -1082,11 +1066,10 @@ SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_S
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case SDL_YV12_OVERLAY:
|
case SDL_YV12_OVERLAY:
|
||||||
case SDL_IYUV_OVERLAY:
|
case SDL_IYUV_OVERLAY:
|
||||||
cpu_mmx = CPU_Flags() & MMX_CPU;
|
|
||||||
if ( display->format->BytesPerPixel == 2 ) {
|
if ( display->format->BytesPerPixel == 2 ) {
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
/* inline assembly functions */
|
/* inline assembly functions */
|
||||||
if ( cpu_mmx && (Rmask == 0xF800) &&
|
if ( SDL_HasMMX() && (Rmask == 0xF800) &&
|
||||||
(Gmask == 0x07E0) &&
|
(Gmask == 0x07E0) &&
|
||||||
(Bmask == 0x001F) &&
|
(Bmask == 0x001F) &&
|
||||||
(width & 15) == 0) {
|
(width & 15) == 0) {
|
||||||
|
@ -1108,7 +1091,7 @@ SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_S
|
||||||
if ( display->format->BytesPerPixel == 4 ) {
|
if ( display->format->BytesPerPixel == 4 ) {
|
||||||
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||||
/* inline assembly functions */
|
/* inline assembly functions */
|
||||||
if ( cpu_mmx && (Rmask == 0x00FF0000) &&
|
if ( SDL_HasMMX() && (Rmask == 0x00FF0000) &&
|
||||||
(Gmask == 0x0000FF00) &&
|
(Gmask == 0x0000FF00) &&
|
||||||
(Bmask == 0x000000FF) &&
|
(Bmask == 0x000000FF) &&
|
||||||
(width & 15) == 0) {
|
(width & 15) == 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue