DOSBox 0.50

This commit is contained in:
Carl.Kenner 2009-05-02 21:03:37 +00:00
parent 54be7b3aac
commit acd61d619e
347 changed files with 57061 additions and 145839 deletions

19
AUTHORS
View File

@ -1,11 +1,8 @@
The DOSBox Team
---------------
Sjoerd v.d. Berg <harekiet>
Peter Veenstra <qbix79>
Ulf Wohlers <finsterr>
Tommy Frössman <fanskapet>
Dean Beeler <canadacow>
Sebastian Strohhäcker <c2woody>
nick_without_<> @ users.sourceforge.net
The DOSBox Team
---------------
Sjoerd v.d. Berg <harekiet@zophar.net>
Peter Veenstra <qbix79@users.sourceforge.net>

680
COPYING
View File

@ -1,340 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 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.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 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.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

512
ChangeLog
View File

@ -1,509 +1,3 @@
0.72
- Fixed unitialized variable in joystick. (Fixes crashes on Vista and
Mac OS X)
- Some bugfixes and speedups to the 64 bit recompiling core.
- Fixed sign flag on soundblaster dma transfers (Space Quest 6 intro)
- Fixed a bug in keyboard layout processing code and fixed certain
layouts.
- Fixed Dreamweb.
- Improved speed unlocking when running cycles=max.
- Fixed a crash related to the tab completion in the shell.
- Improved aspect correction code. Should now be like how a real monitor
handles it.
- Fixed a bug in the xms status report code. (Blake Stone 1.0 shareware)
- Added a lot more keyboard layouts.
- Fix crash related to changing the scaler before a screen was created.
- Hopefully fixed compilation on *bsd.
- Enabled auto cpu core selection for recompiling core as well.
- Made the used joystick selectable when 4axis is specified.
- Added some hints for inexperienced DOS users to the shell.
0.71
- Add a new recompiling cpu core, which should be easier to port.
- Add 64 bit version of the recompiling core.
- Add mipsel 32 bit version of the recompiling core.
- Fix a few small problems with FCBs. (fixes Jewels of darkness and
cyrus chess)
- Raise some more exceptions. (fixes vbdos)
- Fix a few problems with the dynamic core. (fixes Inner Words,
Archmimedean Dynasty and others)
- Improve/Fix fallback code for certain graphics cards.
- Fix a few cd audio related bugs.
- Add an undocumented MSCDEX feature. (Fixes Ultimate Domain)
- Fix some pcspeaker mode. (fixes Test Drive and similar games)
- Improve dos keyinput handling. (fixes Wing Commander 3 exit dialog)
- Remove Exit condition on fully nested mode. (fixes some demo)
- Add image file size detection.
- Add/Fix some ansi codes. (fixes PC Larn and certain versions of
infocom games)
- Several general DOS fixes. (fixes nba95, hexit and various other games)
- Add some valid input checks. (fixes 3d body adventure and similar
games)
- Fix digital joystick centering problem.
- Reenable textmode 54 and 55.
- Fix a pelmask problem with univbe 5.0 lite. (fixes Panzer General)
- Fix minor mixer underflow.
- Some general image and bios disk emulation fixes.
- Hopefully fix compilation on BSD and darwin.
- Try using ioctl cdrom access by default if possible.
- Fix some svga detection routine. (fixes Grandest Fleet 2 and Bobby Fischer
Teaches Chess)
- You can now close DOSBox using the status window in win32.
- Add support for NX enabled systems.
- Fix a casting error which only showed with certain compilers. (fixes
various games under mac os x and 64 bit linux)
- Improve timer and add gate 2 support. (fixes various games and
joystick problems)
- Improve mouse. Add undocumented backdoor. (fixes Last half of Darkness,
PC-BLOX and others)
- Add/improve support for ~ and ~username in all commands.
- Fix a font problem with the pcjr/tandy. (fixes personal deskmate 2)
- Change dma routine a bit. (fixes ticks in sound in various games)
- Allow read-only diskimages to be booted. (fixes various booter
games)
- Add basic hidden file support on cdrom images. (fixes Player
Manager 2)
- Add some rarely used functionality to the int10 mode setup. (fixes
WW2 Battles of the South pacific)
- Add ability to force scaler usage.
- Speed up flag generation and make it more 386-like.
- Some colourful feedback in the mapper.
- General code cleanup.
0.70
- Improve register handling and support with XMS.
- Fix some issues with deleting open files.(windows only issue)
- Add dummy LPT1 class. (windows only issue)
- Improve some of the internal dos commands. (choice, copy and shift)
- Improve ROM area. (for games that use it for random numbers or
overwrite it as some sort of detection thing)
- Improve compatibility of dynamic core by making it handle certain
pagefaults earlier.
- Move internal dos tables around so we have more umb memory.
- Add some dos tables.
- Dynamic core supports io exceptions.
- Move some interrupt handlers to XT Bios locations.
- Add a dynamic fpu on x86.
- Improve fpu on non-x86.
- Trapflag gets strict priority over hardware IRQs.
- Trapflag support for the dynamic core.
- Add dummy TRx handling.
- Fix a few rarely used character functions.
- Improve auto cycle guessing code.
- Improve and extend the joystick support.
- Add autofire support.
- Improve the mapper so you can map keys to the joystick and vice versa.
- A few game specific video card fixes.
- Fix some 64 bit cpu bugs.
- Add support for certain cdrom detection schemes.
- Improve HSG/Red Book support.
- Improve MSCDEX.
- Improve dynamic core support under intel macs.
- Add basic support for clipper programs.
- Add support for different keyboard layouts.
- Add auto core guessing.
- Fix a few flags bugs.
- Fix a few small cpu bugs.
- Improve soundblaster detection rate by various programs.
- Improve EMS emulation. (allow mapping of non standard regions)
- Improve keyboard input codes on various OS-es.
- Fix problems with filenames having stackdata in them.
- Changed a few basic operations in DOSBox so they take emulated time.
- Improve dos ioctl functions.
- Extend cpu core so they are capable of detecting and raising a few
more exception types.
- Improve DOS functions when dealing with virtual drive.
- Improve FAT drives.
- Better handling of volume-labels in file functions.
- Image disk cycling capability. (prompt)
- Try to reduce the impact of using an analog joystick.
- Several measures to avoid code invalidation on certain types
of self modification in the dynamic core.
- Add dynamic core memory function inlining.
- A few small mouse improvements. (some games are using things they
shouldn't)
- Add nullmodem emulation.(h-a-l-9000)
- Some small cga and hercules fixes.
- Add more scalers (hq2x/hq3x/sai). (Kronuz)
- Change configuration file loading support. It now supports
multiple configuration files.
- Make dynamic core capable of running some win32s programs.
- Fix and add some rare soundblaster modes. (Srecko)
- Better soundblaster mixer controls. (Srecko)
- Make soundblaster installation under windows much easier.
- Add device control channel handling.
- GEMMIS support (ems under windows).
- Support more colours in win 3. (vasyl)
- Don't show unmounted drives in windows filemanager.
- Fix some bugs in the int13 handler.
- Simulate some side-effects of bios interrupt handlers on flags.
- Add IPX functions needed by netbios.
- Make ports take emulated time.
- Tabcompletion is now aware of the CD command.
- Add suppport for the dac pel mask.
- Fixes to hercules emulation, better detection and bank switching.
- Fixes to tandy emulation, 640x200x16 mode and different sizes bank.
- EGA/VGA memory changes detection for faster rendering.
- Gus 16 bit fixes.
- Many timer improvements.
- Some pcjr fixes.
- Some booter fixes.
- Many small fixes.
0.65
- Fixed FAT writing.
- Added some more missing DOS functions.
- Improved PIC so that it actually honours irq 2/9.
- Improved intelligent MPU-401 mode so that more games work with it.
- Some mouse fixes.
- Changed DMA transfers a bit so they bypass the paging tables.
- Added S3 XGA functionality.
- Improved paging so that read and write faults are handled differently.
- Rewrote exception handling a bit (no exception 0x0B with dos4gw anymore).
- Added IO exceptions in all but the dynamic core.
- Some ems improvements.
- Added midi-device selection code for the windows hosts.
- Fix crashes/segfaults related to the disabling of the pcspeaker.
- Added some more FILES=XX detection tricks.
- Fixed some vga detection schemes.
- Fixed screenshot corruption when using -noconsole in a read-only directory.
- Fix wrong scaled screenshots.
- Added some hidden file functions when using diskimages. (helps with cdrom
detection schemes)
- Fixed a bug in the mixer code, that muted the music in certain games.
- Added an assembly fpu core.
- Made the shell more flexible for batch files.
- Check for unaligned memory acces fixes hangups on ARM processors.
- Some 64 bit fixes.
- Added code to change configuration at runtime.
- Improved ADPCM emulation.
- Fixed a few cpu instructions.
- Always report vesa 2.0 and fix some colour issues with vesa games.
- Fix video mode 0x06 and 0x0a.
- Improvements to the joystick emulation. 4 buttons are supported as well.
- Add VCPI emulation for Origin games.
- Fixed a lot of things in the boot code. Most booters work now.
- Lots of improvements to the IPX emulation.
- Rewritten modem emulation. Should work with more games.
- Improvements to the dos memory managment routines.
- Add UMB (upper memory blocks) support.
- Emulate the pause key.
- Improve Composite CGA mode emulation.
- Lots of vga compatibility changes.
- Improved support for chained video modes.
- Improved mode and palette handling in cga modes.
- Mount accepts ~ now.
- Added a few of the EGA RIL functions.
- Added TandyDAC emulation.
- OS/2 support.
- Improved and speed up the dynamic cpu core.
- Fix some errors in the CD-ROM emulation layer.
- Added an automatic work-around for some graphics chipsets.
- Add PCjr support.
- Allow mousedriver to be replaced. Fixes a few games that come with their
own (internal) driver.
- Improved dynamic cpu core so it can handle pagefaults and some obscure
types of self-modifying code.
- Added -noautoexec switch to skip the contents of [autoexec] in the
configuration file.
- Improved v86 mode emulation (mainly for Strike Commander).
- Improved timer behavior.
- Improved extended keyboard support.
- Enhanced and added several DOS tables.
- Made core_full endian safe.
- Made pagefaults endian safe.
- Add support for moviecapturing
- Add support for 15/16/32 bit videomodes.
- Add some more VESA modi (4 bit).
- Add 1024x768 output.
- Changed screenrendering so it only draws changes to the screen.
- Allow remapping of the EMS page when the dma transfer was started from
the page frame
- Made EMS and DMA work together when playing from a mapped memory page.
- Renamed several configuration options, so that they are unique.
- Merged mpu and intelligent into one option.
- Merged fullfixed and fullresolution.
- Extended keys should be handled better.
- F11 and F12 work.
- Compilation fixes for various platforms.
- Fix a few crashes when giving bad input.
- Removed interp2x and added few new scalers.
- Reintroduce the lockfree mouse. (autolock=false)
- Add a larger cache for the dynamic cpu core.
- Improved soundblaster DSP, so it gets detected by creative tools.
- Lots of bugfixes.
- Even more bugfixes.
0.63
- Fixed crash with keymapper (ctrl-f1) and output=surface.
- Added unmounting.
- Fixed multiple issues with drive labels.
- Fixed most if not all FILES=XX problems.
- Added redirection in the shell.
- Fixed crashes with subst.
- Fixed multiple crashes with the drive images support.
- Added a missing fpu instruction.
- Fixed some cpu and fpu instructions.
- Fixed a small bug related to font loading.
- Rewrote the devices support.
- Added capslock/numlock checks on startup.
- Fixed wave writing.
- A few internal DOS fixes.
- Timer fixes for the hybrid loader.
- Some small soundblaster fixes.
- The drive cache can now be cleared by a keycombo. (CTRL-F4)
- A few keyboard fixes.
- Compilation fixes on various platforms.
- Quite some debugger improvements.
- Fixed dir only showing files after the first run on cdrom drives.
- Added some cdrom detection checks.
- Enabled insert in the shell. (Easier editing of commands)
- Changed order in which executables appear with tab-completion.
- Fixed some issues with raw opl recording and using a slightly different
format
0.62
- Added blinking support in the shell and some color fixes.
- Fixed commandline parsing when .bat files involved (fixes -exit)
- Fixed issues with tabs in commandline not being processed correctly.
- Cleaned/improved shutdown sequence.
- Added some more bios functions (wait and delay functions).
- Made our XMS driver conform the specs better. (c2woody)
- Added support for some more ems functions.
- Added intelligent mpu401 emulation. (Srecko)
- Added soundblaster 16 emulation.
- Rewrote GUS emulation to sound more authentic.
- Improved pc speaker emulation.
- Added an internal (programmable) mixer.
- Added support a few soundblaster/adlib detection routines.
- Fixed lot's of bugs related to DMA transfers.
- Added interpolating prebuffering mixer routines.
- Added recording of OPL commands and raw midi.
- Fixed some bugs with the wave recording.
- Changed sensitivity settings of the mouse.
- Added ps2 mouse-emulation in bios interrupts (c2woody).
- Fixed some bugs with mouse emulation limits.
- Fixed a bug with an unterminated string in the drivelabel.
- Changed file search routines a bit to be more compatible.
- Added support for attribute-searching with fcb's.
- Added basic SDA.
- Added TPA and DIB.
- Added Lot's of missing dos tables (c2woody).
- Changed psp and dta functions to use dta.
- Returned filename in ds:dx in create-random-file (c2woody).
- Fixed a bug with date and time used on open files.
- Some mscdex fixes.
- Added the -version switch, which makes dosbox report its version.
- Added a keymapper.
- Added basic IPX emulation.
- Added cdrom iso support and floppy images support.
- Added the possibity to boot another dos version.
- Added Serial passthrough support (win32 only).
- Added the possibility to pause dosbox.
- Changed OpenGL so that it is initialized only when used.
- Make dosbox run at higher priority when active and lower when inactive.
- Added direct draw output support (win32 only).
- Added current running program to title bar.
- Rewrote video emulation to support new scalers.
- Added new graphics scalers like advmame3x,tv2x.
- Added a support for a few anti-debugger tricks.
- Improved the handling of the tab-key.
- Improved support for the numeric keyboard.
- Fixed a few cpu opcodes.
- Added cpu core simple (for lowerend machines)
- Fixed some nasty bugs in the dynamic cpu core.
- Added a few (rarely used) fpu opcodes.
- Fixed various issues with GCC 3.4.
- Many internal timer improvements (PIT and PIC).
- Added some more PIC commands (c2woody).
- Added BCD counting to the timers.
- Fix some vesa functions.
- Add some basic support for 132x25 and 132x45 textmodes.
- Improved Tandy emulation a lot.
- Lowered cpu usage when dosbox is idle.
- Allow virtualisation of some basic IO-ports (c2woody).
0.61
- Added a beta dynamic cpu for x86 hosts (very unstable)
- Added opengl and hardware overlay display output
- Rewrote the vga screen updates to go in lines
- Added paging and v86 support to cpu emulation
- Added a config option to simulate a certain type of machine
- Added hercules graphics emulation
- Made CGA/TANDY modes more compatible
- Updated textmode drawing routines to support blinking colors
- Fixed VESA set page function that was documented wrong
- Fixed some wrongly emulated cpu opcodes.
- improved exception handling
- debugger: fixes; logging of gdt,lgt,idt, new commands(Fizzban)
- fixed some mscdex issues (drive letter header error, added get directory entry)
- added/fixed some bios funcs
- added some rarely used xms functions (thanks c2woody!)
- implemented GUS emulation
- Added 16-bit DMA support (for GUS and eventually SB16)
- Fixed many small bugs in filehandling routines
- Many small FPU fixes (c2woody/Fizzban)
- Some keyboard improvements (pharlab games)
- Some Timer and cmos/rtc fixes (Mirek/Srecko/Others)
- Lot's of mouse fixes (Help from various people)
- Enabled internal modem
- Made the DOS parsing routines a bit more flexible
- Added Subst (Srecko)
- Added cdrom ioctl support for linux (prompt)
- Many internal DOS fixes: memory/files/datastructures.
- Got some help from c2woody in allowing more than 1 irq being served
- Disabled DPMI (not needed anymore. DOSBox handles almost every extender)
- Search configfile in $HOME directory if none present in current directory
- Added another way to switch to protected mode. (Thanks Morten Eriksen!)
- Fixed some odd badly documented behaviour with PSP/DTA
- Added some warnings on opening of readonly files in writemode(DOS default).
- Many shell enhanchements
- Fixed a win32 specific bug dealing with filenames starting with a "."
- Fixed some bugs with the directory structure: not found/can't save errors
0.60
- rewrote memory system for future paging support
- fixed several EMS and XMS bugs and rewrite for new memory system
- added some support for tandy video modes
- added MAME Tandy 3 voice emulation
- added MAME CMS/GameBlaster emulation
- added serial port emulation with virtual tcp/ip modem (somewhat buggy)
- sound blaster emulation is now sb pro 2.0 compatible
- added basic support for 32-bit protected mode
- VGA now tries to emulate an S3 Trio 64 card with 2 MB
- VESA 2.0 support for some 256 color modes
- rewrote large piece of video bios code for better compatibility
- added support for the not inheritance flags.
- created functions for creating child psp.
- updated errorcodes of findfirst (thanks Mirek!)
- rewrote loggingsystem to generate less warnings
- added dos protected mode interface (dpmi)
- added cdrom label support
- improved cdrom audio playing
- fixed and improved directory cache
- debugger shows selector- and cpu mode info
- added SELINFO (selector information) command to debugger
- added reference counting for dos files
- added tab-completion
- added basic fpu support.
- fixed several bugs with case sensitive filesystems.
- added more shell commands and improved their behaviour.
- mouse improvements.
- real time clock improvements.
- DMA fixes.
- Improved .BAT file support.
0.58
- fixed date and time issues with fcbs
- added more commands to the internal Shell
- corrected config system when a old configfile was used
- fixed cga put and get pixel
- fixed some vga register getting reset to wrong values
- improved support for foreign keyboards
- improved joystick support
- made dosbox multithreaded again
- lot's of soundblaster fixes
- dma fixes
- cdrom support
- midi support
- added scale2x
- reenabled screenshot support
- joystick support fixes
- mouse improvements
- support for writing wavefiles
- added directory cache and longfilename support (longfilenames will be mangled)
- mouse fixes
- date and time updates at z:\
- added (partial) direct disk support. (works probably only if directory is mounted under a:\)
- added support for env variables. (must be set before starting dosbox: DOSBOX_SECTION_PROPERTY=value
like DOSBOX_SBLASTER_IRQ=1)
0.57
- added support for command /C
- fixed all fcb-write functions
- fixed fcb-parseline
- added debugger under linux/freebsd
- added debugger memory breakpoints and autolog function (heavy debug)
- added loadfix.com program that eats up memory (default 64kb)
Usage : loadfix [-option] [programname] [parameters]...
Example: loadfix mm2 (Allocates 64kb and starts executable mm2)
loadfix -32 mm2 (Allocates 32kb and starts executable mm2)
loadfix -128 (Allocates 128kb)
loadfix -f (frees all previous allocated memory)
- added echoing of characters for input function
- added support for backspace for input function
- added partial support for int10:01 set cursortype
- fixed most of the problems/bugs with character input.
- fixed allocationinfo call.(darksun series)
- improved dos support for non-existant functions
- Split screen support
- prefix 66 67 support
- rewrote timingscheme so 1000 hz timers don't cause problems anymore
- update adlib emulation
- fixed some isues with the mouse (double clicks and visible when it shouldn't be)
- improved mouse behaviour (mickey/pixel rate) and detection routines.
- basic ansi.sys support
- Disney sound system emulation
- rewrote upcase/lowcase functions so they work fine with gcc3.2
- SHELL: added rename and delete
- added support for command /C. Fixed crashes in the shell
- fixed various bugs when exiting dosbox
- fixed a bug in XMS
- fixed a bug with the joystick when pressing a button
- create nicer configfiles.
- bios_disk function improved.
- trapflag support
- improved vertical retrace timing.
- PIT Timer improvements and many bug fixes
- Many many bug fixes to the DOS subsystem
- Support for memory allocation strategy
- rewrote cpu mainloop to act more like a real cpu
0.56
- added support for a configclass/configfile
- added support for writing out the configclass into a configfile
- removed the language file and made it internal
- added support for writing the language file (will override the internal one)
- improved mousesupport
- updated readme
- support for screenshots
- some cpu-bug fixes
- dma changes
- Real Sound support
- EMM fixes and new functions.
- VGA fixes
- new wildcompare
- support for size and disktype at mount.
- added new debugger functionalities: start/trace into INTs, write processor status log,
step over rep and loop instructions, breakpoint support without using INT 03 (heavy debugging switch)
- Added more cpu instructions and changed the string operations.
- Added classes for most of the internal dos structures.
- Rewrote most of the fcb calls to use normal dos calls.
0.55
- fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned).
- fixed compilation error on FreeBSD when #disable_joystick was defined
- int10_writechar has been updated to move the cursor position.
- changed the basedir routines to use the current working dir instead of argv[0]. This will fix and brake things :)
- illegal command, now displays the command
- wildcmp updated to be case insensitive
- added fcb:open,close,findfirst, findnext.
- fixed rename in drive_local
- added new features to the debugger: breakpoint support / data view / command line
- partial support of list of lists (dos info block)
- full emm 3.2 support
- partial emm 4.0 support
- fixes to graphics core fonts (text in sierra games is now correct)
- improved support for user mousehandlers
- fixed EGA graphics
- fixed VGA graphics
- fixed write with size 0
- changed memory management.
- fixed and cleaned up the cpu flags.
- changed interrupt handler.
- speeded up the graphics.
- speeded up the cpu-core
- changed dma
- improved dma streams from emm memory
- added some cga videomodes
- added more funtions to the keyboard handler
- fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned).

133
INSTALL
View File

@ -1,97 +1,36 @@
Things needed for compilation.
SDL
The Simple DirectMedia Library available at http://www.libsdl.org
The dll distributed with the windows version of DOSBox is slightly
modified. You can find the changes in the sourcepackage of DOSBox
(src/platform/sdl-win32.diff). If you want the patched sourcetree
send us an email. (see README)
Licensed under LGPL
Curses (optional)
If you want to enable the debugger you need a curses library.
ncurses should be installed on just about every unix distro.
For win32 get pdcurses at http://pdcurses.sourceforge.net
License: Open source
Libpng (optional)
Needed for the screenshots.
For win32 get libpng from http://gnuwin32.sourceforge.net/packages.html
See http://www.libpng.org/pub/png/ for more details.
License: Open Source
Zlib (optional)
Needed by libpng.
For win32 get libz (rename to zlib) from http://gnuwin32.sourceforge.net/packages.html
See http://www.zlib.net for more details.
License: Open Source
SDL_Net (optional)
For modem/ipx support. Get it from http://www.libsdl.org/projects/SDL_net/
Licensed under LGPL
SDL_Sound
For compressed audio on diskimages. (optional)
This is for cue/bin cdrom images with compressed (mp3/ogg) audio tracks.
Get it from http://icculus.org/SDL_sound
Licenced under LGPL
ALSA_Headers
(optional)
for Alsa support under linux. Part of the linux kernel sources
Licensed under LGPL
If you want compile from the CVS under a unix system, you'll also need
automake (>=1.6), autoconf(>=2.50). Should be available at http://www.gnu.org
For building on unix systems.
If you are building from the cvs run ./autogen.sh first before doing the following.
1. ./configure
2. make
In step 1 you could add the following switches:
--enable-debug
enables the internal debugger. --enable-debug=heavy enables even more
debug options. Dosbox should then be run from a xterm and when the sdl-
window is active press alt-pause to enter the debugger.
--enable-core-inline
enables some memory increasing inlines. This greatly increases
compiletime for maybe a increase in speed.
--disable-fpu
disables the emulated fpu. Although the fpu emulation code isn't
finished and isn't entirely accurate it's advised to leave it on.
--disable-fpu-x86
disables the assembly fpu core. Although relatively new the x86 fpu
core has more accuracy then the regular fpu core.
--disable-dynamic-x86
disables the dynamic x86 specific cpu core. Although it might be
be a bit unstable, it can greatly improve the speed of dosbox on x86
hosts.
Please note that this option on x86 will result in a different
dynamic/recompiling cpu core being compiled then the default.
For more information see the option --disable-dynrec
--disable-dynrec
disables the recompiling cpu core. Currently x86 and x86_64 only.
You can activate this core on x86 by disabling the dynamic-x86 core.
--disable-dynamic-core
disables all dynamic cores. (same effect as
--disable-dynamic-x86 --disable-dynrec)
--disable-unaligned-memory
disables unaligned memory access.
Check the src subdir for the binary.
NOTE: If capslock and numlock appear to be broken. open
src/ints/bios_keyboard.cpp and go to line 30 and read there how to fix it.
Build instructions for VC++6
Don't use VC++ 6:it creates faulty code in core_normal.cpp
First of all if you are running a non-x86 machine this will not work,
code only works for big-endian machines for now :)
Things needed for compilation.
SDL
The Simple DirectMedia Library available at http://www.libsdl.org
Curses
If you want to enable the debugger you need a curses library.
ncurses should be installed on just about every unix distro.
For win32 get pdcurses at http://pdcurses.sourceforge.net
If you want compile from the CVS under a unix system, you'll also need
automake, autoconf. Should be available at http://www.gnu.org
For building on unix systems.
If you are building from the cvs run ./autogen.sh first before doing the following.
1. ./configure
2. Check settings.h for some setup options.
3. make
Check the src subdir for the binary and dosbox.lang file.
These 2 files should be in the same dir if you want to run dosbox.
Compiling on FreeBSD might be a problem since SDL has no joystick support there.
To get around this edit sdlmain.cpp to enable some #define.
Let's hope someday the sdl people will just report 0 joysticks in freebsd or get it working some other way :)
Build instructions for VC++6
Open the workspace in the visualc subdir and build from there.
Copy the src/dosbox.lang file to the same dir as your executable.

View File

@ -1,4 +1,7 @@
# Main Makefile for DOSBox
EXTRA_DIST = autogen.sh
SUBDIRS = src include docs visualc_net
# Main Makefile for DOSBox
EXTRA_DIST = settings.h autogen.sh
SUBDIRS = src include visualc

428
Makefile.in Normal file
View File

@ -0,0 +1,428 @@
# Makefile.in generated by automake 1.6.1 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Main Makefile for DOSBox
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
EXTRA_DIST = settings.h autogen.sh
SUBDIRS = src include visualc
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
uninstall-info-recursive all-recursive install-data-recursive \
install-exec-recursive installdirs-recursive install-recursive \
uninstall-recursive check-recursive installcheck-recursive
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
Makefile.in NEWS THANKS acinclude.m4 aclocal.m4 config.guess \
config.h.in config.sub configure configure.in depcomp \
install-sh missing mkinstalldirs
DIST_SUBDIRS = $(SUBDIRS)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnits Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): configure.in acinclude.m4
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOHEADER)
touch $(srcdir)/config.h.in
distclean-hdr:
-rm -f config.h
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = .
distdir = $(PACKAGE)-$(VERSION)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
GZIP_ENV = --best
distcleancheck_listfiles = find . -type f -print
distdir: $(DISTFILES)
@if sed 15q $(srcdir)/NEWS | fgrep -e "$(VERSION)" >/dev/null; \
then :; else \
echo "NEWS not updated; not releasing" 1>&2; \
exit 1; \
fi
$(am__remove_distdir)
mkdir $(distdir)
@for file in $(DISTFILES); do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist dist-all: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
$(am__remove_distdir)
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/=inst && pwd` \
&& cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& (test `find $$dc_install_base -type f -print | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
find $$dc_install_base -type f -print ; \
exit 1; } >&2 ) \
&& $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
&& rm -f $(distdir).tar.gz \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x'
distcleancheck: distclean
if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f config.status config.cache config.log
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
clean-generic clean-recursive dist dist-all dist-gzip distcheck \
distclean distclean-generic distclean-hdr distclean-recursive \
distclean-tags distcleancheck distdir dvi dvi-am dvi-recursive \
info info-am info-recursive install install-am install-data \
install-data-am install-data-recursive install-exec \
install-exec-am install-exec-recursive install-info \
install-info-am install-info-recursive install-man \
install-recursive install-strip installcheck installcheck-am \
installdirs installdirs-am installdirs-recursive \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-generic \
mostlyclean-recursive tags tags-recursive uninstall \
uninstall-am uninstall-info-am uninstall-info-recursive \
uninstall-recursive
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

553
NEWS
View File

@ -1,530 +1,23 @@
0.72
- Fixed unitialized variable in joystick. (Fixes crashes on Vista and
Mac OS X)
- Some bugfixes and speedups to the 64 bit recompiling core.
- Fixed sign flag on soundblaster dma transfers (Space Quest 6 intro)
- Fixed a bug in keyboard layout processing code and fixed certain
layouts.
- Fixed Dreamweb.
- Improved speed unlocking when running cycles=max.
- Fixed a crash related to the tab completion in the shell.
- Improved aspect correction code. Should now be like how a real monitor
handles it.
- Fixed a bug in the xms status report code. (Blake Stone 1.0 shareware)
- Added a lot more keyboard layouts.
- Fix crash related to changing the scaler before a screen was created.
- Hopefully fixed compilation on *bsd.
- Enabled auto cpu core selection for recompiling core as well.
- Made the used joystick selectable when 4axis is specified.
- Added some hints for inexperienced DOS users to the shell.
0.71
- Add a new recompiling cpu core, which should be easier to port.
- Add 64 bit version of the recompiling core.
- Add mipsel 32 bit version of the recompiling core.
- Fix a few small problems with FCBs. (fixes Jewels of darkness and
cyrus chess)
- Raise some more exceptions. (fixes vbdos)
- Fix a few problems with the dynamic core. (fixes Inner Words,
Archmimedean Dynasty and others)
- Improve/Fix fallback code for certain graphics cards.
- Fix a few cd audio related bugs.
- Add an undocumented MSCDEX feature. (Fixes Ultimate Domain)
- Fix some pcspeaker mode. (fixes Test Drive and similar games)
- Improve dos keyinput handling. (fixes Wing Commander 3 exit dialog)
- Remove Exit condition on fully nested mode. (fixes some demo)
- Add image file size detection.
- Add/Fix some ansi codes. (fixes PC Larn and certain versions of
infocom games)
- Several general DOS fixes. (fixes nba95, hexit and various other games)
- Add some valid input checks. (fixes 3d body adventure and similar
games)
- Fix digital joystick centering problem.
- Reenable textmode 54 and 55.
- Fix a pelmask problem with univbe 5.0 lite. (fixes Panzer General)
- Fix minor mixer underflow.
- Some general image and bios disk emulation fixes.
- Hopefully fix compilation on BSD and darwin.
- Try using ioctl cdrom access by default if possible.
- Fix some svga detection routine. (fixes Grandest Fleet 2 and Bobby Fischer
Teaches Chess)
- You can now close DOSBox using the status window in win32.
- Add support for NX enabled systems.
- Fix a casting error which only showed with certain compilers. (fixes
various games under mac os x and 64 bit linux)
- Improve timer and add gate 2 support. (fixes various games and
joystick problems)
- Improve mouse. Add undocumented backdoor. (fixes Last half of Darkness,
PC-BLOX and others)
- Add/improve support for ~ and ~username in all commands.
- Fix a font problem with the pcjr/tandy. (fixes personal deskmate 2)
- Change dma routine a bit. (fixes ticks in sound in various games)
- Allow read-only diskimages to be booted. (fixes various booter
games)
- Add basic hidden file support on cdrom images. (fixes Player
Manager 2)
- Add some rarely used functionality to the int10 mode setup. (fixes
WW2 Battles of the South pacific)
- Add ability to force scaler usage.
- Speed up flag generation and make it more 386-like.
- Some colourful feedback in the mapper.
- General code cleanup.
0.70
- Improve register handling and support with XMS.
- Fix some issues with deleting open files.(windows only issue)
- Add dummy LPT1 class. (windows only issue)
- Improve some of the internal dos commands. (choice, copy and shift)
- Improve ROM area. (for games that use it for random numbers or
overwrite it as some sort of detection thing)
- Improve compatibility of dynamic core by making it handle certain
pagefaults earlier.
- Move internal dos tables around so we have more umb memory.
- Add some dos tables.
- Dynamic core supports io exceptions.
- Move some interrupt handlers to XT Bios locations.
- Add a dynamic fpu on x86.
- Improve fpu on non-x86.
- Trapflag gets strict priority over hardware IRQs.
- Trapflag support for the dynamic core.
- Add dummy TRx handling.
- Fix a few rarely used character functions.
- Improve auto cycle guessing code.
- Improve and extend the joystick support.
- Add autofire support.
- Improve the mapper so you can map keys to the joystick and vice versa.
- A few game specific video card fixes.
- Fix some 64 bit cpu bugs.
- Add support for certain cdrom detection schemes.
- Improve HSG/Red Book support.
- Improve MSCDEX.
- Improve dynamic core support under intel macs.
- Add basic support for clipper programs.
- Add support for different keyboard layouts.
- Add auto core guessing.
- Fix a few flags bugs.
- Fix a few small cpu bugs.
- Improve soundblaster detection rate by various programs.
- Improve EMS emulation. (allow mapping of non standard regions)
- Improve keyboard input codes on various OS-es.
- Fix problems with filenames having stackdata in them.
- Changed a few basic operations in DOSBox so they take emulated time.
- Improve dos ioctl functions.
- Extend cpu core so they are capable of detecting and raising a few
more exception types.
- Improve DOS functions when dealing with virtual drive.
- Improve FAT drives.
- Better handling of volume-labels in file functions.
- Image disk cycling capability. (prompt)
- Try to reduce the impact of using an analog joystick.
- Several measures to avoid code invalidation on certain types
of self modification in the dynamic core.
- Add dynamic core memory function inlining.
- A few small mouse improvements. (some games are using things they
shouldn't)
- Add nullmodem emulation.(h-a-l-9000)
- Some small cga and hercules fixes.
- Add more scalers (hq2x/hq3x/sai). (Kronuz)
- Change configuration file loading support. It now supports
multiple configuration files.
- Make dynamic core capable of running some win32s programs.
- Fix and add some rare soundblaster modes. (Srecko)
- Better soundblaster mixer controls. (Srecko)
- Make soundblaster installation under windows much easier.
- Add device control channel handling.
- GEMMIS support (ems under windows).
- Support more colours in win 3. (vasyl)
- Don't show unmounted drives in windows filemanager.
- Fix some bugs in the int13 handler.
- Simulate some side-effects of bios interrupt handlers on flags.
- Add IPX functions needed by netbios.
- Make ports take emulated time.
- Tabcompletion is now aware of the CD command.
- Add suppport for the dac pel mask.
- Fixes to hercules emulation, better detection and bank switching.
- Fixes to tandy emulation, 640x200x16 mode and different sizes bank.
- EGA/VGA memory changes detection for faster rendering.
- Gus 16 bit fixes.
- Many timer improvements.
- Some pcjr fixes.
- Some booter fixes.
- Many small fixes.
0.65
- Fixed FAT writing.
- Added some more missing DOS functions.
- Improved PIC so that it actually honours irq 2/9.
- Improved intelligent MPU-401 mode so that more games work with it.
- Some mouse fixes.
- Changed DMA transfers a bit so they bypass the paging tables.
- Added S3 XGA functionality.
- Improved paging so that read and write faults are handled differently.
- Rewrote exception handling a bit (no exception 0x0B with dos4gw anymore).
- Added IO exceptions in all but the dynamic core.
- Some ems improvements.
- Added midi-device selection code for the windows hosts.
- Fix crashes/segfaults related to the disabling of the pcspeaker.
- Added some more FILES=XX detection tricks.
- Fixed some vga detection schemes.
- Fixed screenshot corruption when using -noconsole in a read-only directory.
- Fix wrong scaled screenshots.
- Added some hidden file functions when using diskimages. (helps with cdrom
detection schemes)
- Fixed a bug in the mixer code, that muted the music in certain games.
- Added an assembly fpu core.
- Made the shell more flexible for batch files.
- Check for unaligned memory acces fixes hangups on ARM processors.
- Some 64 bit fixes.
- Added code to change configuration at runtime.
- Improved ADPCM emulation.
- Fixed a few cpu instructions.
- Always report vesa 2.0 and fix some colour issues with vesa games.
- Fix video mode 0x06 and 0x0a.
- Improvements to the joystick emulation. 4 buttons are supported as well.
- Add VCPI emulation for Origin games.
- Fixed a lot of things in the boot code. Most booters work now.
- Lots of improvements to the IPX emulation.
- Rewritten modem emulation. Should work with more games.
- Improvements to the dos memory managment routines.
- Add UMB (upper memory blocks) support.
- Emulate the pause key.
- Improve Composite CGA mode emulation.
- Lots of vga compatibility changes.
- Improved support for chained video modes.
- Improved mode and palette handling in cga modes.
- Mount accepts ~ now.
- Added a few of the EGA RIL functions.
- Added TandyDAC emulation.
- OS/2 support.
- Improved and speed up the dynamic cpu core.
- Fix some errors in the CD-ROM emulation layer.
- Added an automatic work-around for some graphics chipsets.
- Add PCjr support.
- Allow mousedriver to be replaced. Fixes a few games that come with their
own (internal) driver.
- Improved dynamic cpu core so it can handle pagefaults and some obscure
types of self-modifying code.
- Added -noautoexec switch to skip the contents of [autoexec] in the
configuration file.
- Improved v86 mode emulation (mainly for Strike Commander).
- Improved timer behavior.
- Improved extended keyboard support.
- Enhanced and added several DOS tables.
- Made core_full endian safe.
- Made pagefaults endian safe.
- Add support for moviecapturing
- Add support for 15/16/32 bit videomodes.
- Add some more VESA modi (4 bit).
- Add 1024x768 output.
- Changed screenrendering so it only draws changes to the screen.
- Allow remapping of the EMS page when the dma transfer was started from
the page frame
- Made EMS and DMA work together when playing from a mapped memory page.
- Renamed several configuration options, so that they are unique.
- Merged mpu and intelligent into one option.
- Merged fullfixed and fullresolution.
- Extended keys should be handled better.
- F11 and F12 work.
- Compilation fixes for various platforms.
- Fix a few crashes when giving bad input.
- Removed interp2x and added few new scalers.
- Reintroduce the lockfree mouse. (autolock=false)
- Add a larger cache for the dynamic cpu core.
- Improved soundblaster DSP, so it gets detected by creative tools.
- Lots of bugfixes.
- Even more bugfixes.
0.63
- Fixed crash with keymapper (ctrl-f1) and output=surface.
- Added unmounting.
- Fixed multiple issues with drive labels.
- Fixed most if not all FILES=XX problems.
- Added redirection in the shell.
- Fixed crashes with subst.
- Fixed multiple crashes with the drive images support.
- Added a missing fpu instruction.
- Fixed some cpu and fpu instructions.
- Fixed a small bug related to font loading.
- Rewrote the devices support.
- Added capslock/numlock checks on startup.
- Fixed wave writing.
- A few internal DOS fixes.
- Timer fixes for the hybrid loader.
- Some small soundblaster fixes.
- The drive cache can now be cleared by a keycombo. (CTRL-F4)
- A few keyboard fixes.
- Compilation fixes on various platforms.
- Quite some debugger improvements.
- Fixed dir only showing files after the first run on cdrom drives.
- Added some cdrom detection checks.
- Enabled insert in the shell. (Easier editing of commands)
- Changed order in which executables appear with tab-completion.
- Fixed some issues with raw opl recording and using a slightly different
format
0.62
- Added blinking support in the shell and some color fixes.
- Fixed commandline parsing when .bat files involved (fixes -exit)
- Fixed issues with tabs in commandline not being processed correctly.
- Cleaned/improved shutdown sequence.
- Added some more bios functions (wait and delay functions).
- Made our XMS driver conform the specs better. (c2woody)
- Added support for some more ems functions.
- Added intelligent mpu401 emulation. (Srecko)
- Added soundblaster 16 emulation.
- Rewrote GUS emulation to sound more authentic.
- Improved pc speaker emulation.
- Added an internal (programmable) mixer.
- Added support a few soundblaster/adlib detection routines.
- Fixed lot's of bugs related to DMA transfers.
- Added interpolating prebuffering mixer routines.
- Added recording of OPL commands and raw midi.
- Fixed some bugs with the wave recording.
- Changed sensitivity settings of the mouse.
- Added ps2 mouse-emulation in bios interrupts (c2woody).
- Fixed some bugs with mouse emulation limits.
- Fixed a bug with an unterminated string in the drivelabel.
- Changed file search routines a bit to be more compatible.
- Added support for attribute-searching with fcb's.
- Added basic SDA.
- Added TPA and DIB.
- Added Lot's of missing dos tables (c2woody).
- Changed psp and dta functions to use dta.
- Returned filename in ds:dx in create-random-file (c2woody).
- Fixed a bug with date and time used on open files.
- Some mscdex fixes.
- Added the -version switch, which makes dosbox report its version.
- Added a keymapper.
- Added basic IPX emulation.
- Added cdrom iso support and floppy images support.
- Added the possibity to boot another dos version.
- Added Serial passthrough support (win32 only).
- Added the possibility to pause dosbox.
- Changed OpenGL so that it is initialized only when used.
- Make dosbox run at higher priority when active and lower when inactive.
- Added direct draw output support (win32 only).
- Added current running program to title bar.
- Rewrote video emulation to support new scalers.
- Added new graphics scalers like advmame3x,tv2x.
- Added a support for a few anti-debugger tricks.
- Improved the handling of the tab-key.
- Improved support for the numeric keyboard.
- Fixed a few cpu opcodes.
- Added cpu core simple (for lowerend machines)
- Fixed some nasty bugs in the dynamic cpu core.
- Added a few (rarely used) fpu opcodes.
- Fixed various issues with GCC 3.4.
- Many internal timer improvements (PIT and PIC).
- Added some more PIC commands (c2woody).
- Added BCD counting to the timers.
- Fix some vesa functions.
- Add some basic support for 132x25 and 132x45 textmodes.
- Improved Tandy emulation a lot.
- Lowered cpu usage when dosbox is idle.
- Allow virtualisation of some basic IO-ports (c2woody).
0.61
- Added a beta dynamic cpu for x86 hosts (very unstable)
- Added opengl and hardware overlay display output
- Rewrote the vga screen updates to go in lines
- Added paging and v86 support to cpu emulation
- Added a config option to simulate a certain type of machine
- Added hercules graphics emulation
- Made CGA/TANDY modes more compatible
- Updated textmode drawing routines to support blinking colors
- Fixed VESA set page function that was documented wrong
- Fixed some wrongly emulated cpu opcodes.
- improved exception handling
- debugger: fixes; logging of gdt,lgt,idt, new commands(Fizzban)
- fixed some mscdex issues (drive letter header error, added get directory entry)
- added/fixed some bios funcs
- added some rarely used xms functions (thanks c2woody!)
- implemented GUS emulation
- Added 16-bit DMA support (for GUS and eventually SB16)
- Fixed many small bugs in filehandling routines
- Many small FPU fixes (c2woody/Fizzban)
- Some keyboard improvements (pharlab games)
- Some Timer and cmos/rtc fixes (Mirek/Srecko/Others)
- Lot's of mouse fixes (Help from various people)
- Enabled internal modem
- Made the DOS parsing routines a bit more flexible
- Added Subst (Srecko)
- Added cdrom ioctl support for linux (prompt)
- Many internal DOS fixes: memory/files/datastructures.
- Got some help from c2woody in allowing more than 1 irq being served
- Disabled DPMI (not needed anymore. DOSBox handles almost every extender)
- Search configfile in $HOME directory if none present in current directory
- Added another way to switch to protected mode. (Thanks Morten Eriksen!)
- Fixed some odd badly documented behaviour with PSP/DTA
- Added some warnings on opening of readonly files in writemode(DOS default).
- Many shell enhanchements
- Fixed a win32 specific bug dealing with filenames starting with a "."
- Fixed some bugs with the directory structure: not found/can't save errors
0.60
- rewrote memory system for future paging support
- fixed several EMS and XMS bugs and rewrite for new memory system
- added some support for tandy video modes
- added MAME Tandy 3 voice emulation
- added MAME CMS/GameBlaster emulation
- added serial port emulation with virtual tcp/ip modem (somewhat buggy)
- sound blaster emulation is now sb pro 2.0 compatible
- added basic support for 32-bit protected mode
- VGA now tries to emulate an S3 Trio 64 card with 2 MB
- VESA 2.0 support for some 256 color modes
- rewrote large piece of video bios code for better compatibility
- added support for the not inheritance flags.
- created functions for creating child psp.
- updated errorcodes of findfirst (thanks Mirek!)
- rewrote loggingsystem to generate less warnings
- added dos protected mode interface (dpmi)
- added cdrom label support
- improved cdrom audio playing
- fixed and improved directory cache
- debugger shows selector- and cpu mode info
- added SELINFO (selector information) command to debugger
- added reference counting for dos files
- added tab-completion
- added basic fpu support.
- fixed several bugs with case sensitive filesystems.
- added more shell commands and improved their behaviour.
- mouse improvements.
- real time clock improvements.
- DMA fixes.
- Improved .BAT file support.
0.58
- fixed date and time issues with fcbs
- added more commands to the internal Shell
- corrected config system when a old configfile was used
- fixed cga put and get pixel
- fixed some vga register getting reset to wrong values
- improved support for foreign keyboards
- improved joystick support
- made dosbox multithreaded again
- lot's of soundblaster fixes
- dma fixes
- cdrom support
- midi support
- added scale2x
- reenabled screenshot support
- joystick support fixes
- mouse improvements
- support for writing wavefiles
- added directory cache and longfilename support (longfilenames will be mangled)
- mouse fixes
0.57
- added support for command /C
- fixed all fcb-write functions
- fixed fcb-parseline
- added debugger under linux/freebsd
- added debugger memory breakpoints and autolog function (heavy debug)
- added loadfix.com program that eats up memory (default 64kb)
Usage : loadfix [-option] [programname] [parameters]...
Example: loadfix mm2 (Allocates 64kb and starts executable mm2)
loadfix -32 mm2 (Allocates 32kb and starts executable mm2)
loadfix -128 (Allocates 128kb)
loadfix -f (frees all previous allocated memory)
- added echoing of characters for input function
- added support for backspace for input function
- added partial support for int10:01 set cursortype
- fixed most of the problems/bugs with character input.
- fixed allocationinfo call.(darksun series)
- improved dos support for non-existant functions
- Split screen support
- prefix 66 67 support
- rewrote timingscheme so 1000 hz timers don't cause problems anymore
- update adlib emulation
- fixed some isues with the mouse (double clicks and visible when it shouldn't be)
- improved mouse behaviour (mickey/pixel rate) and detection routines.
- basic ansi.sys support
- Disney sound system emulation
- rewrote upcase/lowcase functions so they work fine with gcc3.2
- SHELL: added rename and delete
- added support for command /C. Fixed crashes in the shell
- fixed various bugs when exiting dosbox
- fixed a bug in XMS
- fixed a bug with the joystick when pressing a button
- create nicer configfiles.
- bios_disk function improved.
- trapflag support
- improved vertical retrace timing.
- PIT Timer improvements and many bug fixes
- Many many bug fixes to the DOS subsystem
- Support for memory allocation strategy
- rewrote cpu mainloop to act more like a real cpu
0.56
- added support for a configclass/configfile
- added support for writing out the configclass into a configfile
- removed the language file and made it internal
- added support for writing the language file (will override the internal one)
- improved mousesupport
- updated readme
- support for screenshots
- some cpu-bug fixes
- dma changes
- Real Sound support
- EMM fixes and new functions.
- VGA fixes
- new wildcompare
- support for size and disktype at mount.
- added new debugger functionalities: start/trace into INTs, write processor status log,
step over rep and loop instructions, breakpoint support without using INT 03 (heavy debugging switch)
- Added more cpu instructions and changed the string operations.
- Added classes for most of the internal dos structures.
- Rewrote most of the fcb calls to use normal dos calls.
0.55
- fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned).
- fixed compilation error on FreeBSD when #disable_joystick was defined
- int10_writechar has been updated to move the cursor position.
- changed the basedir routines to use the current working dir instead of argv[0]. This will fix and brake things :)
- illegal command, now displays the command
- wildcmp updated to be case insensitive
- added fcb:open,close,findfirst, findnext.
- fixed rename in drive_local
- added new features to the debugger: breakpoint support / data view / command line
- partial support of list of lists (dos info block)
- full emm 3.2 support
- partial emm 4.0 support
- fixes to graphics core fonts (text in sierra games is now correct)
- improved support for user mousehandlers
- fixed EGA graphics
- fixed VGA graphics
- fixed write with size 0
- changed memory management.
- fixed and cleaned up the cpu flags.
- changed interrupt handler.
- speeded up the graphics.
- speeded up the cpu-core
- changed dma
- improved dma streams from emm memory
- added some cga videomodes
- added more funtions to the keyboard handler
0.50:
-added F3 to repeat the last typed command.
-made it possible to change the shellmessages(dosshell). so
you can costumize it.(dosbox.lang)
-changed cpu core.
-Fixed a lot of errors with the keyboard: shift-f1 and
alt-f1 now works.
-Fixed some division errors.
-made a plugin system.
-added a lot of real 386 mode instructions.
-made it possible to resize the screen.
-Mayor source cleanup/reorganisation.
-Complete rewrite of the graphics routines. Should make it
possible to implement more fancy things like 2xsai,interpolation.
-changed the sound playback.
-Changed the vga drawing to only draw on memory changes, instead
of drawing an entire frame.
-fixes to the soundblaster/dma code should be able to play 4-bit
adpcm compressed sounds.
-added the correct time to dir.
-bugfixes to batch-file handling.
-Lot's of small bugfixes.(Dune1&2,wolf3d, many more).
-Released the source.
0.50:
-added F3 to repeat the last typed command.
-made it possible to change the shellmessages(dosshell). so
you can costumize it.(dosbox.lang)
-changed cpu core.
-Fixed a lot of errors with the keyboard: shift-f1 and
alt-f1 now works.
-Fixed some division errors.
-made a plugin system.
-added a lot of real 386 mode instructions.
-made it possible to resize the screen.
-Mayor source cleanup/reorganisation.
-Complete rewrite of the graphics routines. Should make it
possible to implement more fancy things like 2xsai,interpolation.
-changed the sound playback.
-Changed the vga drawing to only draw on memory changes, instead
of drawing an entire frame.
-fixes to the soundblaster/dma code should be able to play 4-bit
adpcm compressed sounds.
-added the correct time to dir.
-bugfixes to batch-file handling.
-Lot's of small bugfixes.(Dune1&2,wolf3d, many more).
-Released the source.

1327
README

File diff suppressed because it is too large Load Diff

34
THANKS
View File

@ -1,26 +1,8 @@
We would like to thank:
Vlad R. of the vdmsound project for excellent sound blaster info.
Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator.
Jarek Burczynski for the new OPL emulator.
The Bochs and DOSemu projects which I used for information.
Freedos for ideas in making my shell.
Pierre-Yves Gérardy for hosting the old Beta Board.
Colin Snover for hosting our forum.
Sourceforge for hosting our homepage and other development tools.
Mirek Luza, for his moderation of the forums.
eL_Pusher, DosFreak and MiniMax for their moderation of VOGONS forum.
crazyc and gulikoza for their work on the dynrec core.
Jantien for the version management.
Shawn, Johannes and Marcus for creating the MAC OS X version.
Jochen for creating the OS/2 version.
Ido Beeri for the icon.
All the people who submitted a bug.
The Beta Testers.
We would like to thank:
Vlad R. of the vdmsound project for excellent sound blaster info.
Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator.
The Bochs and DOSemu projects which I used for information.
Freedos for ideas in making my shell.
All the people who submitted a bug.

View File

@ -1 +0,0 @@
0.72

View File

@ -1,396 +1,161 @@
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
dnl
AC_DEFUN([AM_PATH_SDL],
[dnl
dnl Get the cflags and libraries from the sdl-config script
dnl
AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)],
sdl_prefix="$withval", sdl_prefix="")
AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
sdl_exec_prefix="$withval", sdl_exec_prefix="")
AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program],
, enable_sdltest=yes)
if test x$sdl_exec_prefix != x ; then
sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix"
if test x${SDL_CONFIG+set} != xset ; then
SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config
fi
fi
if test x$sdl_prefix != x ; then
sdl_args="$sdl_args --prefix=$sdl_prefix"
if test x${SDL_CONFIG+set} != xset ; then
SDL_CONFIG=$sdl_prefix/bin/sdl-config
fi
fi
AC_PATH_PROG(SDL_CONFIG, sdl-config, no)
min_sdl_version=ifelse([$1], ,0.11.0,$1)
AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
no_sdl=""
if test "$SDL_CONFIG" = "no" ; then
no_sdl=yes
else
SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags`
SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs`
sdl_major_version=`$SDL_CONFIG $sdl_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_sdltest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $SDL_CFLAGS"
LIBS="$LIBS $SDL_LIBS"
dnl
dnl Now check if the installed SDL is sufficiently new. (Also sanity
dnl checks the results of sdl-config to some extent
dnl
rm -f conf.sdltest
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
char*
my_strdup (char *str)
{
char *new_str;
if (str)
{
new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
strcpy (new_str, str);
}
else
new_str = NULL;
return new_str;
}
int main (int argc, char *argv[])
{
int major, minor, micro;
char *tmp_version;
/* This hangs on some systems (?)
system ("touch conf.sdltest");
*/
{ FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); }
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = my_strdup("$min_sdl_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_sdl_version");
exit(1);
}
if (($sdl_major_version > major) ||
(($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
(($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro);
printf("*** best to upgrade to the required version.\n");
printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n");
printf("*** to point to the correct copy of sdl-config, and remove the file\n");
printf("*** config.cache before re-running configure\n");
return 1;
}
}
],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_sdl" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
if test "$SDL_CONFIG" = "no" ; then
echo "*** The sdl-config script installed by SDL could not be found"
echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the SDL_CONFIG environment variable to the"
echo "*** full path to sdl-config."
else
if test -f conf.sdltest ; then
:
else
echo "*** Could not run SDL test program, checking why..."
CFLAGS="$CFLAGS $SDL_CFLAGS"
LIBS="$LIBS $SDL_LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include "SDL.h"
], [ return 0; ],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding SDL or finding the wrong"
echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means SDL was incorrectly installed"
echo "*** or that you have moved SDL since it was installed. In the latter case, you"
echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
SDL_CFLAGS=""
SDL_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(SDL_CFLAGS)
AC_SUBST(SDL_LIBS)
rm -f conf.sdltest
])
dnl Configure Paths for Alsa
dnl Some modifications by Richard Boulton <richard-alsa@tartarus.org>
dnl Christopher Lansdown <lansdoct@cs.alfred.edu>
dnl Jaroslav Kysela <perex@suse.cz>
dnl Last modification: alsa.m4,v 1.22 2002/05/27 11:14:20 tiwai Exp
dnl AM_PATH_ALSA([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for libasound, and define ALSA_CFLAGS and ALSA_LIBS as appropriate.
dnl enables arguments --with-alsa-prefix=
dnl --with-alsa-enc-prefix=
dnl --disable-alsatest (this has no effect, as yet)
dnl
dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified,
dnl and the alsa libraries are not found, a fatal AC_MSG_ERROR() will result.
dnl
AC_DEFUN([AM_PATH_ALSA],
[dnl Save the original CFLAGS, LDFLAGS, and LIBS
alsa_save_CFLAGS="$CFLAGS"
alsa_save_LDFLAGS="$LDFLAGS"
alsa_save_LIBS="$LIBS"
alsa_found=yes
dnl
dnl Get the cflags and libraries for alsa
dnl
AC_ARG_WITH(alsa-prefix,
[ --with-alsa-prefix=PFX Prefix where Alsa library is installed(optional)],
[alsa_prefix="$withval"], [alsa_prefix=""])
AC_ARG_WITH(alsa-inc-prefix,
[ --with-alsa-inc-prefix=PFX Prefix where include libraries are (optional)],
[alsa_inc_prefix="$withval"], [alsa_inc_prefix=""])
dnl FIXME: this is not yet implemented
AC_ARG_ENABLE(alsatest,
[ --disable-alsatest Do not try to compile and run a test Alsa program],
[enable_alsatest=no],
[enable_alsatest=yes])
dnl Add any special include directories
AC_MSG_CHECKING(for ALSA CFLAGS)
if test "$alsa_inc_prefix" != "" ; then
ALSA_CFLAGS="$ALSA_CFLAGS -I$alsa_inc_prefix"
CFLAGS="$CFLAGS -I$alsa_inc_prefix"
fi
AC_MSG_RESULT($ALSA_CFLAGS)
dnl add any special lib dirs
AC_MSG_CHECKING(for ALSA LDFLAGS)
if test "$alsa_prefix" != "" ; then
ALSA_LIBS="$ALSA_LIBS -L$alsa_prefix"
LDFLAGS="$LDFLAGS $ALSA_LIBS"
fi
dnl add the alsa library
ALSA_LIBS="$ALSA_LIBS -lasound -lm -ldl -lpthread"
LIBS=`echo $LIBS | sed 's/-lm//'`
LIBS=`echo $LIBS | sed 's/-ldl//'`
LIBS=`echo $LIBS | sed 's/-lpthread//'`
LIBS=`echo $LIBS | sed 's/ //'`
LIBS="$ALSA_LIBS $LIBS"
AC_MSG_RESULT($ALSA_LIBS)
dnl Check for a working version of libasound that is of the right version.
min_alsa_version=ifelse([$1], ,0.1.1,$1)
AC_MSG_CHECKING(for libasound headers version >= $min_alsa_version)
no_alsa=""
alsa_min_major_version=`echo $min_alsa_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
alsa_min_minor_version=`echo $min_alsa_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
alsa_min_micro_version=`echo $min_alsa_version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
AC_LANG_SAVE
AC_LANG_C
AC_TRY_COMPILE([
#include <alsa/asoundlib.h>
], [
/* ensure backward compatibility */
#if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR)
#define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR
#endif
#if !defined(SND_LIB_MINOR) && defined(SOUNDLIB_VERSION_MINOR)
#define SND_LIB_MINOR SOUNDLIB_VERSION_MINOR
#endif
#if !defined(SND_LIB_SUBMINOR) && defined(SOUNDLIB_VERSION_SUBMINOR)
#define SND_LIB_SUBMINOR SOUNDLIB_VERSION_SUBMINOR
#endif
# if(SND_LIB_MAJOR > $alsa_min_major_version)
exit(0);
# else
# if(SND_LIB_MAJOR < $alsa_min_major_version)
# error not present
# endif
# if(SND_LIB_MINOR > $alsa_min_minor_version)
exit(0);
# else
# if(SND_LIB_MINOR < $alsa_min_minor_version)
# error not present
# endif
# if(SND_LIB_SUBMINOR < $alsa_min_micro_version)
# error not present
# endif
# endif
# endif
exit(0);
],
[AC_MSG_RESULT(found.)],
[AC_MSG_RESULT(not present.)
ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)])
alsa_found=no]
)
AC_LANG_RESTORE
dnl Now that we know that we have the right version, let's see if we have the library and not just the headers.
AC_CHECK_LIB([asound], [snd_ctl_open],,
[ifelse([$3], , [AC_MSG_ERROR(No linkable libasound was found.)])
alsa_found=no]
)
if test "x$alsa_found" = "xyes" ; then
ifelse([$2], , :, [$2])
LIBS=`echo $LIBS | sed 's/-lasound//g'`
LIBS=`echo $LIBS | sed 's/ //'`
LIBS="-lasound $LIBS"
fi
if test "x$alsa_found" = "xno" ; then
ifelse([$3], , :, [$3])
CFLAGS="$alsa_save_CFLAGS"
LDFLAGS="$alsa_save_LDFLAGS"
LIBS="$alsa_save_LIBS"
ALSA_CFLAGS=""
ALSA_LIBS=""
fi
dnl That should be it. Now just export out symbols:
AC_SUBST(ALSA_CFLAGS)
AC_SUBST(ALSA_LIBS)
])
AH_TOP([
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
])
AH_BOTTOM([#if C_ATTRIBUTE_ALWAYS_INLINE
#define INLINE inline __attribute__((always_inline))
#else
#define INLINE inline
#endif])
AH_BOTTOM([#if C_ATTRIBUTE_FASTCALL
#define DB_FASTCALL __attribute__((fastcall))
#else
#define DB_FASTCALL
#endif])
AH_BOTTOM([#if C_HAS_ATTRIBUTE
#define GCC_ATTRIBUTE(x) __attribute__ ((x))
#else
#define GCC_ATTRIBUTE(x) /* attribute not supported */
#endif])
AH_BOTTOM([#if C_HAS_BUILTIN_EXPECT
#define GCC_UNLIKELY(x) __builtin_expect((x),0)
#else
#define GCC_UNLIKELY(x) (x)
#endif])
AH_BOTTOM([
typedef double Real64;
#if SIZEOF_UNSIGNED_CHAR != 1
# error "sizeof (unsigned char) != 1"
#else
typedef unsigned char Bit8u;
typedef signed char Bit8s;
#endif
#if SIZEOF_UNSIGNED_SHORT != 2
# error "sizeof (unsigned short) != 2"
#else
typedef unsigned short Bit16u;
typedef signed short Bit16s;
#endif
#if SIZEOF_UNSIGNED_INT == 4
typedef unsigned int Bit32u;
typedef signed int Bit32s;
#elif SIZEOF_UNSIGNED_LONG == 4
typedef unsigned long Bit32u;
typedef signed long Bit32s;
#else
# error "can't find sizeof(type) of 4 bytes!"
#endif
#if SIZEOF_UNSIGNED_LONG == 8
typedef unsigned long Bit64u;
typedef signed long Bit64s;
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
typedef unsigned long long Bit64u;
typedef signed long long Bit64s;
#else
# error "can't find data type of 8 bytes"
#endif
#if SIZEOF_INT_P == 4
typedef Bit32u Bitu;
typedef Bit32s Bits;
#else
typedef Bit64u Bitu;
typedef Bit64s Bits;
#endif
])
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
dnl
AC_DEFUN(AM_PATH_SDL,
[dnl
dnl Get the cflags and libraries from the sdl-config script
dnl
AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)],
sdl_prefix="$withval", sdl_prefix="")
AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
sdl_exec_prefix="$withval", sdl_exec_prefix="")
AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program],
, enable_sdltest=yes)
if test x$sdl_exec_prefix != x ; then
sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix"
if test x${SDL_CONFIG+set} != xset ; then
SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config
fi
fi
if test x$sdl_prefix != x ; then
sdl_args="$sdl_args --prefix=$sdl_prefix"
if test x${SDL_CONFIG+set} != xset ; then
SDL_CONFIG=$sdl_prefix/bin/sdl-config
fi
fi
AC_PATH_PROG(SDL_CONFIG, sdl-config, no)
min_sdl_version=ifelse([$1], ,0.11.0,$1)
AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
no_sdl=""
if test "$SDL_CONFIG" = "no" ; then
no_sdl=yes
else
SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags`
SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs`
sdl_major_version=`$SDL_CONFIG $sdl_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_sdltest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $SDL_CFLAGS"
LIBS="$LIBS $SDL_LIBS"
dnl
dnl Now check if the installed SDL is sufficiently new. (Also sanity
dnl checks the results of sdl-config to some extent
dnl
rm -f conf.sdltest
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
char*
my_strdup (char *str)
{
char *new_str;
if (str)
{
new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
strcpy (new_str, str);
}
else
new_str = NULL;
return new_str;
}
int main (int argc, char *argv[])
{
int major, minor, micro;
char *tmp_version;
/* This hangs on some systems (?)
system ("touch conf.sdltest");
*/
{ FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); }
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = my_strdup("$min_sdl_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_sdl_version");
exit(1);
}
if (($sdl_major_version > major) ||
(($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
(($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro);
printf("*** best to upgrade to the required version.\n");
printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n");
printf("*** to point to the correct copy of sdl-config, and remove the file\n");
printf("*** config.cache before re-running configure\n");
return 1;
}
}
],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_sdl" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
if test "$SDL_CONFIG" = "no" ; then
echo "*** The sdl-config script installed by SDL could not be found"
echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the SDL_CONFIG environment variable to the"
echo "*** full path to sdl-config."
else
if test -f conf.sdltest ; then
:
else
echo "*** Could not run SDL test program, checking why..."
CFLAGS="$CFLAGS $SDL_CFLAGS"
LIBS="$LIBS $SDL_LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include "SDL.h"
], [ return 0; ],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding SDL or finding the wrong"
echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means SDL was incorrectly installed"
echo "*** or that you have moved SDL since it was installed. In the latter case, you"
echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
SDL_CFLAGS=""
SDL_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(SDL_CFLAGS)
AC_SUBST(SDL_LIBS)
rm -f conf.sdltest
])

992
aclocal.m4 vendored Normal file
View File

@ -0,0 +1,992 @@
# aclocal.m4 generated automatically by aclocal 1.6.1 -*- Autoconf -*-
# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
dnl
AC_DEFUN(AM_PATH_SDL,
[dnl
dnl Get the cflags and libraries from the sdl-config script
dnl
AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)],
sdl_prefix="$withval", sdl_prefix="")
AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
sdl_exec_prefix="$withval", sdl_exec_prefix="")
AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program],
, enable_sdltest=yes)
if test x$sdl_exec_prefix != x ; then
sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix"
if test x${SDL_CONFIG+set} != xset ; then
SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config
fi
fi
if test x$sdl_prefix != x ; then
sdl_args="$sdl_args --prefix=$sdl_prefix"
if test x${SDL_CONFIG+set} != xset ; then
SDL_CONFIG=$sdl_prefix/bin/sdl-config
fi
fi
AC_PATH_PROG(SDL_CONFIG, sdl-config, no)
min_sdl_version=ifelse([$1], ,0.11.0,$1)
AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
no_sdl=""
if test "$SDL_CONFIG" = "no" ; then
no_sdl=yes
else
SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags`
SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs`
sdl_major_version=`$SDL_CONFIG $sdl_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_sdltest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $SDL_CFLAGS"
LIBS="$LIBS $SDL_LIBS"
dnl
dnl Now check if the installed SDL is sufficiently new. (Also sanity
dnl checks the results of sdl-config to some extent
dnl
rm -f conf.sdltest
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
char*
my_strdup (char *str)
{
char *new_str;
if (str)
{
new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
strcpy (new_str, str);
}
else
new_str = NULL;
return new_str;
}
int main (int argc, char *argv[])
{
int major, minor, micro;
char *tmp_version;
/* This hangs on some systems (?)
system ("touch conf.sdltest");
*/
{ FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); }
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = my_strdup("$min_sdl_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_sdl_version");
exit(1);
}
if (($sdl_major_version > major) ||
(($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
(($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro);
printf("*** best to upgrade to the required version.\n");
printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n");
printf("*** to point to the correct copy of sdl-config, and remove the file\n");
printf("*** config.cache before re-running configure\n");
return 1;
}
}
],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_sdl" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
if test "$SDL_CONFIG" = "no" ; then
echo "*** The sdl-config script installed by SDL could not be found"
echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the SDL_CONFIG environment variable to the"
echo "*** full path to sdl-config."
else
if test -f conf.sdltest ; then
:
else
echo "*** Could not run SDL test program, checking why..."
CFLAGS="$CFLAGS $SDL_CFLAGS"
LIBS="$LIBS $SDL_LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include "SDL.h"
], [ return 0; ],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding SDL or finding the wrong"
echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means SDL was incorrectly installed"
echo "*** or that you have moved SDL since it was installed. In the latter case, you"
echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
SDL_CFLAGS=""
SDL_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(SDL_CFLAGS)
AC_SUBST(SDL_LIBS)
rm -f conf.sdltest
])
# Do all the work for Automake. -*- Autoconf -*-
# This macro actually does too much some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 8
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
AC_PREREQ([2.52])
# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
# the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
# test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
AC_SUBST([PACKAGE], [AC_PACKAGE_TARNAME])dnl
AC_SUBST([VERSION], [AC_PACKAGE_VERSION])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AM_MISSING_PROG(AMTAR, tar)
AM_PROG_INSTALL_SH
AM_PROG_INSTALL_STRIP
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_][CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_][CC],
defn([AC_PROG_][CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_][CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_][CXX],
defn([AC_PROG_][CXX])[_AM_DEPENDENCIES(CXX)])])dnl
])
])
# Copyright 2002 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.6"])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.6.1])])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright 2001, 2002 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 2
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
#
# Check to make sure that the build environment is sane.
#
# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 3
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# -*- Autoconf -*-
# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 3
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# AM_AUX_DIR_EXPAND
# Copyright 2001 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
# Rely on autoconf to set up CDPATH properly.
AC_PREREQ([2.50])
AC_DEFUN([AM_AUX_DIR_EXPAND], [
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
# Copyright 2001 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# AM_PROG_INSTALL_STRIP
# Copyright 2001 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# serial 4 -*- Autoconf -*-
# Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc']
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
for depmode in $am_compiler_list; do
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
echo '#include "conftest.h"' > conftest.c
echo 'int i;' > conftest.h
echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
none) break ;;
esac
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
source=conftest.c object=conftest.o \
depfile=conftest.Po tmpdepfile=conftest.TPo \
$SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
grep conftest.h conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[rm -f .deps 2>/dev/null
mkdir .deps 2>/dev/null
if test -d .deps; then
DEPDIR=.deps
else
# MS-DOS does not allow filenames that begin with a dot.
DEPDIR=_deps
fi
rmdir .deps 2>/dev/null
AC_SUBST([DEPDIR])
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking Speeds up one-time builds
--enable-dependency-tracking Do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#serial 2
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
if (sed 1q $mf | fgrep 'generated by automake') > /dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
# Extract the definition of DEP_FILES from the Makefile without
# running `make'.
DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
test -z "$DEPDIR" && continue
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n -e '/^U = / s///p' < "$mf"`
test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
# We invoke sed twice because it is the simplest approach to
# changing $(DEPDIR) to its actual value in the expansion.
for file in `sed -n -e '
/^DEP_FILES = .*\\\\$/ {
s/^DEP_FILES = //
:loop
s/\\\\$//
p
n
/\\\\$/ b loop
p
}
/^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Copyright 2001 Free Software Foundation, Inc. -*- Autoconf -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 2
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
doit:
@echo done
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# We grep out `Entering directory' and `Leaving directory'
# messages which can occur if `w' ends up in MAKEFLAGS.
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
fi
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
am__include=.include
am__quote="\""
_am_result=BSD
fi
fi
AC_SUBST(am__include)
AC_SUBST(am__quote)
AC_MSG_RESULT($_am_result)
rm -f confinc confmf
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 5
AC_PREREQ(2.52)
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])
AC_SUBST([$1_FALSE])
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([conditional \"$1\" was never defined.
Usually this means the macro was only invoked conditionally.])
fi])])
# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
AC_PREREQ([2.52])
# serial 6
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. We must strip everything past the first ":",
# and everything past the last "/".
# _AM_DIRNAME(PATH)
# -----------------
# Like AS_DIRNAME, only do it during macro expansion
AC_DEFUN([_AM_DIRNAME],
[m4_if(regexp([$1], [^.*[^/]//*[^/][^/]*/*$]), -1,
m4_if(regexp([$1], [^//\([^/]\|$\)]), -1,
m4_if(regexp([$1], [^/.*]), -1,
[.],
patsubst([$1], [^\(/\).*], [\1])),
patsubst([$1], [^\(//\)\([^/].*\|$\)], [\1])),
patsubst([$1], [^\(.*[^/]\)//*[^/][^/]*/*$], [\1]))[]dnl
])# _AM_DIRNAME
# The stamp files are numbered to have different names.
# We could number them on a directory basis, but that's additional
# complications, let's have a unique counter.
m4_define([_AM_STAMP_Count], [0])
# _AM_STAMP(HEADER)
# -----------------
# The name of the stamp file for HEADER.
AC_DEFUN([_AM_STAMP],
[m4_define([_AM_STAMP_Count], m4_incr(_AM_STAMP_Count))dnl
AS_ESCAPE(_AM_DIRNAME(patsubst([$1],
[:.*])))/stamp-h[]_AM_STAMP_Count])
# _AM_CONFIG_HEADER(HEADER[:SOURCES], COMMANDS, INIT-COMMANDS)
# ------------------------------------------------------------
# We used to try to get a real timestamp in stamp-h. But the fear is that
# that will cause unnecessary cvs conflicts.
AC_DEFUN([_AM_CONFIG_HEADER],
[# Add the stamp file to the list of files AC keeps track of,
# along with our hook.
AC_CONFIG_HEADERS([$1],
[# update the timestamp
echo 'timestamp for $1' >"_AM_STAMP([$1])"
$2],
[$3])
])# _AM_CONFIG_HEADER
# AM_CONFIG_HEADER(HEADER[:SOURCES]..., COMMANDS, INIT-COMMANDS)
# --------------------------------------------------------------
AC_DEFUN([AM_CONFIG_HEADER],
[AC_FOREACH([_AM_File], [$1], [_AM_CONFIG_HEADER(_AM_File, [$2], [$3])])
])# AM_CONFIG_HEADER

View File

@ -1,14 +1,18 @@
#!/bin/sh
echo "Generating build information using aclocal, autoheader, automake and autoconf"
echo "This may take a while ..."
# Regenerate configuration files.
aclocal
autoheader
automake --include-deps --add-missing --copy
autoconf
echo "Now you are ready to run ./configure."
echo "You can also run ./configure --help for extra features to enable/disable."
#!/bin/sh
#
echo "Generating build information using aclocal, auotheader, automake and autoconf"
echo "This may take a while ..."
# Touch the timestamps on all the files since CVS messes them up
directory=`dirname $0`
touch $directory/configure.in
# Regenerate configuration files
aclocal
autoheader
automake --gnits --include-deps --add-missing --copy
autoconf
cp $directory/settings.h.cvs $directory/settings.h
echo "Now you are ready to run ./configure also check settings.h for extra build settings"

1368
config.guess vendored Normal file

File diff suppressed because it is too large Load Diff

65
config.h.in Normal file
View File

@ -0,0 +1,65 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Version number of package */
#undef VERSION
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
#undef inline
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t

1443
config.sub vendored Normal file

File diff suppressed because it is too large Load Diff

5512
configure vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,519 +1,61 @@
dnl Init.
AC_INIT(dosbox,0.72)
AC_PREREQ(2.50)
AC_CONFIG_SRCDIR(README)
dnl Detect the canonical host and target build environment
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
dnl Setup for automake
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
dnl Checks for programs.
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_RANLIB
dnl Some needed libaries for OS2
dnl perharps join this with the other target depended checks. move them upwards
if test x$target = xi386-pc-os2-emx ; then
CXXFLAGS="$CXXFLAGS -Zmt"
LDFLAGS="$LDFLAGS -Zomf -Zmt"
LIBS="$LIBS -los2me"
fi
dnl Check for SDL
SDL_VERSION=1.2.0
AM_PATH_SDL($SDL_VERSION,
:,
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
)
LIBS="$LIBS $SDL_LIBS"
CPPFLAGS="$CPPFLAGS $SDL_CFLAGS"
dnl Check if SDL is 1.2.x (1.3 not supported)
AC_MSG_CHECKING([SDL version only being 1.2.X])
AC_COMPILE_IFELSE([
#include "SDL.h"
void blah(){
#if SDL_MINOR_VERSION != 2
#error "Only SDL 1.2 supported"
#endif
;
}
],AC_MSG_RESULT([yes]),[
AC_MSG_RESULT([no])
AC_MSG_ERROR([Only libSDL 1.2.X supported])])
dnl Checks for header files.
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_STRUCT_TM
AC_CHECK_SIZEOF(unsigned char)
AC_CHECK_SIZEOF(unsigned short)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned long long)
AC_CHECK_SIZEOF(int *)
dnl some semi complex check for sys/socket so it works on darwin as well
AC_CHECK_HEADERS([stdlib.h sys/types.h])
AC_CHECK_HEADERS([sys/socket.h netinet/in.h pwd.h], [], [],
[#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
])
dnl check for the socklen_t (darwin doesn't always have it)
AC_COMPILE_IFELSE([
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
],[],[AC_DEFINE([socklen_t],[int],[Define to `int` if you don't have socklen_t])])
AC_MSG_CHECKING(if environ can be included)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <unistd.h>
#include <stdlib.h>]],[[*environ;]])],
[AC_MSG_RESULT(yes);AC_DEFINE(ENVIRON_INCLUDED,1,[environ can be included])],AC_MSG_RESULT(no))
AC_MSG_CHECKING(if environ can be linked)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char ** environ;]],[[*environ;]])],
[AC_MSG_RESULT(yes);AC_DEFINE(ENVIRON_LINKED,1,[environ can be linked])],AC_MSG_RESULT(no))
AC_MSG_CHECKING([if dirent includes d_type])
AC_COMPILE_IFELSE([
#include <sys/types.h>
#include <dirent.h>
void blah(){
struct dirent d_test;
d_test.d_type = 0;
}],[AC_MSG_RESULT(yes);AC_DEFINE(DIRENT_HAS_D_TYPE,1,[struct dirent has d_type])],AC_MSG_RESULT(no))
dnl Check for powf
if test x$target = xi386-pc-os2-emx ; then
AC_MSG_CHECKING(for powf in libm);
LIBS_BACKUP=$LIBS;
LIBS="$LIBS -lm";
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>]],[[
powf(1.0f, 1.0f);
]])], [AC_MSG_RESULT(yes)], [AC_DEFINE([DB_HAVE_NO_POWF],[1],[libm doesn't include powf])])
LIBS=$LIBS_BACKUP
else
AC_CHECK_LIB([m],[powf],,[AC_DEFINE([DB_HAVE_NO_POWF],[1],[libm doesn't include powf])])
fi
dnl Checks for libraries.
#Check if the compiler support attributes
AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures.])
AC_MSG_CHECKING(if compiler allows __attribute__)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
typedef struct { } __attribute__((packed)) junk;]],
[[ ]])],[ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no))
#Check if the compiler supports certain attributes
OLDCFLAGS="$CFLAGS"
CFLAGS="-Werror"
AH_TEMPLATE([C_ATTRIBUTE_ALWAYS_INLINE],[Determines if the compilers supports always_inline attribute.])
AC_MSG_CHECKING(if compiler allows __attribute__((always_inline)) )
AC_COMPILE_IFELSE([ void __attribute__((always_inline)) test(){}
],[ AC_MSG_RESULT(yes);AC_DEFINE(C_ATTRIBUTE_ALWAYS_INLINE)],AC_MSG_RESULT(no))
AH_TEMPLATE([C_ATTRIBUTE_FASTCALL],[Determines if the compilers supports fastcall attribute.])
AC_MSG_CHECKING(if compiler allows __attribute__((fastcall)) )
AC_COMPILE_IFELSE([ void __attribute__((fastcall)) test(){}
],[ AC_MSG_RESULT(yes);AC_DEFINE(C_ATTRIBUTE_FASTCALL)],AC_MSG_RESULT(no))
CFLAGS="$OLDCFLAGS"
#Check if the compiler supports __builtin_expect
#Switch language to c++
AC_LANG_PUSH(C++)
AH_TEMPLATE([C_HAS_BUILTIN_EXPECT],[Determines if the compilers supports __builtin_expect for branch prediction.])
AC_MSG_CHECKING(if compiler allows __builtin_expect)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[
int x=10;if( __builtin_expect ((x==1),0) ) ;
]])], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_BUILTIN_EXPECT)],AC_MSG_RESULT(no))
#switch language back
AC_LANG_POP(C++)
dnl enable disable alsa and pass it's cflags to CXXFLAGS
AC_ARG_ENABLE(alsa-midi,
AC_HELP_STRING([--enable-alsa-midi],[compile with alsa midi support (default yes)]),
[ case "${enableval}" in
yes) alsa_midi=true;;
no) alsa_midi=false;;
esac],
[alsa_midi=true])
if test x$alsa_midi = xtrue ; then
AM_PATH_ALSA(0.9.0, AC_DEFINE(HAVE_ALSA,1,[Define to 1 to use ALSA for MIDI]) , : )
CXXFLAGS="$CXXFLAGS $ALSA_CFLAGS"
fi
#Check for big endian machine, should #define WORDS_BIGENDIAN if so
AC_C_BIGENDIAN
#Features to enable/disable
AH_TEMPLATE(C_DEBUG,[Define to 1 to enable internal debugger, requires libcurses])
AH_TEMPLATE(C_HEAVY_DEBUG,[Define to 1 to enable heavy debugging, also have to enable C_DEBUG])
AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[
AC_CHECK_HEADER(curses.h,have_curses_h=yes,)
AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , )
AC_CHECK_LIB(ncurses, initscr, have_ncurses_lib=yes, , )
AC_CHECK_LIB(pdcurses, initscr, have_pdcurses_lib=yes, , )
if test x$enable_debug = xno; then
AC_MSG_RESULT([Debugger not enabled])
elif test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then
LIBS="$LIBS -lcurses"
AC_DEFINE(C_DEBUG,1)
if test x$enable_debug = xheavy ; then
AC_DEFINE(C_HEAVY_DEBUG,1)
fi
elif test x$have_ncurses_lib = xyes -a x$have_curses_h = xyes ; then
LIBS="$LIBS -lncurses"
AC_DEFINE(C_DEBUG,1)
if test x$enable_debug = xheavy ; then
AC_DEFINE(C_HEAVY_DEBUG,1)
fi
elif test x$have_pdcurses_lib = xyes -a x$have_curses_h = xyes ; then
LIBS="$LIBS -lpdcurses"
AC_DEFINE(C_DEBUG,1)
if test x$enable_debug = xheavy ; then
AC_DEFINE(C_HEAVY_DEBUG,1)
fi
else
AC_MSG_ERROR([Can't find curses, which is required for debug mode])
fi
],)
AH_TEMPLATE(C_CORE_INLINE,[Define to 1 to use inlined memory functions in cpu core])
AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined memory handling in CPU Core]),[
if test x$enable_core_inline = xyes ; then
AC_MSG_RESULT([enabling inlined memory handling in CPU Core])
AC_DEFINE(C_CORE_INLINE,1)
fi
],)
dnl The target cpu checks for dynamic cores
AH_TEMPLATE(C_TARGETCPU,[The type of cpu this target has])
AC_MSG_CHECKING(for target cpu type)
case "$target_cpu" in
x86_64 | amd64)
AC_DEFINE(C_TARGETCPU,X86_64)
AC_MSG_RESULT(x86-64 bit compatible)
c_targetcpu="x86_64"
c_unalignedmemory=yes
;;
i?86)
AC_DEFINE(C_TARGETCPU,X86)
AC_MSG_RESULT(x86 compatible)
c_targetcpu="x86"
c_unalignedmemory=yes
;;
powerpc*)
AC_DEFINE(C_TARGETCPU,POWERPC)
AC_MSG_RESULT(Power PC)
c_targetcpu="powerpc"
c_unalignedmemory=yes
;;
m68k*)
AC_DEFINE(C_TARGETCPU,M68K)
AC_MSG_RESULT(Motorola 68000)
c_targetcpu="m68k"
c_unalignedmemory=yes
;;
*)
AC_DEFINE(C_TARGETCPU,UNKNOWN)
AC_MSG_RESULT(unknown)
c_unalignedmemory=no
;;
esac
AC_ARG_ENABLE(dynamic-core,AC_HELP_STRING([--disable-dynamic-core],[Disable all dynamic cores]),,enable_dynamic_core=yes)
AH_TEMPLATE(C_DYNAMIC_X86,[Define to 1 to use x86 dynamic cpu core])
AC_ARG_ENABLE(dynamic-x86,AC_HELP_STRING([--disable-dynamic-x86],[Disable x86 dynamic cpu core]),,enable_dynamic_x86=yes)
AC_MSG_CHECKING(whether x86 dynamic cpu core will be enabled)
if test x$enable_dynamic_x86 = xno -o x$enable_dynamic_core = xno; then
AC_MSG_RESULT(no)
else
if test x$c_targetcpu = xx86 ; then
AC_DEFINE(C_DYNAMIC_X86,1)
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
AH_TEMPLATE(C_DYNREC,[Define to 1 to use recompiling cpu core. Can not be used together with the dynamic-x86 core])
AC_ARG_ENABLE(dynrec,AC_HELP_STRING([--disable-dynrec],[Disable recompiling cpu core]),,enable_dynrec=yes)
AC_MSG_CHECKING(whether recompiling cpu core will be enabled)
if test x$enable_dynrec = xno -o x$enable_dynamic_core = xno; then
AC_MSG_RESULT(no)
else
dnl x86 only enable it if dynamic-x86 is disabled.
if test x$c_targetcpu = xx86 ; then
if test x$enable_dynamic_x86 = xno ; then
AC_DEFINE(C_DYNREC,1)
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT([no, using dynamic-x86])
fi
else
if test x$c_targetcpu = xx86_64 ; then
AC_DEFINE(C_DYNREC,1)
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
fi
AH_TEMPLATE(C_FPU,[Define to 1 to enable floating point emulation])
AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable fpu support]),,enable_fpu=yes)
AC_MSG_CHECKING(whether fpu emulation will be enabled)
if test x$enable_fpu = xyes ; then
AC_MSG_RESULT(yes)
AC_DEFINE(C_FPU,1)
else
AC_MSG_RESULT(no)
fi
AH_TEMPLATE(C_FPU_X86,[Define to 1 to use a x86 assembly fpu core])
AC_ARG_ENABLE(fpu-x86,AC_HELP_STRING([--disable-fpu-x86],[Disable x86 assembly fpu core]),,enable_fpu_x86=yes)
AC_MSG_CHECKING(whether x86 assembly fpu core will be enabled)
if test x$enable_fpu_x86 = xno ; then
AC_MSG_RESULT(no)
else
if test x$enable_fpu = xyes; then
if test x$c_targetcpu = xx86 ; then
AC_DEFINE(C_FPU_X86,1)
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
else
AC_MSG_RESULT(no)
fi
fi
AH_TEMPLATE(C_UNALIGNED_MEMORY,[Define to 1 to use a unaligned memory access])
AC_ARG_ENABLE(unaligned_memory,AC_HELP_STRING([--disable-unaligned-memory],[Disable unaligned memory access]),,enable_unaligned_memory=yes)
AC_MSG_CHECKING(whether to enable unaligned memory access)
if test x$enable_unaligned_memory = xyes -a x$c_unalignedmemory = xyes; then
AC_DEFINE(C_UNALIGNED_MEMORY,1)
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng])
AC_CHECK_HEADER(png.h,have_png_h=yes,)
AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, ,-lz)
if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then
LIBS="$LIBS -lpng -lz"
AC_DEFINE(C_SSHOT,1)
else
AC_MSG_WARN([Can't find libpng, screenshot support disabled])
fi
AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_net])
AH_TEMPLATE(C_IPX,[Define to 1 to enable IPX over Internet networking, requires SDL_net])
AC_CHECK_HEADER(SDL_net.h,have_sdl_net_h=yes,)
if test x$target = xi386-pc-os2-emx ; then
AC_MSG_CHECKING(for SDLNet_Init in SDL_net);
LIBS_BACKUP=$LIBS;
LIBS="$LIBS -lSDL_Net";
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <SDL_Net.h>]],[[
SDLNet_Init ();
]])], [AC_MSG_RESULT(yes); have_sdl_net_lib=yes], AC_MSG_RESULT(no))
LIBS=$LIBS_BACKUP
else
AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , )
fi
if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then
LIBS="$LIBS -lSDL_net"
AC_DEFINE(C_MODEM,1)
AC_DEFINE(C_IPX,1)
else
AC_MSG_WARN([Can't find SDL_net, internal modem and ipx disabled])
fi
AH_TEMPLATE(C_OPENGL,[Define to 1 to use opengl display output support])
AC_CHECK_LIB(GL, main, have_gl_lib=yes, have_gl_lib=no , )
AC_CHECK_LIB(opengl32, main, have_opengl32_lib=yes,have_opengl32_lib=no , )
AC_CHECK_HEADER(GL/gl.h, have_gl_h=yes , have_gl_h=no , )
AC_ARG_ENABLE(opengl,AC_HELP_STRING([--disable-opengl],[Disable opengl support]),,enable_opengl=yes)
AC_MSG_CHECKING(whether opengl display output will be enabled)
if test x$enable_opengl = xyes; then
case "$target" in
*-*-darwin*)
AC_MSG_RESULT(yes)
LIBS="$LIBS -framework OpenGL"
AC_DEFINE(C_OPENGL,1)
;;
*)
if test x$have_gl_h = xyes -a x$have_gl_lib = xyes ; then
AC_MSG_RESULT(yes)
LIBS="$LIBS -lGL"
AC_DEFINE(C_OPENGL,1)
elif test x$have_gl_h = xyes -a x$have_opengl32_lib = xyes ; then
AC_MSG_RESULT(yes)
LIBS="$LIBS -lopengl32"
AC_DEFINE(C_OPENGL,1)
else
AC_MSG_RESULT(no)
fi
;;
esac
fi
AH_TEMPLATE(C_SDL_SOUND,[Define to 1 to enable SDL_sound support])
AC_CHECK_HEADER(SDL_sound.h,have_SDL_sound_h=yes,)
AC_CHECK_LIB(SDL_sound, Sound_Init, have_SDL_sound_init=yes,,)
AC_CHECK_LIB(SDL_sound, Sound_Seek, have_SDL_sound_seek=yes,,)
if test x$have_SDL_sound_h = xyes -a x$have_SDL_sound_init = xyes ; then
if test x$have_SDL_sound_seek = xyes ; then
LIBS="-lSDL_sound $LIBS"
AC_DEFINE(C_SDL_SOUND,1)
else
AC_MSG_WARN([Can't find SoundSeek in libSDL_Sound, libSDL_sound support disabled])
fi
else
AC_MSG_WARN([Can't find libSDL_sound, libSDL_sound support disabled])
fi
dnl Check for mprotect. Needed for 64 bits linux
AH_TEMPLATE(C_HAVE_MPROTECT,[Define to 1 if you have the mprotect function])
AC_CHECK_HEADER([sys/mman.h], [
AC_CHECK_FUNC([mprotect],[AC_DEFINE(C_HAVE_MPROTECT,1)])
])
dnl Setpriority
AH_TEMPLATE(C_SET_PRIORITY,[Define to 1 if you have setpriority support])
AC_MSG_CHECKING(for setpriority support)
AC_LINK_IFELSE([
#include <sys/resource.h>
int main(int argc,char * argv[]) {
return setpriority (PRIO_PROCESS, 0,PRIO_MIN+PRIO_MAX);
};
],AC_MSG_RESULT(yes);AC_DEFINE(C_SET_PRIORITY,1),AC_MSG_RESULT(no))
dnl Some target detection and actions for them
case "$target" in
*-*-cygwin* | *-*-mingw32*)
LIBS="$LIBS -lwinmm"
AC_CHECK_HEADERS(ddraw.h)
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2 only).])
if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then
LIBS="$LIBS -lws2_32"
fi
;;
*-*-darwin*)
dnl We have a problem here: both Mac OS X and Darwin report
dnl the same signature "powerpc-apple-darwin*" - so we have
dnl to do more to distinguish them.
dnl For now I am lazy and do not add proper detection code.
AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X])
LIBS="$LIBS -framework CoreMidi -framework AudioUnit -framework AudioToolbox"
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
;;
*-*-linux*)
AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux])
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
;;
*-*-freebsd* | *-*-dragonfly* | *-*-netbsd* | *-*-openbsd*)
dnl Disabled directserial for now. It doesn't do anything without
dnl specifying an extra ifdef in directserial_posix.*
dnl directserial detection should be rewritten to test for the needed
dnl functions and headers. I currently do not know
dnl which ones are needed for BSD
AC_DEFINE(BSD, 1, [Compiling on BSD])
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
;;
*-*-os2-emx*)
AC_DEFINE(OS2, 1, [Compiling on OS/2 EMX])
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
;;
esac
dnl Some stuff for the icon.
case "$target" in
*-*-cygwin* | *-*-mingw32*)
dnl Some stuff for the ico
AC_CHECK_TOOL(WINDRES, windres, :)
;;
*)
WINDRES=":"
;;
esac
AM_CONDITIONAL(HAVE_WINDRES, test "x$WINDRES" != "x:")
AC_SUBST(WINDRES)
AC_CONFIG_FILES([
Makefile
src/Makefile
src/cpu/Makefile
src/cpu/core_full/Makefile
src/cpu/core_normal/Makefile
src/cpu/core_dyn_x86/Makefile
src/cpu/core_dynrec/Makefile
src/debug/Makefile
src/dos/Makefile
src/fpu/Makefile
src/gui/Makefile
src/hardware/Makefile
src/hardware/serialport/Makefile
src/ints/Makefile
src/libs/Makefile
src/libs/zmbv/Makefile
src/libs/gui_tk/Makefile
src/misc/Makefile
src/shell/Makefile
src/platform/Makefile
src/platform/visualc/Makefile
visualc_net/Makefile
include/Makefile
docs/Makefile
])
AC_OUTPUT
dnl Init.
AC_INIT(dosbox,0.50)
AC_CONFIG_SRCDIR(README)
dnl Detect the canonical host and target build environment
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
dnl Setup for automake
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
dnl Checks for programs.
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_RANLIB
dnl Check for SDL
SDL_VERSION=1.2.0
AM_PATH_SDL($SDL_VERSION,
:,
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
)
LIBS="$LIBS $SDL_LIBS"
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
dnl Checks for header files.
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_STRUCT_TM
dnl Checks for library functions.
#Always include the standard include dir in all makefiless
AC_OUTPUT([
Makefile
src/Makefile
src/cpu/Makefile
src/cpu/core_16/Makefile
src/debug/Makefile
src/dos/Makefile
src/fpu/Makefile
src/gui/Makefile
src/hardware/Makefile
src/ints/Makefile
src/misc/Makefile
src/shell/Makefile
src/platform/Makefile
src/platform/visualc/Makefile
visualc/Makefile
include/Makefile
])

436
depcomp Normal file
View File

@ -0,0 +1,436 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
# Copyright 1999, 2000 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# `libtool' can also be set to `yes' or `no'.
if test -z "$depfile"; then
base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
dir=`echo "$object" | sed 's,/.*$,/,'`
if test "$dir" = "$object"; then
dir=
fi
# FIXME: should be _deps on DOS.
depfile="$dir.deps/$base"
fi
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. This file always lives in the current directory.
# Also, the AIX compiler puts `$object:' at the start of each line;
# $object doesn't have directory information.
stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
outname="$stripped.o"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
base=`echo "$object" | sed -e 's/\.o$//' -e 's/\.lo$//'`
tmpdepfile1="$base.o.d"
tmpdepfile2="$base.d"
if test "$libtool" = yes; then
"$@" -Wc,-MD
else
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
else
tmpdepfile="$tmpdepfile2"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a space and a tab in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
test -z "$dashmflag" && dashmflag=-M
( IFS=" "
case " $* " in
*" --mode=compile "*) # this is libtool, let us make it quiet
for arg
do # cycle over the arguments
case "$arg" in
"--mode=compile")
# insert --quiet before "--mode=compile"
set fnord "$@" --quiet
shift # fnord
;;
esac
set fnord "$@" "$arg"
shift # fnord
shift # "$arg"
done
;;
esac
"$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
) &
proc=$!
"$@"
stat=$?
wait "$proc"
if test "$stat" != 0; then exit $stat; fi
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
# X makedepend
(
shift
cleared=no
for arg in "$@"; do
case $cleared in no)
set ""; shift
cleared=yes
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift;;
-*)
;;
*)
set fnord "$@" "$arg"; shift;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
) &
proc=$!
"$@"
stat=$?
wait "$proc"
if test "$stat" != 0; then exit $stat; fi
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
( IFS=" "
case " $* " in
*" --mode=compile "*)
for arg
do # cycle over the arguments
case $arg in
"--mode=compile")
# insert --quiet before "--mode=compile"
set fnord "$@" --quiet
shift # fnord
;;
esac
set fnord "$@" "$arg"
shift # fnord
shift # "$arg"
done
;;
esac
"$@" -E |
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
) &
proc=$!
"$@"
stat=$?
wait "$proc"
if test "$stat" != 0; then exit $stat; fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
( IFS=" "
case " $* " in
*" --mode=compile "*)
for arg
do # cycle over the arguments
case $arg in
"--mode=compile")
# insert --quiet before "--mode=compile"
set fnord "$@" --quiet
shift # fnord
;;
esac
set fnord "$@" "$arg"
shift # fnord
shift # "$arg"
done
;;
esac
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
) &
proc=$!
"$@"
stat=$?
wait "$proc"
if test "$stat" != 0; then exit $stat; fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0

View File

@ -1,8 +0,0 @@
# Main Makefile for DOSBox
man_MANS = dosbox.1
EXTRA_DIST = $(man_MANS) README.video PORTING

View File

@ -1,44 +0,0 @@
Some notes about porting DOSBox to systems with certain restrictions,
like handheld devices.
If memory is a constraint:
- in paging.h out-comment the USE_FULL_TLB define to enable special
TLB linking code that uses less memory
drawback: none (the code is not heavily tested though)
gain: reduces memory requirements about ~15mb
- in render.h lower the scaler integration:
#define RENDER_USE_ADVANCED_SCALERS 1
or
#define RENDER_USE_ADVANCED_SCALERS 0
drawback: complex scalers and the scaler cache are disabled,
be sure to test if this affects speed!
with define RENDER_USE_ADVANCED_SCALERS==0 most simple
scalers are disabled as well, some graphics modes won't
work due to reduced cache sizes
gain: ~2mb with RENDER_USE_ADVANCED_SCALERS==1
~5mb with RENDER_USE_ADVANCED_SCALERS==0
- in dos_system.h reduce the drive cache entries:
#define MAX_OPENDIRS 256
drawback: some apps might not work with large directory trees
gain: ~1mb per mounted drive
- remove the GUS emulation (gus.cpp, especially GUSRam[1024*1024] )
drawback: no gravis ultrasound
gain: reduces memory requirements about 1mb
- reduce the size of the emulated graphics memory:
see the memory sizing in SVGA_Setup_*, especially the defaults
in vga_s3.cpp's SVGA_Setup_S3Trio
drawback: some graphics modes won't work then
gain: reduces memory requirements
TODO: fully check this, introduce hard limits
If speed is a constraint:
- see if the simple core is faster, possibly remove the normal core
set the simple core as default
drawback: one game is known to not work with the simple core;
the simple core does only work for games which don't use paging
(when paging is requested the normal core is used automatically)
gain: the simple core should be somewhat faster
TODO: add possibility to easily remove the normal core, use fullcore fallback
- raise the default frameskip value
drawback: minor graphics smoothness loss for some games (video playback)
gain: reduces graphics load

View File

@ -1,35 +0,0 @@
Starting with version 0.65, DOSBox allows you to create movies out of screen
output.
To record a movie, you have to press CTRL-ALT-F5.
To stop/end the recording, you have to press CTRL-ALT-F5 again.
To play the recorded movie, you need a movie player which can handle the
ZMBV codec. MS Windows users can find this codec in the start menu entry of
DOSBox. Users of Linux and other OSes should look for a movie player that
uses the ffmpeg libary (you may need to update or ask your distribution to
upgrade).
FAQ:
Q: During the display of the movies the sound is lagging.
A: Check your display properties to see whether your refresh rate is set to
at least 70 hz. Try playing the movie in virtualdub (http://virtualdub.sf.net)
Q: Why does the resulting movie consist of multiple files?
A: Each time the game changes resolution, DOSBox creates a new movie file,
because a movie file can only contain one resolution.
Q: Can I set the cycles higher than my PC can handle during recording?
A: Yes. During recording, the game might play slowly and stuttering, but the
resulting movie should play at the intended speed and have no stuttering.
Q: CTRL-ALT-F5 switches to the console under linux.
A: 1. Start DOSBox like this: dosbox -startmapper
2. Click on Video, click on Add
3. Press the key you want (for example scroll lock or printscreen)
4. Click exit.
5. You can make movies by pressing scroll lock or whichever key you
selected.
Q: The colours are wrong and I'm using 64 bit windows
A: Look here: http://vogons.zetafleet.com/viewtopic.php?t=12133

View File

@ -1,337 +0,0 @@
.\" Hey, EMACS: -*- nroff -*-
.TH DOSBOX 1 "Jul 01, 2007"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
dosbox \- an x86/DOS emulator with sound/graphics
.SH SYNOPSIS
.B dosbox
.B [\-fullscreen]
.B [\-startmapper]
.B [\-noautoexec]
.B [\-securemode]
.BI "[\-scaler " scaler ]
.BI "[\-forcescaler " scaler ]
.BI "[\-conf " configfile ]
.BI "[\-lang " langfile ]
.B [file]
.BI "[\-c " command ]
.B [\-exit]
.BI "[\-machine " machinetype ]
.LP
.B dosbox -version
.SH DESCRIPTION
This manual page briefly documents
.BR "dosbox" ", an x86/DOS emulator."
.LP
.RB "The optional " file " argument should be a DOS executable or a"
directory. If it is a dos executable (.com .exe .bat) the program will
run automatically. If it is a directory, a DOS session will run with
the directory mounted as C:\\.
.LP
.RI "For an introduction type " INTRO
.RB "inside " dosbox .
.SH OPTIONS
A summary of options is included below.
.TP
.B \-fullscreen
.RB "Start " dosbox " in fullscreen mode."
.TP
.B \-startmapper
.RB "Start the internal keymapper on startup of " dosbox ". You can use it to change the keys " dosbox " uses."
.TP
.B \-noautoexec
Skips the [autoexec] section of the loaded configuration file.
.TP
.B \-securemode
.RB "Same as " \-noautoexec ", but adds " "config.com \-securemode"
at the end of
.I AUTOEXEC.BAT
(which in turn disables any changes to how the drives are mounted
.RB "inside " dosbox )
.TP
.BI \-scaler " scaler"
.RI "Uses the graphical scaler specified by " scaler ". See the configuration"
file for the available scalers
.TP
.BI \-forcescaler " scaler"
.RB "Similar to the " \-scaler " parameter, but tries to force usage of"
the specified scaler even if it might not fit.
.TP
.BI \-c " command"
.RI "Runs the specified " command " before running "
.BR file .
.RI "Multiple commands can be specified. Each " command " should start with "
.BR \-c " though. A command can be:"
an Internal Program, a DOS command or an executable on a mounted drive.
.TP
.BI \-conf " configfile
.RB "Start " dosbox " with the options specified in "
.IR configfile ". This file has a section in which you can put commands you "
wish to execute on startup. Multiple
.IR configfiles " can be present at the commandline."
.TP
.BI \-lang " langfile
.RB "Start " dosbox " with the language specified in "
.IR langfile .
.TP
.B \-exit
.BR dosbox " will close itself when the DOS program specified by "file " ends."
.TP
.BI \-machine " machinetype
.RB "Setup " dosbox " to emulate a specific type of machine."
.RI "Valid choices are: " "hercules, cga, pcjr, tandy, vga(default)".
The machinetype has influence on both the videocard and the available
soundcards.
.TP
.B \-version
Output version information and exit. Useful for frontends.
.SH "INTERNAL COMMANDS"
.B dosbox
supports most of the DOS commands found in command.com. In addition, the
following extra commands are available:
.HP
.BI "MOUNT [\-t " type "] [\-size " size ]
.I driveletter sourcedirectory
.B [\-ioctl]
.BI "[\-usecd " number "] [\-label " drivelabel "] [\-freesize " freesize ]
.LP
.B MOUNT \-cd
.LP
.B MOUNT \-u driveletter
.LP
.RB "Program to mount local directories as drives inside " dosbox .
.RS
.TP
.I driveletter
The driveletter inside dosbox (eg. C).
.TP
.I sourcedirectory
The local directory you want to have inside dosbox.
.TP
.BI \-t " type"
Type of the mounted directory. Supported are: dir (standard), floppy, cdrom.
.TP
.BI \-size " drivesize"
Sets the size of the drive. See the examples in the README for details.
.TP
.BI \-freesize " size_in_mb"
Sets the amount of free space available on a drive in MB's. This is a more
.RB "simple version of " \-size .
.TP
.BI \-label " drivelabel"
.RI "Sets the name of the drive to " drivelabel ". Needed on some"
systems if the cd label isn't read correctly. Useful when a
program can't find its cdrom. If you don't specify a label and no
.RB "lowlevel support is selected (" "\-usecd #" " and/or " "\-ioctl/aspi" "):"
.RS
.LP
For win32: label is extracted from "Real Drive".
.TP
For Linux: label is set to NO_LABEL.
.TP
If you do specify a label this label will be kept as long as the drive
is mounted. It will not be updated !!
.RE
.TP
.B \-ioctl
Forces to use ioctl commands.
.TP
.BI \-usecd " number"
Forces to use SDL cdrom support for drive number.
.IR Number " can be found by "
.BR \-cd ".
.TP
.B \-cd
.RB "Displays all detected cdrom drives and their numbers. Use with " \-usecd "."
.TP
.B \-u
Unmounts a mounted drive. Doesn't work on virtual Drives (like Z:\\)
.RE
.PP
.B "Example:"
.TP
.RB "To mount your /home/dos/dosgames directory as C drive in " dosbox :
.RS
mount c /home/dos/dosgames
.RE
.TP
.B MEM
.LP
Display the amount of free memory
.TP
.B CONFIG [\-writeconf] [\-writelang] file
.LP
.B CONFIG -securemode
.LP
.RB "Write the current configuration or language settings to " file ,
which is located on the local filesystem. Not a mounted drive in
.BR dosbox .
.TP
.B \-securemode
.RB Switches dosbox " to a more secure mode. In this mode the"
.RI "internal commands " MOUNT ", " IMGMOUNT " and " BOOT " won\'t work."
It\'s not possible
either to create a new configfile or languagefile in this mode.
(Warning you can only undo this mode by restarting
.BR dosbox .)
.LP
The configuration file controls various settings of
.BR dosbox ": The amount of emulated memory,"
the emulated soundcards and many
.RI "more things. It futher allows acces to " AUTOEXEC.BAT .
.LP
The language file controls all visible ouput of the internal commands and
the internal dos.
.RB "See the section " FILES " for more information."
.TP
.B LOADFIX [\-size] [programname] [parameters]
.LP
.B LOADFIX \-f
.LP
Program to reduce the amount of memory available. Useful for old programs which don't expect much memory to be free.
.RS
.TP
.B [programname]
The name of the program which is executed after loadfix eats up its memory.
.TP
.B [parameters]
.RB "Parameters given to the " programname " executable."
.TP
.B \-size
The amount of memory to eat up (in kb). Example -32, -64 or -128
.TP
.B \-f
Frees all memory eaten up by loadfix.
.RE
.TP
.B RESCAN
.LP
.RB "Make " dosbox " reread the directory structure. Useful if you changed
.RB "something on a mounted drive outside " dosbox ".(CTRL\-F4 does"
this as well!)
.TP
.B IMGMOUNT
.LP
.RB "A utility to mount disk images and CD-ROM images in " dosbox .
.TP
.RB "Read the " README " of " dosbox " for the full and correct syntax."
.RE
.TP
.B BOOT
.LP
Boot will start floppy images or hard disk images independent of the
.RB "operating system emulation offered by " dosbox ". This will allow you to play booter floppies or boot to other operating systems inside " dosbox .
.TP
.RB "Read the " README " of " dosbox " for the full and correct syntax."
.RE
.TP
.B IPX
.LP
.RB "You need to enable IPX networking in the configuration file of " dosbox .
.RB "All of the IPX networking is managed through the internal " dosbox " program
.BR IPXNET ". For help on the IPX networking from inside " dosbox ", type"
.BR "IPXNET HELP" " and the program will list out the commands and relevant documentation."
.TP
.RB "Read the " README " of " dosbox " for the full and correct syntax."
.RE
.TP
.B KEYB
.LP
Keyb can change the keyboardlayout and the codepage used inside dosbox.
.TP
.RB "Read the " README " of " dosbox " for the full and correct syntax."
.RE
.SH FILES
Configuration and language files use a format similar to Windows .ini files.
First ~/.dosboxrc (if present) will be loaded. If no
configfile is specified at the commandline, a file named
.BR dosbox.conf " (if present in the current directory) will be"
loaded automatically afterwards. If a configfile is specified at the commandline
that one will be used instead.
.SH "SPECIAL KEYS"
.TP 12m
.IP ALT\-ENTER
Go full screen and back.
.IP ALT\-PAUSE
Pause emulation.
.IP CTRL\-F1
Start the keymapper.
.IP CTRL\-ALT\-F5
Start/Stop creating a movie of the screen.
.IP CTRL\-F4
Swap mounted disk-image (Only used with imgmount). Update directory cache
for all drives!
.IP CTRL\-F5
Save a screenshot.(png)
.IP CTRL\-F6
Start/Stop recording sound output to a wave file.
.IP CTRL\-ALT\-F7
Start/Stop recording of OPL commands.
.IP CTRL\-ALT\-F8
Start/Stop the recording of raw MIDI commands.
.IP CTRL\-F7
Decrease frameskip.
.IP CTRL\-F8
Increase frameskip.
.IP CTRL\-F9
Kill dosbox.
.IP CTRL\-F10
Capture/Release the mouse.
.IP CTRL\-F11
Slow down emulation (Increase dosbox Cycles).
.IP CTRL\-F12
Speed up emulation (Decrease dosbox Cycles).
.IP ALT\-F12
Unlock speed (turbo button).
.PP
These are the default keybindings. They can be changed in the keymapper.
.PP
Saved/recorded files can be found in current_directory/capture
(can be changed in the configfile).
.RB "The directory has to exist prior to starting " dosbox " else nothing"
gets saved/recorded !
.PP
.BR "Note: " "Once you increase your " dosbox " cycles beyond your computer's maximum
capacity, it will produce the same effect as slowing down the emulation.
This maximum will vary from computer to computer, there is no standard.
.SH "SYSTEM REQUIREMENTS"
Fast machine. My guess would be pentium\-2 400+ to get decent emulation
of games written for an 286 machine.
For protected mode games a 1 Ghz machine is recommended and don't expect
them to run fast though!! Be sure to read the next section on how to speed
it up somewhat.
.SS "To run resource\-demanding games"
.BR dosbox " emulates the CPU, the sound and graphic cards, and some other"
.RB " stuff, all at the same time. You can overclock " dosbox " by using CTRL\-F12, but"
you'll be limited by the power of your actual CPU. You can see how much free
time your true CPU has by various utils (top). Once 100% of your real CPU time is
.RB "used there is no further way to speed up " dosbox " unless you reduce the load"
.RB "generated by the non\-CPU parts of " dosbox .
.PP
So:
.PP
.RB "Close every program but " dosbox .
.PP
.RB "Overclock " dosbox " until 100% of your CPU is used.(CTRL\-F12)"
.PP
.RB "Since VGA emulation is the most demanding part of " dosbox " in terms of actual"
CPU usage, we'll start here. Increase the number of frames skipped (in
increments of one) by pressing CTRL\-F8. Your CPU usage should decrease.
Go back one step and repeat this until the game runs fast enough for you.
Please note that this is a trade off: you lose in fluidity of video what you
gain in speed.
.SH NOTES
.RB "While we hope that, one day, " dosbox " will run virtually all programs ever made for the PC..."
.RB "we are not there yet. At present, " dosbox " run on a 1.7 Gigahertz PC is roughly the equivalent of a 25MHz 386 PC."
While the 0.60 release has added support for "protected mode" allowing for more complex and recent programs,
but note that this support is early in development and nowhere near as complete as the support for 386 real\-mode
games (or earlier). Also note that "protected mode" games need substantially more resources and may
.RB "require a much faster processor for you to run it properly in " dosbox .
.SH BUGS
Not all DOS programs work properly.
.BR dosbox " will exit without warning if an error occurred."
.SH "SEE ALSO"
The README in /usr/share/doc/dosbox
.SH AUTHOR
This manual page was written by Peter Veenstra <H.P.Veenstra@student.rug.nl> and James Oakley <jfunk@funktronics.ca>,
for the Debian system (but may be used by others).

View File

@ -1,39 +1,29 @@
noinst_HEADERS = \
bios.h \
bios_disk.h \
callback.h \
cpu.h \
cross.h \
control.h \
debug.h \
dma.h \
dos_inc.h \
dos_system.h \
dosbox.h \
fpu.h \
hardware.h \
inout.h \
joystick.h \
ipx.h \
ipxserver.h \
keyboard.h \
logging.h \
mapper.h \
mem.h \
mixer.h \
modules.h \
mouse.h \
paging.h \
pic.h \
programs.h \
render.h \
regs.h \
render.h \
serialport.h \
setup.h \
shell.h \
support.h \
timer.h \
vga.h \
video.h
noinst_HEADERS = \
bios.h \
callback.h \
cpu.h \
cross.h \
debug.h \
dma.h \
dos_inc.h \
dos_system.h \
dosbox.h \
fpu.h \
hardware.h \
inout.h \
joystick.h \
keyboard.h \
mem.h \
mixer.h \
modules.h \
mouse.h \
pic.h \
programs.h \
render.h \
regs.h \
render.h \
setup.h \
support.h \
timer.h \
video.h

269
include/Makefile.in Normal file
View File

@ -0,0 +1,269 @@
# Makefile.in generated by automake 1.6.1 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
noinst_HEADERS = \
bios.h \
callback.h \
cpu.h \
cross.h \
debug.h \
dma.h \
dos_inc.h \
dos_system.h \
dosbox.h \
fpu.h \
hardware.h \
inout.h \
joystick.h \
keyboard.h \
mem.h \
mixer.h \
modules.h \
mouse.h \
pic.h \
programs.h \
render.h \
regs.h \
render.h \
setup.h \
support.h \
timer.h \
video.h
subdir = include
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
HEADERS = $(noinst_HEADERS)
DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnits include/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
uninstall-am: uninstall-info-am
.PHONY: GTAGS all all-am check check-am clean clean-generic distclean \
distclean-generic distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic tags uninstall uninstall-am \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,127 +1,120 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_BIOS_H
#define DOSBOX_BIOS_H
#define BIOS_BASE_ADDRESS_COM1 0x400
#define BIOS_BASE_ADDRESS_COM2 0x402
#define BIOS_BASE_ADDRESS_COM3 0x404
#define BIOS_BASE_ADDRESS_COM4 0x406
#define BIOS_ADDRESS_LPT1 0x408
#define BIOS_ADDRESS_LPT2 0x40a
#define BIOS_ADDRESS_LPT3 0x40c
/* 0x40e is reserved */
#define BIOS_CONFIGURATION 0x410
/* 0x412 is reserved */
#define BIOS_MEMORY_SIZE 0x413
#define BIOS_TRUE_MEMORY_SIZE 0x415
/* #define bios_expansion_memory_size (*(unsigned int *) 0x415) */
#define BIOS_KEYBOARD_STATE 0x417
#define BIOS_KEYBOARD_FLAGS1 BIOS_KEYBOARD_STATE
#define BIOS_KEYBOARD_FLAGS2 0x418
#define BIOS_KEYBOARD_TOKEN 0x419
/* used for keyboard input with Alt-Number */
#define BIOS_KEYBOARD_BUFFER_HEAD 0x41a
#define BIOS_KEYBOARD_BUFFER_TAIL 0x41c
#define BIOS_KEYBOARD_BUFFER 0x41e
/* #define bios_keyboard_buffer (*(unsigned int *) 0x41e) */
#define BIOS_DRIVE_ACTIVE 0x43e
#define BIOS_DRIVE_RUNNING 0x43f
#define BIOS_DISK_MOTOR_TIMEOUT 0x440
#define BIOS_DISK_STATUS 0x441
/* #define bios_fdc_result_buffer (*(unsigned short *) 0x442) */
#define BIOS_VIDEO_MODE 0x449
#define BIOS_SCREEN_COLUMNS 0x44a
#define BIOS_VIDEO_MEMORY_USED 0x44c
#define BIOS_VIDEO_MEMORY_ADDRESS 0x44e
#define BIOS_VIDEO_CURSOR_POS 0x450
#define BIOS_CURSOR_SHAPE 0x460
#define BIOS_CURSOR_LAST_LINE 0x460
#define BIOS_CURSOR_FIRST_LINE 0x461
#define BIOS_CURRENT_SCREEN_PAGE 0x462
#define BIOS_VIDEO_PORT 0x463
#define BIOS_VDU_CONTROL 0x465
#define BIOS_VDU_COLOR_REGISTER 0x466
/* 0x467-0x468 is reserved */
#define BIOS_TIMER 0x46c
#define BIOS_24_HOURS_FLAG 0x470
#define BIOS_KEYBOARD_FLAGS 0x471
#define BIOS_CTRL_ALT_DEL_FLAG 0x472
#define BIOS_HARDDISK_COUNT 0x475
/* 0x474, 0x476, 0x477 is reserved */
#define BIOS_LPT1_TIMEOUT 0x478
#define BIOS_LPT2_TIMEOUT 0x479
#define BIOS_LPT3_TIMEOUT 0x47a
/* 0x47b is reserved */
#define BIOS_COM1_TIMEOUT 0x47c
#define BIOS_COM2_TIMEOUT 0x47d
#define BIOS_COM3_TIMEOUT 0x47e
#define BIOS_COM4_TIMEOUT 0x47f
/* 0x47e is reserved */ //<- why that?
/* 0x47f-0x4ff is unknow for me */
#define BIOS_KEYBOARD_BUFFER_START 0x480
#define BIOS_KEYBOARD_BUFFER_END 0x482
#define BIOS_ROWS_ON_SCREEN_MINUS_1 0x484
#define BIOS_FONT_HEIGHT 0x485
#define BIOS_VIDEO_INFO_0 0x487
#define BIOS_VIDEO_INFO_1 0x488
#define BIOS_VIDEO_INFO_2 0x489
#define BIOS_VIDEO_COMBO 0x48a
#define BIOS_KEYBOARD_FLAGS3 0x496
#define BIOS_KEYBOARD_LEDS 0x497
#define BIOS_WAIT_FLAG_POINTER 0x498
#define BIOS_WAIT_FLAG_COUNT 0x49c
#define BIOS_WAIT_FLAG_ACTIVE 0x4a0
#define BIOS_WAIT_FLAG_TEMP 0x4a1
#define BIOS_PRINT_SCREEN_FLAG 0x500
#define BIOS_VIDEO_SAVEPTR 0x4a8
/* maximum of scancodes handled by keyboard bios routines */
#define MAX_SCAN_CODE 0x58
/* The Section handling Bios Disk Access */
//#define BIOS_MAX_DISK 10
//#define MAX_SWAPPABLE_DISKS 20
void BIOS_ZeroExtendedSize(bool in);
void char_out(Bit8u chr,Bit32u att,Bit8u page);
void INT10_StartUp(void);
void INT16_StartUp(void);
void INT2A_StartUp(void);
void INT2F_StartUp(void);
void INT33_StartUp(void);
void INT13_StartUp(void);
bool BIOS_AddKeyToBuffer(Bit16u code);
void INT10_ReloadRomFonts();
void BIOS_SetComPorts (Bit16u baseaddr[]);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define BIOS_BASE_ADDRESS_COM1 0x400
#define BIOS_BASE_ADDRESS_COM2 0x402
#define BIOS_BASE_ADDRESS_COM3 0x404
#define BIOS_BASE_ADDRESS_COM4 0x406
#define BIOS_ADDRESS_LPT1 0x408
#define BIOS_ADDRESS_LPT2 0x40a
#define BIOS_ADDRESS_LPT3 0x40c
/* 0x40e is reserved */
#define BIOS_CONFIGURATION 0x410
/* 0x412 is reserved */
#define BIOS_MEMORY_SIZE 0x413
/* #define bios_expansion_memory_size (*(unsigned int *) 0x415) */
#define BIOS_KEYBOARD_STATE 0x417
#define BIOS_KEYBOARD_FLAGS1 BIOS_KEYBOARD_STATE
#define BIOS_KEYBOARD_FLAGS2 0x418
#define BIOS_KEYBOARD_TOKEN 0x419
/* used for keyboard input with Alt-Number */
#define BIOS_KEYBOARD_BUFFER_HEAD 0x41a
#define BIOS_KEYBOARD_BUFFER_TAIL 0x41c
#define BIOS_KEYBOARD_BUFFER 0x41e
/* #define bios_keyboard_buffer (*(unsigned int *) 0x41e) */
#define BIOS_DRIVE_ACTIVE 0x43e
#define BIOS_DRIVE_RUNNING 0x43f
#define BIOS_MOTOR_NACHLAUFZEIT 0x440
#define BIOS_DISK_STATUS 0x441
/* #define bios_fdc_result_buffer (*(unsigned short *) 0x442) */
#define BIOS_VIDEO_MODE 0x449
#define BIOS_SCREEN_COLUMNS 0x44a
#define BIOS_VIDEO_MEMORY_USED 0x44c
#define BIOS_VIDEO_MEMORY_ADDRESS 0x44e
#define BIOS_VIDEO_CURSOR_POS 0x450
#define BIOS_CURSOR_SHAPE 0x460
#define BIOS_CURSOR_LAST_LINE 0x460
#define BIOS_CURSOR_FIRST_LINE 0x461
#define BIOS_CURRENT_SCREEN_PAGE 0x462
#define BIOS_VIDEO_PORT 0x463
#define BIOS_VDU_CONTROL 0x465
#define BIOS_VDU_COLOR_REGISTER 0x466
/* 0x467-0x468 is reserved */
#define BIOS_TIMER 0x46c
#define BIOS_24_HOURS_FLAG 0x470
#define BIOS_KEYBOARD_FLAGS 0x471
#define BIOS_CTRL_ALT_DEL_FLAG 0x472
#define BIOS_HARDDISK_COUNT 0x475
/* 0x474, 0x476, 0x477 is reserved */
#define BIOS_LPT1_TIMEOUT 0x478
#define BIOS_LPT2_TIMEOUT 0x479
#define BIOS_LPT3_TIMEOUT 0x47a
/* 0x47b is reserved */
#define BIOS_COM1_TIMEOUT 0x47c
#define BIOS_COM2_TIMEOUT 0x47d
/* 0x47e is reserved */
/* 0x47f-0x4ff is unknow for me */
#define BIOS_KEYBOARD_BUFFER_START 0x480
#define BIOS_KEYBOARD_BUFFER_END 0x482
#define BIOS_ROWS_ON_SCREEN_MINUS_1 0x484
#define BIOS_FONT_HEIGHT 0x485
#define BIOS_VIDEO_INFO_0 0x487
#define BIOS_VIDEO_INFO_1 0x488
#define BIOS_VIDEO_INFO_2 0x489
#define BIOS_VIDEO_COMBO 0x48a
#define BIOS_KEYBOARD_FLAGS3 0x496
#define BIOS_KEYBOARD_LEDS 0x497
#define BIOS_PRINT_SCREEN_FLAG 0x500
#define BIOS_VIDEO_SAVEPTR 0x4a8
/* The Section handling Bios Disk Access */
#define BIOS_MAX_DISK 10
class BIOS_Disk {
public:
virtual Bit8u Read_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data)=0;
virtual Bit8u Write_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data)=0;
};
class imageDisk : public BIOS_Disk {
public:
Bit8u Read_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data);
Bit8u Write_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data);
imageDisk(char * file);
private:
Bit16u sector_size;
Bit16u heads,cylinders,sectors;
Bit8u * image;
};
void char_out(Bit8u chr,Bit32u att,Bit8u page);
void INT10_StartUp(void);
void INT16_StartUp(void);
void INT2A_StartUp(void);
void INT2F_StartUp(void);
void INT33_StartUp(void);
void INT13_StartUp(void);

View File

@ -1,85 +0,0 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_BIOS_DISK_H
#define DOSBOX_BIOS_DISK_H
#include <stdio.h>
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
#ifndef DOSBOX_DOS_INC_H
#include "dos_inc.h"
#endif
#ifndef DOSBOX_BIOS_H
#include "bios.h"
#endif
/* The Section handling Bios Disk Access */
#define BIOS_MAX_DISK 10
#define MAX_SWAPPABLE_DISKS 20
struct diskGeo {
Bit32u ksize; /* Size in kilobytes */
Bit16u secttrack; /* Sectors per track */
Bit16u headscyl; /* Heads per cylinder */
Bit16u cylcount; /* Cylinders per side */
Bit16u biosval; /* Type to return from BIOS */
};
extern diskGeo DiskGeometryList[];
class imageDisk {
public:
Bit8u Read_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
Bit8u Write_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
Bit8u Read_AbsoluteSector(Bit32u sectnum, void * data);
Bit8u Write_AbsoluteSector(Bit32u sectnum, void * data);
void Set_Geometry(Bit32u setHeads, Bit32u setCyl, Bit32u setSect, Bit32u setSectSize);
void Get_Geometry(Bit32u * getHeads, Bit32u *getCyl, Bit32u *getSect, Bit32u *getSectSize);
Bit8u GetBiosType(void);
Bit32u getSectSize(void);
imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHardDisk);
~imageDisk() { if(diskimg != NULL) { fclose(diskimg); } };
bool hardDrive;
bool active;
FILE *diskimg;
Bit8u diskname[512];
Bit8u floppytype;
Bit32u sector_size;
Bit32u heads,cylinders,sectors;
};
void updateDPT(void);
#define MAX_HDD_IMAGES 2
extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES];
extern imageDisk *diskSwap[20];
extern Bits swapPosition;
extern Bit16u imgDTASeg; /* Real memory location of temporary DTA pointer for fat image disk access */
extern RealPt imgDTAPtr; /* Real memory location of temporary DTA pointer for fat image disk access */
extern DOS_DTA *imgDTA;
void swapInDisks(void);
void swapInNextDisk(void);
bool getSwapRequest(void);
#endif

View File

@ -1,99 +1,56 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: callback.h,v 1.23 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_CALLBACK_H
#define DOSBOX_CALLBACK_H
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
typedef Bitu (*CallBack_Handler)(void);
extern CallBack_Handler CallBack_Handlers[];
enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1,
CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR,CB_MOUSE,
CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET,
CB_INT21 };
#define CB_MAX 128
#define CB_SIZE 32
#define CB_SEG 0xF100
enum {
CBRET_NONE=0,CBRET_STOP=1
};
extern Bit8u lastint;
static INLINE RealPt CALLBACK_RealPointer(Bitu callback) {
return RealMake(CB_SEG,(Bit16u)(callback*CB_SIZE));
}
static INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) {
return PhysMake(CB_SEG,(Bit16u)(callback*CB_SIZE));
}
static INLINE PhysPt CALLBACK_GetBase(void) {
return CB_SEG << 4;
}
Bitu CALLBACK_Allocate();
void CALLBACK_Idle(void);
void CALLBACK_RunRealInt(Bit8u intnum);
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off);
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr);
Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr);
const char* CALLBACK_GetDescription(Bitu callback);
bool CALLBACK_Free(Bitu callback);
void CALLBACK_SCF(bool val);
void CALLBACK_SZF(bool val);
extern Bitu call_priv_io;
class CALLBACK_HandlerObject{
private:
bool installed;
Bit16u m_callback;
enum {NONE,SETUP,SETUPAT} m_type;
struct {
RealPt old_vector;
Bit8u interrupt;
bool installed;
} vectorhandler;
public:
CALLBACK_HandlerObject():installed(false),m_type(NONE){vectorhandler.installed=false;}
~CALLBACK_HandlerObject();
//Install and allocate a callback.
void Install(CallBack_Handler handler,Bitu type,const char* description);
void Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description);
//Only allocate a callback number
void Allocate(CallBack_Handler handler,const char* description=0);
Bit16u Get_callback(){return m_callback;}
RealPt Get_RealPointer(){ return CALLBACK_RealPointer(m_callback);}
void Set_RealVec(Bit8u vec);
};
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __CALLBACK_H
#define __CALLBACK_H
#include <mem.h>
typedef Bitu (*CallBack_Handler)(void);
extern CallBack_Handler CallBack_Handlers[];
enum { CB_RETF,CB_IRET };
#define CB_MAX 1024
#define CB_SEG 0xC800
enum {
CBRET_NONE=0,CBRET_STOP=1
};
extern Bit8u lastint;
INLINE RealPt CALLBACK_RealPointer(Bitu callback) {
return RealMake(CB_SEG,callback << 4);
}
Bitu CALLBACK_Allocate();
void CALLBACK_Idle(void);
void CALLBACK_RunRealInt(Bit8u intnum);
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off);
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type);
bool CALLBACK_Free(Bitu callback);
void CALLBACK_SCF(bool val);
void CALLBACK_SZF(bool val);
#endif

View File

@ -1,87 +0,0 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: control.h,v 1.1 2009/02/01 14:11:45 qbix79 Exp $ */
#ifndef DOSBOX_CONTROL_H
#define DOSBOX_CONTROL_H
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#pragma warning ( disable : 4290 )
#endif
#ifndef DOSBOX_PROGRAMS_H
#include "programs.h"
#endif
#ifndef DOSBOX_SETUP_H
#include "setup.h"
#endif
#ifndef CH_LIST
#define CH_LIST
#include <list>
#endif
#ifndef CH_VECTOR
#define CH_VECTOR
#include <vector>
#endif
#ifndef CH_STRING
#define CH_STRING
#include <string>
#endif
class Config{
public:
CommandLine * cmdline;
private:
std::list<Section*> sectionlist;
typedef std::list<Section*>::iterator it;
typedef std::list<Section*>::reverse_iterator reverse_it;
typedef std::list<Section*>::const_iterator const_it;
typedef std::list<Section*>::const_reverse_iterator const_reverse_it;
void (* _start_function)(void);
bool secure_mode; //Sandbox mode
public:
Config(CommandLine * cmd):cmdline(cmd),secure_mode(false){}
~Config();
Section_line * AddSection_line(char const * const _name,void (*_initfunction)(Section*));
Section_prop * AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange=false);
Section* GetSection(int index);
Section* GetSection(std::string const&_sectionname) const;
Section* GetSectionFromProperty(char const * const prop) const;
void SetStartUp(void (*_function)(void));
void Init();
void ShutDown();
void StartUp();
bool PrintConfig(char const * const configfilename) const;
bool ParseConfigFile(char const * const configfilename);
void ParseEnv(char ** envp);
bool SecureMode() const { return secure_mode; }
void SwitchToSecureMode() { secure_mode = true; }//can't be undone
};
#endif

View File

@ -1,492 +1,99 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cpu.h,v 1.56 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_CPU_H
#define DOSBOX_CPU_H
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#ifndef DOSBOX_REGS_H
#include "regs.h"
#endif
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
#define CPU_AUTODETERMINE_NONE 0x00
#define CPU_AUTODETERMINE_CORE 0x01
#define CPU_AUTODETERMINE_CYCLES 0x02
#define CPU_AUTODETERMINE_SHIFT 0x02
#define CPU_AUTODETERMINE_MASK 0x03
#define CPU_CYCLES_LOWER_LIMIT 100
#define CPU_ARCHTYPE_MIXED 0xff
#define CPU_ARCHTYPE_386SLOW 0x30
#define CPU_ARCHTYPE_386FAST 0x35
#define CPU_ARCHTYPE_486OLDSLOW 0x40
#define CPU_ARCHTYPE_486NEWSLOW 0x45
#define CPU_ARCHTYPE_PENTIUMSLOW 0x50
/* CPU Cycle Timing */
extern Bit32s CPU_Cycles;
extern Bit32s CPU_CycleLeft;
extern Bit32s CPU_CycleMax;
extern Bit32s CPU_OldCycleMax;
extern Bit32s CPU_CyclePercUsed;
extern Bit32s CPU_CycleLimit;
extern Bit64s CPU_IODelayRemoved;
extern bool CPU_CycleAutoAdjust;
extern bool CPU_SkipCycleAutoAdjust;
extern Bitu CPU_AutoDetermineMode;
extern Bitu CPU_ArchitectureType;
extern Bitu CPU_PrefetchQueueSize;
/* Some common Defines */
/* A CPU Handler */
typedef Bits (CPU_Decoder)(void);
extern CPU_Decoder * cpudecoder;
Bits CPU_Core_Normal_Run(void);
Bits CPU_Core_Normal_Trap_Run(void);
Bits CPU_Core_Simple_Run(void);
Bits CPU_Core_Full_Run(void);
Bits CPU_Core_Dyn_X86_Run(void);
Bits CPU_Core_Dyn_X86_Trap_Run(void);
Bits CPU_Core_Dynrec_Run(void);
Bits CPU_Core_Dynrec_Trap_Run(void);
Bits CPU_Core_Prefetch_Run(void);
Bits CPU_Core_Prefetch_Trap_Run(void);
void CPU_Enable_SkipAutoAdjust(void);
void CPU_Disable_SkipAutoAdjust(void);
void CPU_Reset_AutoAdjust(void);
//CPU Stuff
extern Bit16u parity_lookup[256];
bool CPU_LLDT(Bitu selector);
bool CPU_LTR(Bitu selector);
void CPU_LIDT(Bitu limit,Bitu base);
void CPU_LGDT(Bitu limit,Bitu base);
Bitu CPU_STR(void);
Bitu CPU_SLDT(void);
Bitu CPU_SIDT_base(void);
Bitu CPU_SIDT_limit(void);
Bitu CPU_SGDT_base(void);
Bitu CPU_SGDT_limit(void);
void CPU_ARPL(Bitu & dest_sel,Bitu src_sel);
void CPU_LAR(Bitu selector,Bitu & ar);
void CPU_LSL(Bitu selector,Bitu & limit);
void CPU_SET_CRX(Bitu cr,Bitu value);
bool CPU_WRITE_CRX(Bitu cr,Bitu value);
Bitu CPU_GET_CRX(Bitu cr);
bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue);
bool CPU_WRITE_DRX(Bitu dr,Bitu value);
bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue);
bool CPU_WRITE_TRX(Bitu dr,Bitu value);
bool CPU_READ_TRX(Bitu dr,Bit32u & retvalue);
Bitu CPU_SMSW(void);
bool CPU_LMSW(Bitu word);
void CPU_VERR(Bitu selector);
void CPU_VERW(Bitu selector);
void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu oldeip);
void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu oldeip);
void CPU_RET(bool use32,Bitu bytes,Bitu oldeip);
void CPU_IRET(bool use32,Bitu oldeip);
void CPU_HLT(Bitu oldeip);
bool CPU_POPF(Bitu use32);
bool CPU_PUSHF(Bitu use32);
bool CPU_CLI(void);
bool CPU_STI(void);
bool CPU_IO_Exception(Bitu port,Bitu size);
void CPU_RunException(void);
void CPU_ENTER(bool use32,Bitu bytes,Bitu level);
#define CPU_INT_SOFTWARE 0x1
#define CPU_INT_EXCEPTION 0x2
#define CPU_INT_HAS_ERROR 0x4
#define CPU_INT_NOIOPLCHECK 0x8
void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip);
static INLINE void CPU_HW_Interrupt(Bitu num) {
CPU_Interrupt(num,0,reg_eip);
}
static INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) {
CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip);
}
static INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) {
CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK,oldeip);
}
bool CPU_PrepareException(Bitu which,Bitu error);
void CPU_Exception(Bitu which,Bitu error=0);
bool CPU_SetSegGeneral(SegNames seg,Bitu value);
bool CPU_PopSeg(SegNames seg,bool use32);
bool CPU_CPUID(void);
Bitu CPU_Pop16(void);
Bitu CPU_Pop32(void);
void CPU_Push16(Bitu value);
void CPU_Push32(Bitu value);
void CPU_SetFlags(Bitu word,Bitu mask);
#define EXCEPTION_UD 6
#define EXCEPTION_TS 10
#define EXCEPTION_NP 11
#define EXCEPTION_SS 12
#define EXCEPTION_GP 13
#define EXCEPTION_PF 14
#define CR0_PROTECTION 0x00000001
#define CR0_MONITORPROCESSOR 0x00000002
#define CR0_FPUEMULATION 0x00000004
#define CR0_TASKSWITCH 0x00000008
#define CR0_FPUPRESENT 0x00000010
#define CR0_PAGING 0x80000000
// *********************************************************************
// Descriptor
// *********************************************************************
#define DESC_INVALID 0x00
#define DESC_286_TSS_A 0x01
#define DESC_LDT 0x02
#define DESC_286_TSS_B 0x03
#define DESC_286_CALL_GATE 0x04
#define DESC_TASK_GATE 0x05
#define DESC_286_INT_GATE 0x06
#define DESC_286_TRAP_GATE 0x07
#define DESC_386_TSS_A 0x09
#define DESC_386_TSS_B 0x0b
#define DESC_386_CALL_GATE 0x0c
#define DESC_386_INT_GATE 0x0e
#define DESC_386_TRAP_GATE 0x0f
/* EU/ED Expand UP/DOWN RO/RW Read Only/Read Write NA/A Accessed */
#define DESC_DATA_EU_RO_NA 0x10
#define DESC_DATA_EU_RO_A 0x11
#define DESC_DATA_EU_RW_NA 0x12
#define DESC_DATA_EU_RW_A 0x13
#define DESC_DATA_ED_RO_NA 0x14
#define DESC_DATA_ED_RO_A 0x15
#define DESC_DATA_ED_RW_NA 0x16
#define DESC_DATA_ED_RW_A 0x17
/* N/R Readable NC/C Confirming A/NA Accessed */
#define DESC_CODE_N_NC_A 0x18
#define DESC_CODE_N_NC_NA 0x19
#define DESC_CODE_R_NC_A 0x1a
#define DESC_CODE_R_NC_NA 0x1b
#define DESC_CODE_N_C_A 0x1c
#define DESC_CODE_N_C_NA 0x1d
#define DESC_CODE_R_C_A 0x1e
#define DESC_CODE_R_C_NA 0x1f
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct S_Descriptor {
#ifdef WORDS_BIGENDIAN
Bit32u base_0_15 :16;
Bit32u limit_0_15 :16;
Bit32u base_24_31 :8;
Bit32u g :1;
Bit32u big :1;
Bit32u r :1;
Bit32u avl :1;
Bit32u limit_16_19 :4;
Bit32u p :1;
Bit32u dpl :2;
Bit32u type :5;
Bit32u base_16_23 :8;
#else
Bit32u limit_0_15 :16;
Bit32u base_0_15 :16;
Bit32u base_16_23 :8;
Bit32u type :5;
Bit32u dpl :2;
Bit32u p :1;
Bit32u limit_16_19 :4;
Bit32u avl :1;
Bit32u r :1;
Bit32u big :1;
Bit32u g :1;
Bit32u base_24_31 :8;
#endif
}GCC_ATTRIBUTE(packed);
struct G_Descriptor {
#ifdef WORDS_BIGENDIAN
Bit32u selector: 16;
Bit32u offset_0_15 :16;
Bit32u offset_16_31 :16;
Bit32u p :1;
Bit32u dpl :2;
Bit32u type :5;
Bit32u reserved :3;
Bit32u paramcount :5;
#else
Bit32u offset_0_15 :16;
Bit32u selector :16;
Bit32u paramcount :5;
Bit32u reserved :3;
Bit32u type :5;
Bit32u dpl :2;
Bit32u p :1;
Bit32u offset_16_31 :16;
#endif
} GCC_ATTRIBUTE(packed);
struct TSS_16 {
Bit16u back; /* Back link to other task */
Bit16u sp0; /* The CK stack pointer */
Bit16u ss0; /* The CK stack selector */
Bit16u sp1; /* The parent KL stack pointer */
Bit16u ss1; /* The parent KL stack selector */
Bit16u sp2; /* Unused */
Bit16u ss2; /* Unused */
Bit16u ip; /* The instruction pointer */
Bit16u flags; /* The flags */
Bit16u ax, cx, dx, bx; /* The general purpose registers */
Bit16u sp, bp, si, di; /* The special purpose registers */
Bit16u es; /* The extra selector */
Bit16u cs; /* The code selector */
Bit16u ss; /* The application stack selector */
Bit16u ds; /* The data selector */
Bit16u ldt; /* The local descriptor table */
} GCC_ATTRIBUTE(packed);
struct TSS_32 {
Bit32u back; /* Back link to other task */
Bit32u esp0; /* The CK stack pointer */
Bit32u ss0; /* The CK stack selector */
Bit32u esp1; /* The parent KL stack pointer */
Bit32u ss1; /* The parent KL stack selector */
Bit32u esp2; /* Unused */
Bit32u ss2; /* Unused */
Bit32u cr3; /* The page directory pointer */
Bit32u eip; /* The instruction pointer */
Bit32u eflags; /* The flags */
Bit32u eax, ecx, edx, ebx; /* The general purpose registers */
Bit32u esp, ebp, esi, edi; /* The special purpose registers */
Bit32u es; /* The extra selector */
Bit32u cs; /* The code selector */
Bit32u ss; /* The application stack selector */
Bit32u ds; /* The data selector */
Bit32u fs; /* And another extra selector */
Bit32u gs; /* ... and another one */
Bit32u ldt; /* The local descriptor table */
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack()
#endif
class Descriptor
{
public:
Descriptor() { saved.fill[0]=saved.fill[1]=0; }
void Load(PhysPt address);
void Save(PhysPt address);
PhysPt GetBase (void) {
return (saved.seg.base_24_31<<24) | (saved.seg.base_16_23<<16) | saved.seg.base_0_15;
}
Bitu GetLimit (void) {
Bitu limit = (saved.seg.limit_16_19<<16) | saved.seg.limit_0_15;
if (saved.seg.g) return (limit<<12) | 0xFFF;
return limit;
}
Bitu GetOffset(void) {
return (saved.gate.offset_16_31 << 16) | saved.gate.offset_0_15;
}
Bitu GetSelector(void) {
return saved.gate.selector;
}
Bitu Type(void) {
return saved.seg.type;
}
Bitu Conforming(void) {
return saved.seg.type & 8;
}
Bitu DPL(void) {
return saved.seg.dpl;
}
Bitu Big(void) {
return saved.seg.big;
}
public:
union {
S_Descriptor seg;
G_Descriptor gate;
Bit32u fill[2];
} saved;
};
class DescriptorTable {
public:
PhysPt GetBase (void) { return table_base; }
Bitu GetLimit (void) { return table_limit; }
void SetBase (PhysPt _base) { table_base = _base; }
void SetLimit (Bitu _limit) { table_limit= _limit; }
bool GetDescriptor (Bitu selector, Descriptor& desc) {
selector&=~7;
if (selector>=table_limit) return false;
desc.Load(table_base+(selector));
return true;
}
protected:
PhysPt table_base;
Bitu table_limit;
};
class GDTDescriptorTable : public DescriptorTable {
public:
bool GetDescriptor(Bitu selector, Descriptor& desc) {
Bitu address=selector & ~7;
if (selector & 4) {
if (address>=ldt_limit) return false;
desc.Load(ldt_base+address);
return true;
} else {
if (address>=table_limit) return false;
desc.Load(table_base+address);
return true;
}
}
bool SetDescriptor(Bitu selector, Descriptor& desc) {
Bitu address=selector & ~7;
if (selector & 4) {
if (address>=ldt_limit) return false;
desc.Save(ldt_base+address);
return true;
} else {
if (address>=table_limit) return false;
desc.Save(table_base+address);
return true;
}
}
Bitu SLDT(void) {
return ldt_value;
}
bool LLDT(Bitu value) {
if ((value&0xfffc)==0) {
ldt_value=0;
ldt_base=0;
ldt_limit=0;
return true;
}
Descriptor desc;
if (!GetDescriptor(value,desc)) return !CPU_PrepareException(EXCEPTION_GP,value);
if (desc.Type()!=DESC_LDT) return !CPU_PrepareException(EXCEPTION_GP,value);
if (!desc.saved.seg.p) return !CPU_PrepareException(EXCEPTION_NP,value);
ldt_base=desc.GetBase();
ldt_limit=desc.GetLimit();
ldt_value=value;
return true;
}
private:
PhysPt ldt_base;
Bitu ldt_limit;
Bitu ldt_value;
};
class TSS_Descriptor : public Descriptor {
public:
Bitu IsBusy(void) {
return saved.seg.type & 2;
}
Bitu Is386(void) {
return saved.seg.type & 8;
}
void SetBusy(bool busy) {
if (busy) saved.seg.type|=2;
else saved.seg.type&=~2;
}
};
struct CPUBlock {
Bitu cpl; /* Current Privilege */
Bitu mpl;
Bitu cr0;
bool pmode; /* Is Protected mode enabled */
GDTDescriptorTable gdt;
DescriptorTable idt;
struct {
Bitu mask,notmask;
bool big;
} stack;
struct {
bool big;
} code;
struct {
Bitu cs,eip;
CPU_Decoder * old_decoder;
} hlt;
struct {
Bitu which,error;
} exception;
Bits direction;
bool trap_skip;
Bit32u drx[8];
Bit32u trx[8];
};
extern CPUBlock cpu;
static INLINE void CPU_SetFlagsd(Bitu word) {
Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL;
CPU_SetFlags(word,mask);
}
static INLINE void CPU_SetFlagsw(Bitu word) {
Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff;
CPU_SetFlags(word,mask);
}
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __CPU_H
#define __CPU_H
#include <dosbox.h>
#include <regs.h>
#include <mem.h>
/* Some common Defines */
/* A CPU Handler */
typedef Bitu (CPU_Decoder)(Bitu count);
extern CPU_Decoder * cpudecoder;
extern Bit32u cpu_cycles;
extern Bit32u hoever;
//CPU Stuff
void SetCPU16bit();
void SetSegment_16(Bit32u seg,Bit16u val);
//Types of Flag changing instructions
enum {
t_ADDb=0,t_ADDw,t_ADDd,
t_ORb,t_ORw,t_ORd,
t_ADCb,t_ADCw,t_ADCd,
t_SBBb,t_SBBw,t_SBBd,
t_ANDb,t_ANDw,t_ANDd,
t_SUBb,t_SUBw,t_SUBd,
t_XORb,t_XORw,t_XORd,
t_CMPb,t_CMPw,t_CMPd,
t_INCb,t_INCw,t_INCd,
t_DECb,t_DECw,t_DECd,
t_TESTb,t_TESTw,t_TESTd,
t_SHLb,t_SHLw,t_SHLd,
t_SHRb,t_SHRw,t_SHRd,
t_SARb,t_SARw,t_SARd,
t_ROLb,t_ROLw,t_ROLd,
t_RORb,t_RORw,t_RORd,
t_RCLb,t_RCLw,t_RCLd,
t_RCRb,t_RCRw,t_RCRd,
t_NEGb,t_NEGw,t_NEGd,
t_CF,t_ZF,
t_DSHLw,t_DSHLd,
t_DSHRw,t_DSHRd,
t_MUL,t_DIV,
t_UNKNOWN,
t_NOTDONE,
};
enum { rep_NONE,rep_Z,rep_NZ };
void Interrupt(Bit8u num);
//Flag Handling
bool get_CF(void);
bool get_AF(void);
bool get_ZF(void);
bool get_SF(void);
bool get_OF(void);
bool get_PF(void);
Bit8u get_Flags8(void);
#define LoadCF flags.cf=get_CF();
#define LoadZF flags.zf=get_ZF();
#define LoadSF flags.sf=get_SF();
#define LoadOF flags.of=get_OF();
//The opcode handlers
void FPU_ESC0_Normal(Bitu rm);
void FPU_ESC0_EA(Bitu func,PhysOff ea);
#endif

View File

@ -1,108 +1,54 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cross.h,v 1.21 2009/03/14 18:02:34 qbix79 Exp $ */
#ifndef DOSBOX_CROSS_H
#define DOSBOX_CROSS_H
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>
#if defined (_MSC_VER) /* MS Visual C++ */
#include <direct.h>
#include <io.h>
#define LONGTYPE(a) a##i64
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#else /* LINUX / GCC */
#include <dirent.h>
#include <unistd.h>
#define LONGTYPE(a) a##LL
#endif
#define CROSS_LEN 512 /* Maximum filename size */
#if defined (WIN32) || defined (OS2) /* Win 32 & OS/2*/
#define CROSS_FILENAME(blah)
#define CROSS_FILESPLIT '\\'
#define F_OK 0
#else
#define CROSS_FILENAME(blah) strreplace(blah,'\\','/')
#define CROSS_FILESPLIT '/'
#endif
#define CROSS_NONE 0
#define CROSS_FILE 1
#define CROSS_DIR 2
#if defined (WIN32)
#define ftruncate(blah,blah2) chsize(blah,blah2)
#endif
//Solaris maybe others
#if defined (DB_HAVE_NO_POWF)
#include <math.h>
static inline float powf (float x, float y) { return (float) pow (x,y); }
#endif
class Cross {
public:
static void GetPlatformConfigDir(std::string& in);
static void GetPlatformConfigName(std::string& in);
static void CreatePlatformConfigDir(std::string& in);
static void ResolveHomedir(std::string & temp_line);
static void CreateDir(std::string const& temp);
};
#if defined (WIN32)
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from
#include <windows.h>
typedef struct dir_struct {
HANDLE handle;
char base_path[MAX_PATH+4];
WIN32_FIND_DATA search_data;
} dir_information;
#else
//#include <sys/types.h> //Included above
#include <dirent.h>
typedef struct dir_struct {
DIR* dir;
char base_path[CROSS_LEN];
} dir_information;
#endif
dir_information* open_directory(const char* dirname);
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory);
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory);
void close_directory(dir_information* dirp);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _CROSS_H
#define _CROSS_H
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#if defined (_MSC_VER) /* MS Visual C++ */
#include <direct.h>
#include <io.h>
#else /* LINUX */
#include <dirent.h>
#include <unistd.h>
#endif
#define CROSS_LEN 512 /* Maximum filename size */
#if defined (_MSC_VER) /* MS Visual C++ */
#define CROSS_FILENAME(blah)
#define CROSS_FILESPLIT '\\'
#define F_OK 0
#else
#define CROSS_FILENAME(blah) strreplace(blah,'\\','/')
#define CROSS_FILESPLIT '/'
#endif
#define CROSS_NONE 0
#define CROSS_FILE 1
#define CROSS_DIR 2
extern const char * dosbox_datadir;
#endif

View File

@ -1,35 +1,24 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
void DEBUG_SetupConsole(void);
void DEBUG_DrawScreen(void);
bool DEBUG_Breakpoint(void);
bool DEBUG_IntBreakpoint(Bit8u intNum);
void DEBUG_Enable(bool pressed);
void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off);
bool DEBUG_ExitLoop(void);
void DEBUG_RefreshPage(char scroll);
Bitu DEBUG_EnableDebugger(void);
extern Bitu cycle_count;
extern Bitu debugCallback;
#ifdef C_HEAVY_DEBUG
bool DEBUG_HeavyIsBreakpoint(void);
void DEBUG_HeavyWriteLogInstruction(void);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
void DEBUG_DrawScreen(void);
bool DEBUG_BreakPoint(void);
void DEBUG_Enable(void);
extern Bitu cycle_count;

View File

@ -1,117 +1,24 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dma.h,v 1.18 2008/09/13 20:04:28 c2woody Exp $ */
#ifndef DOSBOX_DMA_H
#define DOSBOX_DMA_H
enum DMAEvent {
DMA_REACHED_TC,
DMA_MASKED,
DMA_UNMASKED,
DMA_TRANSFEREND
};
class DmaChannel;
typedef void (* DMA_CallBack)(DmaChannel * chan,DMAEvent event);
class DmaChannel {
public:
Bit32u pagebase;
Bit16u baseaddr;
Bit16u curraddr;
Bit16u basecnt;
Bit16u currcnt;
Bit8u channum;
Bit8u pagenum;
Bit8u DMA16;
bool increment;
bool autoinit;
Bit8u trantype;
bool masked;
bool tcount;
bool request;
DMA_CallBack callback;
DmaChannel(Bit8u num, bool dma16);
void DoCallBack(DMAEvent event) {
if (callback) (*callback)(this,event);
}
void SetMask(bool _mask) {
masked=_mask;
DoCallBack(masked ? DMA_MASKED : DMA_UNMASKED);
}
void Register_Callback(DMA_CallBack _cb) {
callback = _cb;
SetMask(masked);
if (callback) Raise_Request();
else Clear_Request();
}
void ReachedTC(void) {
tcount=true;
DoCallBack(DMA_REACHED_TC);
}
void SetPage(Bit8u val) {
pagenum=val;
pagebase=(pagenum >> DMA16) << (16+DMA16);
}
void Raise_Request(void) {
request=true;
}
void Clear_Request(void) {
request=false;
}
Bitu Read(Bitu size, Bit8u * buffer);
Bitu Write(Bitu size, Bit8u * buffer);
};
class DmaController {
private:
Bit8u ctrlnum;
bool flipflop;
DmaChannel *DmaChannels[4];
public:
IO_ReadHandleObject DMA_ReadHandler[0x11];
IO_WriteHandleObject DMA_WriteHandler[0x11];
DmaController(Bit8u num) {
flipflop = false;
ctrlnum = num; /* first or second DMA controller */
for(Bit8u i=0;i<4;i++) {
DmaChannels[i] = new DmaChannel(i+ctrlnum*4,ctrlnum==1);
}
}
~DmaController(void) {
for(Bit8u i=0;i<4;i++) {
delete DmaChannels[i];
}
}
DmaChannel * GetChannel(Bit8u chan) {
if (chan<4) return DmaChannels[chan];
else return NULL;
}
void WriteControllerReg(Bitu reg,Bitu val,Bitu len);
Bitu ReadControllerReg(Bitu reg,Bitu len);
};
DmaChannel * GetDMAChannel(Bit8u chan);
void CloseSecondDMAController(void);
bool SecondDMAControllerAvailable(void);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
void DMA_8_Read(Bit32u channel,Bit8u * buffer,Bit16u count);
void DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count);
void DMA_16_Read(Bit32u channel,Bit8u * buffer,Bit16u count);
void DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count);

View File

@ -1,643 +1,275 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_inc.h,v 1.77 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_DOS_INC_H
#define DOSBOX_DOS_INC_H
#ifndef DOSBOX_DOS_SYSTEM_H
#include "dos_system.h"
#endif
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct CommandTail{
Bit8u count; /* number of bytes returned */
char buffer[127]; /* the buffer itself */
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif
struct DOS_Date {
Bit16u year;
Bit8u month;
Bit8u day;
};
struct DOS_Version {
Bit8u major,minor,revision;
};
#ifdef _MSC_VER
#pragma pack (1)
#endif
union bootSector {
struct entries {
Bit8u jump[3];
Bit8u oem_name[8];
Bit16u bytesect;
Bit8u sectclust;
Bit16u reserve_sect;
Bit8u misc[496];
} bootdata;
Bit8u rawdata[512];
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif
enum { MCB_FREE=0x0000,MCB_DOS=0x0008 };
enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
#define DOS_FILES 127
#define DOS_DRIVES 26
#define DOS_DEVICES 10
// dos swappable area is 0x320 bytes beyond the sysvars table
// device driver chain is inside sysvars
#define DOS_INFOBLOCK_SEG 0x80 // sysvars (list of lists)
#define DOS_CONDRV_SEG 0xa0
#define DOS_CONSTRING_SEG 0xa8
#define DOS_SDA_SEG 0xb2 // dos swappable area
#define DOS_SDA_OFS 0
#define DOS_CDS_SEG 0x108
#define DOS_FIRST_SHELL 0x118
#define DOS_MEM_START 0x158 //First Segment that DOS can use
#define DOS_PRIVATE_SEGMENT 0xc800
#define DOS_PRIVATE_SEGMENT_END 0xd000
/* internal Dos Tables */
extern DOS_File * Files[DOS_FILES];
extern DOS_Drive * Drives[DOS_DRIVES];
extern DOS_Device * Devices[DOS_DEVICES];
extern Bit8u dos_copybuf[0x10000];
void DOS_SetError(Bit16u code);
/* File Handling Routines */
enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDPRN=4};
enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE};
/* Routines for File Class */
void DOS_SetupFiles (void);
bool DOS_ReadFile(Bit16u handle,Bit8u * data,Bit16u * amount);
bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount);
bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type);
bool DOS_CloseFile(Bit16u handle);
bool DOS_FlushFile(Bit16u handle);
bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry);
bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry);
bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate);
/* Routines for Drive Class */
bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry);
bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status);
bool DOS_CreateFile(char const * name,Bit16u attribute,Bit16u * entry);
bool DOS_UnlinkFile(char const * const name);
bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false);
bool DOS_FindNext(void);
bool DOS_Canonicalize(char const * const name,char * const big);
bool DOS_CreateTempFile(char * const name,Bit16u * entry);
bool DOS_FileExists(char const * const name);
/* Helper Functions */
bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive);
/* Drive Handing Routines */
Bit8u DOS_GetDefaultDrive(void);
void DOS_SetDefaultDrive(Bit8u drive);
bool DOS_SetDrive(Bit8u drive);
bool DOS_GetCurrentDir(Bit8u drive,char * const buffer);
bool DOS_ChangeDir(char const * const dir);
bool DOS_MakeDir(char const * const dir);
bool DOS_RemoveDir(char const * const dir);
bool DOS_Rename(char const * const oldname,char const * const newname);
bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free);
bool DOS_GetFileAttr(char const * const name,Bit16u * attr);
bool DOS_SetFileAttr(char const * const name,Bit16u attr);
/* IOCTL Stuff */
bool DOS_IOCTL(void);
bool DOS_GetSTDINStatus();
Bit8u DOS_FindDevice(char const * name);
void DOS_SetupDevices(void);
/* Execute and new process creation */
bool DOS_NewPSP(Bit16u pspseg,Bit16u size);
bool DOS_ChildPSP(Bit16u pspseg,Bit16u size);
bool DOS_Execute(char * name,PhysPt block,Bit8u flags);
bool DOS_Terminate(bool tsr,Bit8u exitcode);
/* Memory Handling Routines */
void DOS_SetupMemory(void);
bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks);
bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks);
bool DOS_FreeMemory(Bit16u segment);
void DOS_FreeProcessMemory(Bit16u pspseg);
Bit16u DOS_GetMemory(Bit16u pages);
bool DOS_SetMemAllocStrategy(Bit16u strat);
Bit16u DOS_GetMemAllocStrategy(void);
void DOS_BuildUMBChain(bool umb_active,bool ems_active);
bool DOS_LinkUMBsToMemChain(Bit16u linkstate);
/* FCB stuff */
bool DOS_FCBOpen(Bit16u seg,Bit16u offset);
bool DOS_FCBCreate(Bit16u seg,Bit16u offset);
bool DOS_FCBClose(Bit16u seg,Bit16u offset);
bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset);
bool DOS_FCBFindNext(Bit16u seg,Bit16u offset);
Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset, Bit16u numBlocks);
Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u numBlocks);
Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore);
Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore);
bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset);
bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset);
bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset);
void DOS_FCBSetRandomRecord(Bit16u seg, Bit16u offset);
Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change);
bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters);
/* Extra DOS Interrupts */
void DOS_SetupMisc(void);
/* The DOS Tables */
void DOS_SetupTables(void);
/* Internal DOS Setup Programs */
void DOS_SetupPrograms(void);
/* Initialize Keyboard Layout */
void DOS_KeyboardLayout_Init(Section* sec);
bool DOS_LayoutKey(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3);
enum {
KEYB_NOERROR=0,
KEYB_FILENOTFOUND,
KEYB_INVALIDFILE,
KEYB_LAYOUTNOTFOUND,
KEYB_INVALIDCPFILE
};
static INLINE Bit16u long2para(Bit32u size) {
if (size>0xFFFF0) return 0xffff;
if (size&0xf) return (Bit16u)((size>>4)+1);
else return (Bit16u)(size>>4);
}
static INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) {
return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f);
}
static INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) {
return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f);
}
/* Dos Error Codes */
#define DOSERR_NONE 0
#define DOSERR_FUNCTION_NUMBER_INVALID 1
#define DOSERR_FILE_NOT_FOUND 2
#define DOSERR_PATH_NOT_FOUND 3
#define DOSERR_TOO_MANY_OPEN_FILES 4
#define DOSERR_ACCESS_DENIED 5
#define DOSERR_INVALID_HANDLE 6
#define DOSERR_MCB_DESTROYED 7
#define DOSERR_INSUFFICIENT_MEMORY 8
#define DOSERR_MB_ADDRESS_INVALID 9
#define DOSERR_ENVIRONMENT_INVALID 10
#define DOSERR_FORMAT_INVALID 11
#define DOSERR_ACCESS_CODE_INVALID 12
#define DOSERR_DATA_INVALID 13
#define DOSERR_RESERVED 14
#define DOSERR_FIXUP_OVERFLOW 14
#define DOSERR_INVALID_DRIVE 15
#define DOSERR_REMOVE_CURRENT_DIRECTORY 16
#define DOSERR_NOT_SAME_DEVICE 17
#define DOSERR_NO_MORE_FILES 18
#define DOSERR_FILE_ALREADY_EXISTS 80
/* Remains some classes used to access certain things */
#define sOffset(s,m) ((char*)&(((s*)NULL)->m)-(char*)NULL)
#define sGet(s,m) GetIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m))
#define sSave(s,m,val) SaveIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m),val)
class MemStruct {
public:
Bitu GetIt(Bitu size,PhysPt addr) {
switch (size) {
case 1:return mem_readb(pt+addr);
case 2:return mem_readw(pt+addr);
case 4:return mem_readd(pt+addr);
}
return 0;
}
void SaveIt(Bitu size,PhysPt addr,Bitu val) {
switch (size) {
case 1:mem_writeb(pt+addr,(Bit8u)val);break;
case 2:mem_writew(pt+addr,(Bit16u)val);break;
case 4:mem_writed(pt+addr,(Bit32u)val);break;
}
}
void SetPt(Bit16u seg) { pt=PhysMake(seg,0);}
void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);}
void SetPt(RealPt addr) { pt=Real2Phys(addr);}
protected:
PhysPt pt;
};
class DOS_PSP :public MemStruct {
public:
DOS_PSP (Bit16u segment) { SetPt(segment);seg=segment;};
void MakeNew (Bit16u memSize);
void CopyFileTable (DOS_PSP* srcpsp,bool createchildpsp);
Bit16u FindFreeFileEntry (void);
void CloseFiles (void);
void SaveVectors (void);
void RestoreVectors (void);
void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); };
Bit16u GetSize (void) { return (Bit16u)sGet(sPSP,next_seg); };
void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); };
Bit16u GetEnvironment (void) { return (Bit16u)sGet(sPSP,environment); };
Bit16u GetSegment (void) { return seg; };
void SetFileHandle (Bit16u index, Bit8u handle);
Bit8u GetFileHandle (Bit16u index);
void SetParent (Bit16u parent) { sSave(sPSP,psp_parent,parent); };
Bit16u GetParent (void) { return (Bit16u)sGet(sPSP,psp_parent); };
void SetStack (RealPt stackpt) { sSave(sPSP,stack,stackpt); };
RealPt GetStack (void) { return sGet(sPSP,stack); };
void SetInt22 (RealPt int22pt) { sSave(sPSP,int_22,int22pt); };
RealPt GetInt22 (void) { return sGet(sPSP,int_22); };
void SetFCB1 (RealPt src);
void SetFCB2 (RealPt src);
void SetCommandTail (RealPt src);
bool SetNumFiles (Bit16u fileNum);
Bit16u FindEntryByHandle (Bit8u handle);
private:
#ifdef _MSC_VER
#pragma pack(1)
#endif
struct sPSP {
Bit8u exit[2]; /* CP/M-like exit poimt */
Bit16u next_seg; /* Segment of first byte beyond memory allocated or program */
Bit8u fill_1; /* single char fill */
Bit8u far_call; /* far call opcode */
RealPt cpm_entry; /* CPM Service Request address*/
RealPt int_22; /* Terminate Address */
RealPt int_23; /* Break Address */
RealPt int_24; /* Critical Error Address */
Bit16u psp_parent; /* Parent PSP Segment */
Bit8u files[20]; /* File Table - 0xff is unused */
Bit16u environment; /* Segment of evironment table */
RealPt stack; /* SS:SP Save point for int 0x21 calls */
Bit16u max_files; /* Maximum open files */
RealPt file_table; /* Pointer to File Table PSP:0x18 */
RealPt prev_psp; /* Pointer to previous PSP */
Bit8u interim_flag;
Bit8u truename_flag;
Bit16u nn_flags;
Bit16u dos_version;
Bit8u fill_2[14]; /* Lot's of unused stuff i can't care aboue */
Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */
Bit8u fill_3[9]; /* This has some blocks with FCB info */
Bit8u fcb1[16]; /* first FCB */
Bit8u fcb2[16]; /* second FCB */
Bit8u fill_4[4]; /* unused */
CommandTail cmdtail;
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack()
#endif
Bit16u seg;
public:
static Bit16u rootpsp;
};
class DOS_ParamBlock:public MemStruct {
public:
DOS_ParamBlock(PhysPt addr) {pt=addr;}
void Clear(void);
void LoadData(void);
void SaveData(void); /* Save it as an exec block */
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct sOverlay {
Bit16u loadseg;
Bit16u relocation;
} GCC_ATTRIBUTE(packed);
struct sExec {
Bit16u envseg;
RealPt cmdtail;
RealPt fcb1;
RealPt fcb2;
RealPt initsssp;
RealPt initcsip;
}GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack()
#endif
sExec exec;
sOverlay overlay;
};
class DOS_InfoBlock:public MemStruct {
public:
DOS_InfoBlock () {};
void SetLocation(Bit16u seg);
void SetFirstMCB(Bit16u _first_mcb);
void SetBuffers(Bit16u x,Bit16u y);
void SetCurDirStruct(Bit32u _curdirstruct);
void SetFCBTable(Bit32u _fcbtable);
void SetDeviceChainStart(Bit32u _devchain);
void SetDiskBufferHeadPt(Bit32u _dbheadpt);
void SetStartOfUMBChain(Bit16u _umbstartseg);
void SetUMBChainState(Bit8u _umbchaining);
Bit16u GetStartOfUMBChain(void);
Bit8u GetUMBChainState(void);
RealPt GetPointer(void);
Bit32u GetDeviceChain(void);
#ifdef _MSC_VER
#pragma pack(1)
#endif
struct sDIB {
Bit8u unknown1[4];
Bit16u magicWord; // -0x22 needs to be 1
Bit8u unknown2[8];
Bit16u regCXfrom5e; // -0x18 CX from last int21/ah=5e
Bit16u countLRUcache; // -0x16 LRU counter for FCB caching
Bit16u countLRUopens; // -0x14 LRU counter for FCB openings
Bit8u stuff[6]; // -0x12 some stuff, hopefully never used....
Bit16u sharingCount; // -0x0c sharing retry count
Bit16u sharingDelay; // -0x0a sharing retry delay
RealPt diskBufPtr; // -0x08 pointer to disk buffer
Bit16u ptrCONinput; // -0x04 pointer to con input
Bit16u firstMCB; // -0x02 first memory control block
RealPt firstDPB; // 0x00 first drive parameter block
RealPt firstFileTable; // 0x04 first system file table
RealPt activeClock; // 0x08 active clock device header
RealPt activeCon; // 0x0c active console device header
Bit16u maxSectorLength; // 0x10 maximum bytes per sector of any block device;
RealPt diskInfoBuffer; // 0x12 pointer to disk info buffer
RealPt curDirStructure; // 0x16 pointer to current array of directory structure
RealPt fcbTable; // 0x1a pointer to system FCB table
Bit16u protFCBs; // 0x1e protected fcbs
Bit8u blockDevices; // 0x20 installed block devices
Bit8u lastdrive; // 0x21 lastdrive
Bit32u nulNextDriver; // 0x22 NUL driver next pointer
Bit16u nulAttributes; // 0x26 NUL driver aattributes
Bit32u nulStrategy; // 0x28 NUL driver strategy routine
Bit8u nulString[8]; // 0x2c NUL driver name string
Bit8u joindedDrives; // 0x34 joined drives
Bit16u specialCodeSeg; // 0x35 special code segment
RealPt setverPtr; // 0x37 pointer to setver
Bit16u a20FixOfs; // 0x3b a20 fix routine offset
Bit16u pspLastIfHMA; // 0x3d psp of last program (if dos in hma)
Bit16u buffers_x; // 0x3f x in BUFFERS x,y
Bit16u buffers_y; // 0x41 y in BUFFERS x,y
Bit8u bootDrive; // 0x43 boot drive
Bit8u useDwordMov; // 0x44 use dword moves
Bit16u extendedSize; // 0x45 size of extended memory
Bit32u diskBufferHeadPt; // 0x47 pointer to least-recently used buffer header
Bit16u dirtyDiskBuffers; // 0x4b number of dirty disk buffers
Bit32u lookaheadBufPt; // 0x4d pointer to lookahead buffer
Bit16u lookaheadBufNumber; // 0x51 number of lookahead buffers
Bit8u bufferLocation; // 0x53 workspace buffer location
Bit32u workspaceBuffer; // 0x54 pointer to workspace buffer
Bit8u unknown3[11]; // 0x58
Bit8u chainingUMB; // 0x63 bit0: UMB chain linked to MCB chain
Bit16u minMemForExec; // 0x64 minimum paragraphs needed for current program
Bit16u startOfUMBChain; // 0x66 segment of first UMB-MCB
Bit16u memAllocScanStart; // 0x68 start paragraph for memory allocation
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif
Bit16u seg;
};
class DOS_DTA:public MemStruct{
public:
DOS_DTA(RealPt addr) { SetPt(addr); }
void SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * _pattern);
void SetResult(const char * _name,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr);
Bit8u GetSearchDrive(void);
void GetSearchParams(Bit8u & _sattr,char * _spattern);
void GetResult(char * _name,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr);
void SetDirID(Bit16u entry) { sSave(sDTA,dirID,entry); };
void SetDirIDCluster(Bit16u entry) { sSave(sDTA,dirCluster,entry); };
Bit16u GetDirID(void) { return (Bit16u)sGet(sDTA,dirID); };
Bit16u GetDirIDCluster(void) { return (Bit16u)sGet(sDTA,dirCluster); };
private:
#ifdef _MSC_VER
#pragma pack(1)
#endif
struct sDTA {
Bit8u sdrive; /* The Drive the search is taking place */
Bit8u sname[8]; /* The Search pattern for the filename */
Bit8u sext[3]; /* The Search pattern for the extenstion */
Bit8u sattr; /* The Attributes that need to be found */
Bit16u dirID; /* custom: dir-search ID for multiple searches at the same time */
Bit16u dirCluster; /* custom (drive_fat only): cluster number for multiple searches at the same time */
Bit8u fill[4];
Bit8u attr;
Bit16u time;
Bit16u date;
Bit32u size;
char name[DOS_NAMELENGTH_ASCII];
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack()
#endif
};
class DOS_FCB: public MemStruct {
public:
DOS_FCB(Bit16u seg,Bit16u off);
void Create(bool _extended);
void SetName(Bit8u _drive,char * _fname,char * _ext);
void SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time);
void GetSizeDateTime(Bit32u & _size,Bit16u & _date,Bit16u & _time);
void GetName(char * fillname);
void FileOpen(Bit8u _fhandle);
void FileClose(Bit8u & _fhandle);
void GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec);
void SetRecord(Bit16u _cur_block,Bit8u _cur_rec);
void GetSeqData(Bit8u & _fhandle,Bit16u & _rec_size);
void GetRandom(Bit32u & _random);
void SetRandom(Bit32u _random);
Bit8u GetDrive(void);
bool Extended(void);
void GetAttr(Bit8u & attr);
void SetAttr(Bit8u attr);
bool Valid(void);
private:
bool extended;
PhysPt real_pt;
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct sFCB {
Bit8u drive; /* Drive number 0=default, 1=A, etc */
Bit8u filename[8]; /* Space padded name */
Bit8u ext[3]; /* Space padded extension */
Bit16u cur_block; /* Current Block */
Bit16u rec_size; /* Logical record size */
Bit32u filesize; /* File Size */
Bit16u date;
Bit16u time;
/* Reserved Block should be 8 bytes */
Bit8u sft_entries;
Bit8u share_attributes;
Bit8u extra_info;
Bit8u file_handle;
Bit8u reserved[4];
/* end */
Bit8u cur_rec; /* Current record in current block */
Bit32u rndm; /* Current relative record number */
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif
};
class DOS_MCB : public MemStruct{
public:
DOS_MCB(Bit16u seg) { SetPt(seg); }
void SetFileName(char const * const _name) { MEM_BlockWrite(pt+offsetof(sMCB,filename),_name,8); }
void GetFileName(char * const _name) { MEM_BlockRead(pt+offsetof(sMCB,filename),_name,8);_name[8]=0;}
void SetType(Bit8u _type) { sSave(sMCB,type,_type);}
void SetSize(Bit16u _size) { sSave(sMCB,size,_size);}
void SetPSPSeg(Bit16u _pspseg) { sSave(sMCB,psp_segment,_pspseg);}
Bit8u GetType(void) { return (Bit8u)sGet(sMCB,type);}
Bit16u GetSize(void) { return (Bit16u)sGet(sMCB,size);}
Bit16u GetPSPSeg(void) { return (Bit16u)sGet(sMCB,psp_segment);}
private:
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct sMCB {
Bit8u type;
Bit16u psp_segment;
Bit16u size;
Bit8u unused[3];
Bit8u filename[8];
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif
};
class DOS_SDA : public MemStruct {
public:
DOS_SDA(Bit16u _seg,Bit16u _offs) { SetPt(_seg,_offs); }
void Init();
void SetDrive(Bit8u _drive) { sSave(sSDA,current_drive, _drive); }
void SetDTA(Bit32u _dta) { sSave(sSDA,current_dta, _dta); }
void SetPSP(Bit16u _psp) { sSave(sSDA,current_psp, _psp); }
Bit8u GetDrive(void) { return (Bit8u)sGet(sSDA,current_drive); }
Bit16u GetPSP(void) { return (Bit16u)sGet(sSDA,current_psp); }
Bit32u GetDTA(void) { return (Bit32u)sGet(sSDA,current_dta); }
private:
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct sSDA {
Bit8u crit_error_flag; /* 0x00 Critical Error Flag */
Bit8u inDOS_flag; /* 0x01 InDOS flag (count of active INT 21 calls) */
Bit8u drive_crit_error; /* 0x02 Drive on which current critical error occurred or FFh */
Bit8u locus_of_last_error; /* 0x03 locus of last error */
Bit16u extended_error_code; /* 0x04 extended error code of last error */
Bit8u suggested_action; /* 0x06 suggested action for last error */
Bit8u error_class; /* 0x07 class of last error*/
Bit32u last_error_pointer; /* 0x08 ES:DI pointer for last error */
Bit32u current_dta; /* 0x0C current DTA (Disk Transfer Address) */
Bit16u current_psp; /* 0x10 current PSP */
Bit16u sp_int_23; /* 0x12 stores SP across an INT 23 */
Bit16u return_code; /* 0x14 return code from last process termination (zerod after reading with AH=4Dh) */
Bit8u current_drive; /* 0x16 current drive */
Bit8u extended_break_flag; /* 0x17 extended break flag */
Bit8u fill[2]; /* 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort*/
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack()
#endif
};
extern DOS_InfoBlock dos_infoblock;
struct DOS_Block {
DOS_Date date;
DOS_Version version;
Bit16u firstMCB;
Bit16u errorcode;
Bit16u psp(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetPSP();};
void psp(Bit16u _seg){ DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetPSP(_seg);};
Bit16u env;
RealPt cpmentry;
RealPt dta(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDTA();};
void dta(RealPt _dta){DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDTA(_dta);};
Bit8u return_code,return_mode;
Bit8u current_drive;
bool verify;
bool breakcheck;
bool echo; // if set to true dev_con::read will echo input
struct {
RealPt mediaid;
RealPt tempdta;
RealPt tempdta_fcbdelete;
RealPt dbcs;
RealPt filenamechar;
RealPt collatingseq;
Bit8u* country;//Will be copied to dos memory. resides in real mem
Bit16u dpb; //Fake Disk parameter system using only the first entry so the drive letter matches
} tables;
Bit16u loaded_codepage;
};
extern DOS_Block dos;
static Bit8u RealHandle(Bit16u handle) {
DOS_PSP psp(dos.psp());
return psp.GetFileHandle(handle);
}
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOS_H_
#define DOS_H_
#include <dos_system.h>
#include <mem.h>
#pragma pack(1)
struct CommandTail{
Bit8u count; /* number of bytes returned */
char buffer[127]; /* the buffer itself */
};
struct PSP {
Bit8u exit[2]; /* CP/M-like exit poimt */
Bit16u mem_size; /* memory size in paragraphs */
Bit8u fill_1; /* single char fill */
/* CPM Stuff dunno what this is*/
//TODO Add some checks for people using this i think
Bit8u far_call; /* far call opcode */
RealPt cpm_entry; /* CPM Service Request address*/
RealPt int_22; /* Terminate Address */
RealPt int_23; /* Break Address */
RealPt int_24; /* Critical Error Address */
Bit16u psp_parent; /* Parent PSP Segment */
Bit8u files[20]; /* File Table - 0xff is unused */
Bit16u environment; /* Segment of evironment table */
RealPt stack; /* SS:SP Save point for int 0x21 calls */
Bit16u max_files; /* Maximum open files */
RealPt file_table; /* Pointer to File Table PSP:0x18 */
RealPt prev_psp; /* Pointer to previous PSP */
RealPt dta; /* Pointer to current Process DTA */
Bit8u fill_2[16]; /* Lot's of unused stuff i can't care aboue */
Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */
Bit8u fill_3[45]; /* This has some blocks with FCB info */
CommandTail cmdtail;
};
struct ParamBlock {
union {
struct {
Bit16u loadseg;
Bit16u relocation;
} overlay;
struct {
Bit16u envseg;
RealPt cmdtail;
RealPt fcb1;
RealPt fcb2;
RealPt initsssp;
RealPt initcsip;
} exec;
};
};
struct MCB {
Bit8u type;
Bit16u psp_segment;
Bit16u size;
Bit8u unused[3];
Bit8u filename[8];
};
struct FCB {
Bit8u drive; //0 is current drive. when opened 0 is replaced by drivenumber
Bit8u filename[8]; //spacepadded to fit
Bit8u ext[3]; //spacepadded to fit
Bit16u current_block; // set to 0 by open
Bit16u record_size; // used by reads Set to 80h by OPEN function
Bit32u filesize; //in bytes In this field, the first word is the low-order part of the size
Bit16u date;
Bit16u time;
Bit8u reserved[8];
Bit8u current_relative_record_number; //open doesn't set this
Bit32u rel_record; //open does not handle this
};
#pragma pack()
struct DOS_Date {
Bit16u year;
Bit8u month;
Bit8u day;
};
struct DOS_Version {
Bit8u major,minor,revision;
};
struct DOS_Block {
DOS_Date date;
DOS_Version version;
Bit16u firstMCB;
Bit16u errorcode;
Bit16u psp;
Bit16u env;
RealPt cpmentry;
RealPt dta;
Bit8u return_code,return_mode;
bool verify;
bool breakcheck;
struct {
RealPt indosflag;
} tables;
};
enum { MCB_FREE=0x0000,MCB_DOS=0x0008 };
enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
#define DOS_FILES 50
#define DOS_DRIVES 26
/* internal Dos Tables */
extern DOS_Block dos;
extern DOS_File * Files[DOS_FILES];
extern DOS_Drive * Drives[DOS_DRIVES];
void DOS_SetError(Bit16u code);
/* File Handling Routines */
enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDNUL=4,STDPRN=5};
enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE};
/* Routines for File Class */
void DOS_SetupFiles (void);
bool DOS_ReadFile(Bit16u handle,Bit8u * data,Bit16u * amount);
bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount);
bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type);
bool DOS_CloseFile(Bit16u handle);
bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry);
/* Routines for Drive Class */
bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry);
bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry);
bool DOS_UnlinkFile(char * name);
bool DOS_FindFirst(char *search,Bit16u attr);
bool DOS_FindNext(void);
bool DOS_Canonicalize(char * small,Bit8u * big);
bool DOS_CreateTempFile(char * name,Bit16u * entry);
bool DOS_FileExists(char * name);
/* Drive Handing Routines */
Bit8u DOS_GetDefaultDrive(void);
void DOS_SetDefaultDrive(Bit8u drive);
bool DOS_SetDrive(Bit8u drive);
bool DOS_GetCurrentDir(Bit8u drive,Bit8u * buffer);
bool DOS_ChangeDir(char * dir);
bool DOS_MakeDir(char * dir);
bool DOS_RemoveDir(char * dir);
bool DOS_Rename(char * oldname,char * newname);
bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free);
bool DOS_GetFileAttr(char * name,Bit16u * attr);
/* IOCTL Stuff */
bool DOS_IOCTL(Bit8u call,Bit16u entry);
bool DOS_GetSTDINStatus();
Bit8u DOS_FindDevice(char * name);
void DOS_SetupDevices(void);
/* Execute and new process creation */
bool DOS_NewPSP(Bit16u pspseg);
bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags);
bool DOS_Terminate(bool tsr);
/* Memory Handling Routines */
void DOS_SetupMemory(void);
bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks);
bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks);
bool DOS_FreeMemory(Bit16u segment);
void DOS_FreeProcessMemory(Bit16u pspseg);
Bit16u DOS_GetMemory(Bit16u pages);
/* Extra DOS Interrupts */
void DOS_SetupMisc(void);
/* The DOS Tables */
void DOS_SetupTables(void);
/* Internal DOS Setup Programs */
void DOS_SetupPrograms(void);
INLINE Bit16u long2para(Bit32u size) {
if (size>0xFFFF0) return 0xffff;
if (size&0xf) return (Bit16u)((size>>4)+1);
else return (Bit16u)(size>>4);
};
INLINE Bit8u RealHandle(Bit16u handle) {
PSP * psp=(PSP *)real_off(dos.psp,0);
if (handle>=psp->max_files) return DOS_FILES;
return mem_readb(Real2Phys(psp->file_table)+handle);
};
/* Dos Error Codes */
#define DOSERR_NONE 0
#define DOSERR_FUNCTION_NUMBER_INVALID 1
#define DOSERR_FILE_NOT_FOUND 2
#define DOSERR_PATH_NOT_FOUND 3
#define DOSERR_TOO_MANY_OPEN_FILES 4
#define DOSERR_ACCESS_DENIED 5
#define DOSERR_INVALID_HANDLE 6
#define DOSERR_MCB_DESTROYED 7
#define DOSERR_INSUFFICIENT_MEMORY 8
#define DOSERR_MB_ADDRESS_INVALID 9
#define DOSERR_ENVIRONMENT_INVALID 10
#define DOSERR_FORMAT_INVALID 11
#define DOSERR_ACCESS_CODE_INVALID 12
#define DOSERR_DATA_INVALID 13
#define DOSERR_RESERVED 14
#define DOSERR_FIXUP_OVERFLOW 14
#define DOSERR_INVALID_DRIVE 15
#define DOSERR_REMOVE_CURRENT_DIRECTORY 16
#define DOSERR_NOT_SAME_DEVICE 17
#define DOSERR_NO_MORE_FILES 18
/* Remains some classes used to access certain things */
class DOS_FCB {
public:
DOS_FCB(PhysPt pt){
off=pt;
}
DOS_FCB(Bit16u seg, Bit16u offset){
off=Real2Phys(RealMake(seg,offset));
}
void Set_drive(Bit8u a);
void Set_filename(char* a); //writes an the first 8 bytes of a as the filename
void Set_ext(char* a);
void Set_current_block(Bit16u a);
void Set_record_size(Bit16u a);
void Set_filesize(Bit32u a);
void Set_date(Bit16u a);
void Set_time(Bit16u a);
// others nog yet handled
Bit8u Get_drive(void);
void Get_filename(char* a);
void Get_ext(char* a);
Bit16u Get_current_block(void);
Bit16u Get_record_size(void);
Bit32u Get_filesize(void);
Bit16u Get_date(void);
Bit16u Get_time(void);
private:
PhysPt off;
};
#endif

View File

@ -1,269 +1,105 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_system.h,v 1.47 2009/03/04 21:08:22 c2woody Exp $ */
#ifndef DOSBOX_DOS_SYSTEM_H
#define DOSBOX_DOS_SYSTEM_H
#include <vector>
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#ifndef DOSBOX_CROSS_H
#include "cross.h"
#endif
#ifndef DOSBOX_SUPPORT_H
#include "support.h"
#endif
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
#define DOS_NAMELENGTH 12
#define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1)
#define DOS_FCBNAME 15
#define DOS_DIRDEPTH 8
#define DOS_PATHLENGTH 80
#define DOS_TEMPSIZE 1024
enum {
DOS_ATTR_READ_ONLY= 0x01,
DOS_ATTR_HIDDEN= 0x02,
DOS_ATTR_SYSTEM= 0x04,
DOS_ATTR_VOLUME= 0x08,
DOS_ATTR_DIRECTORY= 0x10,
DOS_ATTR_ARCHIVE= 0x20,
DOS_ATTR_DEVICE= 0x40
};
struct FileStat_Block {
Bit32u size;
Bit16u time;
Bit16u date;
Bit16u attr;
};
class DOS_DTA;
class DOS_File {
public:
DOS_File():flags(0) { name=0; refCtr = 0; hdrive=0xff; };
DOS_File(const DOS_File& orig);
DOS_File & operator= (const DOS_File & orig);
virtual ~DOS_File(){if(name) delete [] name;};
virtual bool Read(Bit8u * data,Bit16u * size)=0;
virtual bool Write(Bit8u * data,Bit16u * size)=0;
virtual bool Seek(Bit32u * pos,Bit32u type)=0;
virtual bool Close()=0;
virtual Bit16u GetInformation(void)=0;
virtual void SetName(const char* _name) { if (name) delete[] name; name = new char[strlen(_name)+1]; strcpy(name,_name); }
virtual char* GetName(void) { return name; };
virtual bool IsOpen() { return open; };
virtual bool IsName(const char* _name) { if (!name) return false; return strcasecmp(name,_name)==0; };
virtual void AddRef() { refCtr++; };
virtual Bits RemoveRef() { return --refCtr; };
virtual bool UpdateDateTimeFromHost() { return true; }
void SetDrive(Bit8u drv) { hdrive=drv;}
Bit8u GetDrive(void) { return hdrive;}
Bit32u flags;
Bit16u time;
Bit16u date;
Bit16u attr;
Bits refCtr;
bool open;
char* name;
/* Some Device Specific Stuff */
private:
Bit8u hdrive;
};
class DOS_Device : public DOS_File {
public:
DOS_Device(const DOS_Device& orig):DOS_File(orig) {
devnum=orig.devnum;
open=true;
}
DOS_Device & operator= (const DOS_Device & orig) {
DOS_File::operator=(orig);
devnum=orig.devnum;
open=true;
return *this;
}
DOS_Device():DOS_File(),devnum(0){};
virtual bool Read(Bit8u * data,Bit16u * size);
virtual bool Write(Bit8u * data,Bit16u * size);
virtual bool Seek(Bit32u * pos,Bit32u type);
virtual bool Close();
virtual Bit16u GetInformation(void);
virtual bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
virtual bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
void SetDeviceNumber(Bitu num) { devnum=num;}
private:
Bitu devnum;
};
/* The following variable can be lowered to free up some memory.
* The negative side effect: The stored searches will be turned over faster.
* Should not have impact on systems with few directory entries. */
#define MAX_OPENDIRS 2048
//Can be high as it's only storage (16 bit variable)
class DOS_Drive_Cache {
public:
DOS_Drive_Cache (void);
DOS_Drive_Cache (const char* path);
~DOS_Drive_Cache (void);
enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV };
void SetBaseDir (const char* path);
void SetDirSort (TDirSort sort) { sortDirType = sort; };
bool OpenDir (const char* path, Bit16u& id);
bool ReadDir (Bit16u id, char* &result);
void ExpandName (char* path);
char* GetExpandName (const char* path);
bool GetShortName (const char* fullname, char* shortname);
bool FindFirst (char* path, Bitu& id);
bool FindNext (Bitu id, char* &result);
void CacheOut (const char* path, bool ignoreLastDir = false);
void AddEntry (const char* path, bool checkExist = false);
void DeleteEntry (const char* path, bool ignoreLastDir = false);
void EmptyCache (void);
void SetLabel (const char* name,bool cdrom,bool allowupdate);
char* GetLabel (void) { return label; };
class CFileInfo {
public:
CFileInfo(void) {
orgname[0] = shortname[0] = 0;
nextEntry = shortNr = 0;
isDir = false;
}
~CFileInfo(void) {
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
fileList.clear();
longNameList.clear();
};
char orgname [CROSS_LEN];
char shortname [DOS_NAMELENGTH_ASCII];
bool isDir;
Bitu nextEntry;
Bitu shortNr;
// contents
std::vector<CFileInfo*> fileList;
std::vector<CFileInfo*> longNameList;
};
private:
bool RemoveTrailingDot (char* shortname);
Bits GetLongName (CFileInfo* info, char* shortname);
void CreateShortName (CFileInfo* dir, CFileInfo* info);
Bitu CreateShortNameID (CFileInfo* dir, const char* name);
int CompareShortname (const char* compareName, const char* shortName);
bool SetResult (CFileInfo* dir, char * &result, Bitu entryNr);
bool IsCachedIn (CFileInfo* dir);
CFileInfo* FindDirInfo (const char* path, char* expandedPath);
bool RemoveSpaces (char* str);
bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id);
void CreateEntry (CFileInfo* dir, const char* name, bool query_directory);
void CopyEntry (CFileInfo* dir, CFileInfo* from);
Bit16u GetFreeID (CFileInfo* dir);
void Clear (void);
CFileInfo* dirBase;
char dirPath [CROSS_LEN];
char basePath [CROSS_LEN];
bool dirFirstTime;
TDirSort sortDirType;
CFileInfo* save_dir;
char save_path [CROSS_LEN];
char save_expanded [CROSS_LEN];
Bit16u srchNr;
CFileInfo* dirSearch [MAX_OPENDIRS];
char dirSearchName [MAX_OPENDIRS];
bool free [MAX_OPENDIRS];
CFileInfo* dirFindFirst [MAX_OPENDIRS];
Bitu nextFreeFindFirst;
char label [CROSS_LEN];
bool updatelabel;
};
class DOS_Drive {
public:
DOS_Drive();
virtual ~DOS_Drive(){};
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags)=0;
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes)=0;
virtual bool FileUnlink(char * _name)=0;
virtual bool RemoveDir(char * _dir)=0;
virtual bool MakeDir(char * _dir)=0;
virtual bool TestDir(char * _dir)=0;
virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false)=0;
virtual bool FindNext(DOS_DTA & dta)=0;
virtual bool GetFileAttr(char * name,Bit16u * attr)=0;
virtual bool Rename(char * oldname,char * newname)=0;
virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters)=0;
virtual bool FileExists(const char* name)=0;
virtual bool FileStat(const char* name, FileStat_Block * const stat_block)=0;
virtual Bit8u GetMediaByte(void)=0;
virtual void SetDir(const char* path) { strcpy(curdir,path); };
virtual void EmptyCache(void) { dirCache.EmptyCache(); };
virtual bool isRemote(void)=0;
virtual bool isRemovable(void)=0;
virtual Bits UnMount(void)=0;
char * GetInfo(void);
char curdir[DOS_PATHLENGTH];
char info[256];
/* Can be overridden for example in iso images */
virtual char const * GetLabel(){return dirCache.GetLabel();};
DOS_Drive_Cache dirCache;
// disk cycling functionality (request resources)
virtual void Activate(void) {};
};
enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2, DOS_NOT_INHERIT=128};
enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2};
/*
A multiplex handler should read the registers to check what function is being called
If the handler returns false dos will stop checking other handlers
*/
typedef bool (MultiplexHandler)(void);
void DOS_AddMultiplexHandler(MultiplexHandler * handler);
void DOS_DelMultiplexHandler(MultiplexHandler * handler);
/* AddDevice stores the pointer to a created device */
void DOS_AddDevice(DOS_Device * adddev);
/* DelDevice destroys the device that is pointed to. */
void DOS_DelDevice(DOS_Device * dev);
void VFILE_Register(const char * name,Bit8u * data,Bit32u size);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSSYSTEM_H_
#define DOSSYSTEM_H_
#include <dosbox.h>
#define DOS_NAMELENGTH 12
#define DOS_DIRDEPTH 16
#define DOS_PATHLENGTH (DOS_DIRDEPTH+1)*(DOS_NAMELENGTH+2)
#define DOS_TEMPSIZE 1024
enum {
DOS_ATTR_READ_ONLY= 0x01,
DOS_ATTR_HIDDEN= 0x02,
DOS_ATTR_SYSTEM= 0x04,
DOS_ATTR_VOLUME= 0x08,
DOS_ATTR_DIRECTORY= 0x10,
DOS_ATTR_ARCHIVE= 0x20
};
#pragma pack (1)
struct DTA_FindBlock {
Bit8u sdrive; /* The Drive the search is taking place */
Bit16u sattr; /* The attributes that need to be found */
Bit8u fill[18];
Bit8u attr;
Bit16u time;
Bit16u date;
Bit32u size;
char name[DOS_NAMELENGTH];
};
#pragma pack ()
class DOS_File {
public:
virtual bool Read(Bit8u * data,Bit16u * size)=0;
virtual bool Write(Bit8u * data,Bit16u * size)=0;
virtual bool Seek(Bit32u * pos,Bit32u type)=0;
virtual bool Close()=0;
virtual Bit16u GetInformation(void)=0;
Bit8u type;Bit32u flags;
/* Some Device Specific Stuff */
};
class DOS_Device : public DOS_File {
public:
/* Some Device Specific Stuff */
char * name;
Bit8u fhandle;
};
class DOS_Drive {
public:
DOS_Drive();
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags)=0;
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes)=0;
virtual bool FileUnlink(char * name)=0;
virtual bool RemoveDir(char * dir)=0;
virtual bool MakeDir(char * dir)=0;
virtual bool TestDir(char * dir)=0;
virtual bool FindFirst(char * search,DTA_FindBlock * dta)=0;
virtual bool FindNext(DTA_FindBlock * dta)=0;
virtual bool GetFileAttr(char * name,Bit16u * attr)=0;
virtual bool Rename(char * oldname,char * newname)=0;
virtual bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free)=0;
char * GetInfo(void);
char curdir[DOS_PATHLENGTH];
char info[256];
};
enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2 };
enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2};
/*
A multiplex handler should read the registers to check what function is being called
If the handler returns false dos will stop checking other handlers
*/
typedef bool (MultiplexHandler)(void);
void DOS_AddMultiplexHandler(MultiplexHandler * handler);
void DOS_AddDevice(DOS_Device * adddev);
void VFILE_Register(char * name,Bit8u * data,Bit32u size);
#endif

View File

@ -1,76 +1,63 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dosbox.h,v 1.31 2008/01/09 20:34:21 c2woody Exp $ */
#ifndef DOSBOX_DOSBOX_H
#define DOSBOX_DOSBOX_H
#include "config.h"
void E_Exit(const char * message,...) GCC_ATTRIBUTE( __format__(__printf__, 1, 2));
void MSG_Add(const char*,const char*); //add messages to the internal langaugefile
const char* MSG_Get(char const *); //get messages from the internal langaugafile
class Section;
typedef Bitu (LoopHandler)(void);
void DOSBOX_RunMachine();
void DOSBOX_SetLoop(LoopHandler * handler);
void DOSBOX_SetNormalLoop();
void DOSBOX_Init(void);
class Config;
extern Config * control;
enum MachineType {
MCH_HERC,
MCH_CGA,
MCH_TANDY,
MCH_PCJR,
MCH_EGA,
MCH_VGA
};
enum SVGACards {
SVGA_None,
SVGA_S3Trio,
SVGA_TsengET4K,
SVGA_TsengET3K,
SVGA_ParadisePVGA1A
};
extern SVGACards svgaCard;
extern MachineType machine;
extern bool SDLNetInited;
#define IS_TANDY_ARCH ((machine==MCH_TANDY) || (machine==MCH_PCJR))
#define IS_EGAVGA_ARCH ((machine==MCH_EGA) || (machine==MCH_VGA))
#define IS_VGA_ARCH (machine==MCH_VGA)
#define TANDY_ARCH_CASE MCH_TANDY: case MCH_PCJR
#define EGAVGA_ARCH_CASE MCH_EGA: case MCH_VGA
#define VGA_ARCH_CASE MCH_VGA
#ifndef DOSBOX_LOGGING_H
#include "logging.h"
#endif // the logging system.
#endif /* DOSBOX_DOSBOX_H */
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined __DOSBOX_H
#define __DOSBOX_H
typedef unsigned char Bit8u;
typedef signed char Bit8s;
typedef unsigned short Bit16u;
typedef signed short Bit16s;
typedef unsigned long Bit32u;
typedef signed long Bit32s;
#if defined(_MSC_VER)
typedef unsigned __int64 Bit64u;
typedef signed __int64 Bit64s;
#else
typedef unsigned long long int Bit64u;
typedef signed long long int Bit64s;
#endif
typedef unsigned int Bitu;
typedef signed int Bits;
#include <stddef.h>
void E_Exit(char * message,...);
void S_Warn(char * message,...);
#include "../settings.h" /* General extra setting */
#if defined (_MSC_VER)
#include "../src/platform/visualc/config.h"
#else
#include "../config.h"
#define INLINE inline
#endif
typedef Bitu (LoopHandler)(void);
void DOSBOX_RunMachine();
void DOSBOX_SetLoop(LoopHandler * handler);
void DOSBOX_Init(int argc, char* argv[]);
void DOSBOX_StartUp(void);
#endif

View File

@ -1,154 +1 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_FPU_H
#define DOSBOX_FPU_H
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
void FPU_ESC0_Normal(Bitu rm);
void FPU_ESC0_EA(Bitu func,PhysPt ea);
void FPU_ESC1_Normal(Bitu rm);
void FPU_ESC1_EA(Bitu func,PhysPt ea);
void FPU_ESC2_Normal(Bitu rm);
void FPU_ESC2_EA(Bitu func,PhysPt ea);
void FPU_ESC3_Normal(Bitu rm);
void FPU_ESC3_EA(Bitu func,PhysPt ea);
void FPU_ESC4_Normal(Bitu rm);
void FPU_ESC4_EA(Bitu func,PhysPt ea);
void FPU_ESC5_Normal(Bitu rm);
void FPU_ESC5_EA(Bitu func,PhysPt ea);
void FPU_ESC6_Normal(Bitu rm);
void FPU_ESC6_EA(Bitu func,PhysPt ea);
void FPU_ESC7_Normal(Bitu rm);
void FPU_ESC7_EA(Bitu func,PhysPt ea);
typedef union {
double d;
#ifndef WORDS_BIGENDIAN
struct {
Bit32u lower;
Bit32s upper;
} l;
#else
struct {
Bit32s upper;
Bit32u lower;
} l;
#endif
Bit64s ll;
} FPU_Reg;
typedef struct {
Bit32u m1;
Bit32u m2;
Bit16u m3;
Bit16u d1;
Bit32u d2;
} FPU_P_Reg;
enum FPU_Tag {
TAG_Valid = 0,
TAG_Zero = 1,
TAG_Weird = 2,
TAG_Empty = 3
};
enum FPU_Round {
ROUND_Nearest = 0,
ROUND_Down = 1,
ROUND_Up = 2,
ROUND_Chop = 3
};
typedef struct {
FPU_Reg regs[9];
FPU_P_Reg p_regs[9];
FPU_Tag tags[9];
Bit16u cw,cw_mask_all;
Bit16u sw;
Bitu top;
FPU_Round round;
} FPU_rec;
//get pi from a real library
#define PI 3.14159265358979323846
#define L2E 1.4426950408889634
#define L2T 3.3219280948873623
#define LN2 0.69314718055994531
#define LG2 0.3010299956639812
extern FPU_rec fpu;
#define TOP fpu.top
#define STV(i) ( (fpu.top+ (i) ) & 7 )
Bit16u FPU_GetTag(void);
void FPU_FLDCW(PhysPt addr);
static INLINE void FPU_SetTag(Bit16u tag){
for(Bitu i=0;i<8;i++)
fpu.tags[i] = static_cast<FPU_Tag>((tag >>(2*i))&3);
}
static INLINE void FPU_SetCW(Bitu word){
fpu.cw = (Bit16u)word;
fpu.cw_mask_all = (Bit16u)(word | 0x3f);
fpu.round = (FPU_Round)((word >> 10) & 3);
}
static INLINE Bitu FPU_GET_TOP(void) {
return (fpu.sw & 0x3800)>>11;
}
static INLINE void FPU_SET_TOP(Bitu val){
fpu.sw &= ~0x3800;
fpu.sw |= (val&7)<<11;
}
static INLINE void FPU_SET_C0(Bitu C){
fpu.sw &= ~0x0100;
if(C) fpu.sw |= 0x0100;
}
static INLINE void FPU_SET_C1(Bitu C){
fpu.sw &= ~0x0200;
if(C) fpu.sw |= 0x0200;
}
static INLINE void FPU_SET_C2(Bitu C){
fpu.sw &= ~0x0400;
if(C) fpu.sw |= 0x0400;
}
static INLINE void FPU_SET_C3(Bitu C){
fpu.sw &= ~0x4000;
if(C) fpu.sw |= 0x4000;
}
#endif

View File

@ -1,50 +1,44 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_HARDWARE_H
#define DOSBOX_HARDWARE_H
#include <stdio.h>
class Section;
enum OPL_Mode {
OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3
};
#define CAPTURE_WAVE 0x01
#define CAPTURE_OPL 0x02
#define CAPTURE_MIDI 0x04
#define CAPTURE_IMAGE 0x08
#define CAPTURE_VIDEO 0x10
extern Bitu CaptureState;
void OPL_Init(Section* sec,OPL_Mode mode);
void CMS_Init(Section* sec);
void OPL_ShutDown(Section* sec);
void CMS_ShutDown(Section* sec);
extern Bit8u adlib_commandreg;
FILE * OpenCaptureFile(const char * type,const char * ext);
void CAPTURE_AddWave(Bit32u freq, Bit32u len, Bit16s * data);
#define CAPTURE_FLAG_DBLW 0x1
#define CAPTURE_FLAG_DBLH 0x2
void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, Bit8u * data, Bit8u * pal);
void CAPTURE_AddMidi(bool sysex, Bitu len, Bit8u * data);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _HARDWARE_H_
#define _HARDWARE_H_
#include <programs.h>
#include <support.h>
#include <stdio.h>
typedef void (* HW_OutputHandler)(char * towrite);
typedef void (* HW_InputHandler)(char * line);
struct HWBlock {
char * dev_name; /* 8 characters max dev name */
char * full_name; /* 60 characters full name */
char * help;
HW_InputHandler get_input;
HW_OutputHandler show_status; /* Supplied with a string to display 50 chars of status info in */
HWBlock * next;
};
void HW_Register(HWBlock * block);
#endif

View File

@ -1,78 +1,48 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: inout.h,v 1.12 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_INOUT_H
#define DOSBOX_INOUT_H
#define IO_MAX (64*1024+3)
#define IO_MB 0x1
#define IO_MW 0x2
#define IO_MD 0x4
#define IO_MA (IO_MB | IO_MW | IO_MD )
typedef Bitu IO_ReadHandler(Bitu port,Bitu iolen);
typedef void IO_WriteHandler(Bitu port,Bitu val,Bitu iolen);
extern IO_WriteHandler * io_writehandlers[3][IO_MAX];
extern IO_ReadHandler * io_readhandlers[3][IO_MAX];
void IO_RegisterReadHandler(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1);
void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1);
void IO_FreeReadHandler(Bitu port,Bitu mask,Bitu range=1);
void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=1);
void IO_WriteB(Bitu port,Bitu val);
void IO_WriteW(Bitu port,Bitu val);
void IO_WriteD(Bitu port,Bitu val);
Bitu IO_ReadB(Bitu port);
Bitu IO_ReadW(Bitu port);
Bitu IO_ReadD(Bitu port);
/* Classes to manage the IO objects created by the various devices.
* The io objects will remove itself on destruction.*/
class IO_Base{
protected:
bool installed;
Bitu m_port, m_mask,m_range;
public:
IO_Base():installed(false){};
};
class IO_ReadHandleObject: private IO_Base{
public:
void Install(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1);
~IO_ReadHandleObject();
};
class IO_WriteHandleObject: private IO_Base{
public:
void Install(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1);
~IO_WriteHandleObject();
};
static INLINE void IO_Write(Bitu port,Bit8u val) {
IO_WriteB(port,val);
}
static INLINE Bit8u IO_Read(Bitu port){
return (Bit8u)IO_ReadB(port);
}
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
typedef Bit8u (IO_ReadHandler)(Bit32u port);
typedef void (IO_WriteHandler)(Bit32u port,Bit8u value);
#define IO_MAX 1024
struct IO_ReadBlock{
IO_ReadHandler * handler;
char * name;
};
struct IO_WriteBlock{
IO_WriteHandler * handler;
char * name;
};
extern IO_ReadBlock IO_ReadTable[IO_MAX];
extern IO_WriteBlock IO_WriteTable[IO_MAX];
void IO_Write(Bitu num,Bit8u val);
Bit8u IO_Read(Bitu num);
void IO_RegisterReadHandler(Bit32u port,IO_ReadHandler * handler,char * name);
void IO_RegisterWriteHandler(Bit32u port,IO_WriteHandler * handler,char * name);
void IO_FreeReadHandler(Bit32u port);
void IO_FreeWriteHandler(Bit32u port);

View File

@ -1,161 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: ipx.h,v 1.12 2007/01/13 08:35:49 qbix79 Exp $ */
#ifndef DOSBOX_IPX_H
#define DOSBOX_IPX_H
// Uncomment this for a lot of debug messages:
//#define IPX_DEBUGMSG
#ifdef IPX_DEBUGMSG
#define LOG_IPX LOG_MSG
#else
#if defined (_MSC_VER)
#define LOG_IPX
#else
#define LOG_IPX(...)
#endif
#endif
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
// In Use Flag codes
#define USEFLAG_AVAILABLE 0x00
#define USEFLAG_AESTEMP 0xe0
#define USEFLAG_IPXCRIT 0xf8
#define USEFLAG_SPXLISTEN 0xf9
#define USEFLAG_PROCESSING 0xfa
#define USEFLAG_HOLDING 0xfb
#define USEFLAG_AESWAITING 0xfc
#define USEFLAG_AESCOUNT 0xfd
#define USEFLAG_LISTENING 0xfe
#define USEFLAG_SENDING 0xff
// Completion codes
#define COMP_SUCCESS 0x00
#define COMP_REMOTETERM 0xec
#define COMP_DISCONNECT 0xed
#define COMP_INVALIDID 0xee
#define COMP_SPXTABLEFULL 0xef
#define COMP_EVENTNOTCANCELED 0xf9
#define COMP_NOCONNECTION 0xfa
#define COMP_CANCELLED 0xfc
#define COMP_MALFORMED 0xfd
#define COMP_UNDELIVERABLE 0xfe
#define COMP_HARDWAREERROR 0xff
#ifdef _MSC_VER
#pragma pack(1)
#endif
// For Uint8 type
#include "SDL_net.h"
struct PackedIP {
Uint32 host;
Uint16 port;
} GCC_ATTRIBUTE(packed);
struct nodeType {
Uint8 node[6];
} GCC_ATTRIBUTE(packed) ;
struct IPXHeader {
Uint8 checkSum[2];
Uint8 length[2];
Uint8 transControl; // Transport control
Uint8 pType; // Packet type
struct transport {
Uint8 network[4];
union addrtype {
nodeType byNode;
PackedIP byIP ;
} GCC_ATTRIBUTE(packed) addr;
Uint8 socket[2];
} dest, src;
} GCC_ATTRIBUTE(packed);
struct fragmentDescriptor {
Bit16u offset;
Bit16u segment;
Bit16u size;
};
#define IPXBUFFERSIZE 1424
class ECBClass {
public:
RealPt ECBAddr;
bool isInESRList;
ECBClass *prevECB; // Linked List
ECBClass *nextECB;
Bit8u iuflag; // Need to save data since we are not always in
Bit16u mysocket; // real mode
Bit8u* databuffer; // received data is stored here until we get called
Bitu buflen; // by Interrupt
#ifdef IPX_DEBUGMSG
Bitu SerialNumber;
#endif
ECBClass(Bit16u segment, Bit16u offset);
Bit16u getSocket(void);
Bit8u getInUseFlag(void);
void setInUseFlag(Bit8u flagval);
void setCompletionFlag(Bit8u flagval);
Bit16u getFragCount(void);
bool writeData();
void writeDataBuffer(Bit8u* buffer, Bit16u length);
void getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc);
RealPt getESRAddr(void);
void NotifyESR(void);
void setImmAddress(Bit8u *immAddr);
void getImmAddress(Bit8u* immAddr);
~ECBClass();
};
// The following routines may not be needed on all systems. On my build of SDL the IPaddress structure is 8 octects
// and therefore screws up my IPXheader structure since it needs to be packed.
void UnpackIP(PackedIP ipPack, IPaddress * ipAddr);
void PackIP(IPaddress ipAddr, PackedIP *ipPack);
#ifdef _MSC_VER
#pragma pack()
#endif
#endif

View File

@ -1,48 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_IPXSERVER_H_
#define DOSBOX_IPXSERVER_H_
#if C_IPX
#include "SDL_net.h"
struct packetBuffer {
Bit8u buffer[1024];
Bit16s packetSize; // Packet size remaining in read
Bit16s packetRead; // Bytes read of total packet
bool inPacket; // In packet reception flag
bool connected; // Connected flag
bool waitsize;
};
#define SOCKETTABLESIZE 16
#define CONVIP(hostvar) hostvar & 0xff, (hostvar >> 8) & 0xff, (hostvar >> 16) & 0xff, (hostvar >> 24) & 0xff
#define CONVIPX(hostvar) hostvar[0], hostvar[1], hostvar[2], hostvar[3], hostvar[4], hostvar[5]
void IPX_StopServer();
bool IPX_StartServer(Bit16u portnum);
bool IPX_isConnectedToServer(Bits tableNum, IPaddress ** ptrAddr);
Bit8u packetCRC(Bit8u *buffer, Bit16u bufSize);
#endif
#endif

View File

@ -1,50 +1,25 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: joystick.h,v 1.12 2007/08/12 10:23:35 c2woody Exp $ */
#ifndef DOSBOX_JOYSTICK_H
#define DOSBOX_JOYSTICK_H
void JOYSTICK_Enable(Bitu which,bool enabled);
void JOYSTICK_Button(Bitu which,Bitu num,bool pressed);
void JOYSTICK_Move_X(Bitu which,float x);
void JOYSTICK_Move_Y(Bitu which,float y);
bool JOYSTICK_IsEnabled(Bitu which);
bool JOYSTICK_GetButton(Bitu which, Bitu num);
float JOYSTICK_GetMove_X(Bitu which);
float JOYSTICK_GetMove_Y(Bitu which);
enum JoystickType {
JOY_NONE,
JOY_AUTO,
JOY_2AXIS,
JOY_4AXIS,
JOY_4AXIS_2,
JOY_FCS,
JOY_CH
};
extern JoystickType joytype;
extern bool button_wrapping_enabled;
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
void JOYSTICK_Enable(Bitu which,bool enabled);
void JOYSTICK_Button(Bitu which,Bitu num,bool pressed);
void JOYSTICK_Move_X(Bitu which,float x);
void JOYSTICK_Move_Y(Bitu which,float y);

View File

@ -1,53 +1,54 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_KEYBOARD_H
#define DOSBOX_KEYBOARD_H
enum KBD_KEYS {
KBD_NONE,
KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0,
KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p,
KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z,
KBD_x, KBD_c, KBD_v, KBD_b, KBD_n, KBD_m,
KBD_f1, KBD_f2, KBD_f3, KBD_f4, KBD_f5, KBD_f6, KBD_f7, KBD_f8, KBD_f9, KBD_f10,KBD_f11,KBD_f12,
/*Now the weirder keys */
KBD_esc,KBD_tab,KBD_backspace,KBD_enter,KBD_space,
KBD_leftalt,KBD_rightalt,KBD_leftctrl,KBD_rightctrl,KBD_leftshift,KBD_rightshift,
KBD_capslock,KBD_scrolllock,KBD_numlock,
KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket,
KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash,KBD_extra_lt_gt,
KBD_printscreen,KBD_pause,
KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown,
KBD_left,KBD_up,KBD_down,KBD_right,
KBD_kp1,KBD_kp2,KBD_kp3,KBD_kp4,KBD_kp5,KBD_kp6,KBD_kp7,KBD_kp8,KBD_kp9,KBD_kp0,
KBD_kpdivide,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod,
KBD_LAST
};
void KEYBOARD_ClrBuffer(void);
void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
typedef void(KEYBOARD_EventHandler)(void);
void KEYBOARD_AddCode(Bit8u code);
void KEYBOARD_AddKey(Bitu keytype,bool pressed);
void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler);
#define ALT_PRESSED 0x1
#define CTRL_PRESSED 0x2
#define SHIFT_PRESSED 0x4
enum {
KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0,
KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p,
KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z,
KBD_x, KBD_c, KBD_v, KBD_b, KBD_n, KBD_m,
KBD_f1, KBD_f2, KBD_f3, KBD_f4, KBD_f5, KBD_f6, KBD_f7, KBD_f8, KBD_f9, KBD_f10,KBD_f11,KBD_f12,
/*Now the weirder keys */
KBD_esc,KBD_tab,KBD_backspace,KBD_enter,KBD_space,
KBD_leftalt,KBD_rightalt,KBD_leftctrl,KBD_rightctrl,KBD_leftshift,KBD_rightshift,
KBD_capslock,KBD_scrolllock,KBD_numlock,
KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket,
KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash,
KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown,
KBD_left,KBD_up,KBD_down,KBD_right,
KBD_kp1,KBD_kp2,KBD_kp3,KBD_kp4,KBD_kp5,KBD_kp6,KBD_kp7,KBD_kp8,KBD_kp9,KBD_kp0,
KBD_kpslash,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod,
KBD_LAST
};

View File

@ -1,67 +0,0 @@
#ifndef DOSBOX_LOGGING_H
#define DOSBOX_LOGGING_H
enum LOG_TYPES {
LOG_ALL,
LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10,
LOG_SB,LOG_DMACONTROL,
LOG_FPU,LOG_CPU,LOG_PAGING,
LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC,
LOG_PIT,LOG_KEYBOARD,LOG_PIC,
LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC,
LOG_IO,
LOG_MAX
};
enum LOG_SEVERITIES {
LOG_NORMAL,
LOG_WARN,
LOG_ERROR
};
#if C_DEBUG
class LOG
{
LOG_TYPES d_type;
LOG_SEVERITIES d_severity;
public:
LOG (LOG_TYPES type , LOG_SEVERITIES severity):
d_type(type),
d_severity(severity)
{}
void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_gui.cpp
};
void DEBUG_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2));
#define LOG_MSG DEBUG_ShowMsg
#else //C_DEBUG
struct LOG
{
LOG(LOG_TYPES , LOG_SEVERITIES ) { }
void operator()(char const* ) { }
void operator()(char const* , double ) { }
void operator()(char const* , double , double ) { }
void operator()(char const* , double , double , double ) { }
void operator()(char const* , double , double , double , double ) { }
void operator()(char const* , double , double , double , double , double ) { }
void operator()(char const* , char const* ) { }
void operator()(char const* , char const* , double ) { }
void operator()(char const* , char const* , double ,double ) { }
void operator()(char const* , double , char const* ) { }
void operator()(char const* , double , double, char const* ) { }
void operator()(char const* , char const*, char const*) { }
}; //add missing operators to here
//try to avoid anything smaller than bit32...
void GFX_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2));
#define LOG_MSG GFX_ShowMsg
#endif //C_DEBUG
#endif //DOSBOX_LOGGING_H

View File

@ -1,39 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_MAPPER_H
#define DOSBOX_MAPPER_H
enum MapKeys {
MK_f1,MK_f2,MK_f3,MK_f4,MK_f5,MK_f6,MK_f7,MK_f8,MK_f9,MK_f10,MK_f11,MK_f12,
MK_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause
};
typedef void (MAPPER_Handler)(bool pressed);
void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const * const eventname,char const * const buttonname);
void MAPPER_Init(void);
void MAPPER_StartUp(Section * sec);
void MAPPER_Run(bool pressed);
void MAPPER_LosingFocus(void);
#define MMOD1 0x1
#define MMOD2 0x2
#endif

View File

@ -1,219 +1,208 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_MEM_H
#define DOSBOX_MEM_H
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
typedef Bit32u PhysPt;
typedef Bit8u * HostPt;
typedef Bit32u RealPt;
typedef Bit32s MemHandle;
#define MEM_PAGESIZE 4096
extern HostPt MemBase;
HostPt GetMemBase(void);
bool MEM_A20_Enabled(void);
void MEM_A20_Enable(bool enable);
/* Memory management / EMS mapping */
HostPt MEM_GetBlockPage(void);
Bitu MEM_FreeTotal(void); //Free 4 kb pages
Bitu MEM_FreeLargest(void); //Largest free 4 kb pages block
Bitu MEM_TotalPages(void); //Total amount of 4 kb pages
Bitu MEM_AllocatedPages(MemHandle handle); // amount of allocated pages of handle
MemHandle MEM_AllocatePages(Bitu pages,bool sequence);
MemHandle MEM_GetNextFreePage(void);
PhysPt MEM_AllocatePage(void);
void MEM_ReleasePages(MemHandle handle);
bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence);
MemHandle MEM_NextHandle(MemHandle handle);
MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where);
/*
The folowing six functions are used everywhere in the end so these should be changed for
Working on big or little endian machines
*/
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
static INLINE Bit8u host_readb(HostPt off) {
return off[0];
}
static INLINE Bit16u host_readw(HostPt off) {
return off[0] | (off[1] << 8);
}
static INLINE Bit32u host_readd(HostPt off) {
return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24);
}
static INLINE void host_writeb(HostPt off,Bit8u val) {
off[0]=val;
}
static INLINE void host_writew(HostPt off,Bit16u val) {
off[0]=(Bit8u)(val);
off[1]=(Bit8u)(val >> 8);
}
static INLINE void host_writed(HostPt off,Bit32u val) {
off[0]=(Bit8u)(val);
off[1]=(Bit8u)(val >> 8);
off[2]=(Bit8u)(val >> 16);
off[3]=(Bit8u)(val >> 24);
}
#else
static INLINE Bit8u host_readb(HostPt off) {
return *(Bit8u *)off;
}
static INLINE Bit16u host_readw(HostPt off) {
return *(Bit16u *)off;
}
static INLINE Bit32u host_readd(HostPt off) {
return *(Bit32u *)off;
}
static INLINE void host_writeb(HostPt off,Bit8u val) {
*(Bit8u *)(off)=val;
}
static INLINE void host_writew(HostPt off,Bit16u val) {
*(Bit16u *)(off)=val;
}
static INLINE void host_writed(HostPt off,Bit32u val) {
*(Bit32u *)(off)=val;
}
#endif
static INLINE void var_write(Bit8u * var, Bit8u val) {
host_writeb((HostPt)var, val);
}
static INLINE void var_write(Bit16u * var, Bit16u val) {
host_writew((HostPt)var, val);
}
static INLINE void var_write(Bit32u * var, Bit32u val) {
host_writed((HostPt)var, val);
}
/* The Folowing six functions are slower but they recognize the paged memory system */
Bit8u mem_readb(PhysPt pt);
Bit16u mem_readw(PhysPt pt);
Bit32u mem_readd(PhysPt pt);
void mem_writeb(PhysPt pt,Bit8u val);
void mem_writew(PhysPt pt,Bit16u val);
void mem_writed(PhysPt pt,Bit32u val);
static INLINE void phys_writeb(PhysPt addr,Bit8u val) {
host_writeb(MemBase+addr,val);
}
static INLINE void phys_writew(PhysPt addr,Bit16u val){
host_writew(MemBase+addr,val);
}
static INLINE void phys_writed(PhysPt addr,Bit32u val){
host_writed(MemBase+addr,val);
}
static INLINE Bit8u phys_readb(PhysPt addr) {
return host_readb(MemBase+addr);
}
static INLINE Bit16u phys_readw(PhysPt addr){
return host_readw(MemBase+addr);
}
static INLINE Bit32u phys_readd(PhysPt addr){
return host_readd(MemBase+addr);
}
/* These don't check for alignment, better be sure it's correct */
void MEM_BlockWrite(PhysPt pt,void const * const data,Bitu size);
void MEM_BlockRead(PhysPt pt,void * data,Bitu size);
void MEM_BlockCopy(PhysPt dest,PhysPt src,Bitu size);
void MEM_StrCopy(PhysPt pt,char * data,Bitu size);
void mem_memcpy(PhysPt dest,PhysPt src,Bitu size);
Bitu mem_strlen(PhysPt pt);
void mem_strcpy(PhysPt dest,PhysPt src);
/* The folowing functions are all shortcuts to the above functions using physical addressing */
static INLINE Bit8u real_readb(Bit16u seg,Bit16u off) {
return mem_readb((seg<<4)+off);
}
static INLINE Bit16u real_readw(Bit16u seg,Bit16u off) {
return mem_readw((seg<<4)+off);
}
static INLINE Bit32u real_readd(Bit16u seg,Bit16u off) {
return mem_readd((seg<<4)+off);
}
static INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) {
mem_writeb(((seg<<4)+off),val);
}
static INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) {
mem_writew(((seg<<4)+off),val);
}
static INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) {
mem_writed(((seg<<4)+off),val);
}
static INLINE Bit16u RealSeg(RealPt pt) {
return (Bit16u)(pt>>16);
}
static INLINE Bit16u RealOff(RealPt pt) {
return (Bit16u)(pt&0xffff);
}
static INLINE PhysPt Real2Phys(RealPt pt) {
return (RealSeg(pt)<<4) +RealOff(pt);
}
static INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) {
return (seg<<4)+off;
}
static INLINE RealPt RealMake(Bit16u seg,Bit16u off) {
return (seg<<16)+off;
}
static INLINE void RealSetVec(Bit8u vec,RealPt pt) {
mem_writed(vec<<2,pt);
}
static INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) {
old = mem_readd(vec<<2);
mem_writed(vec<<2,pt);
}
static INLINE RealPt RealGetVec(Bit8u vec) {
return mem_readd(vec<<2);
}
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined __MEM_H
#define __MEM_H
#include <dosbox.h>
enum { MEMORY_HANDLER=1,MEMORY_RELOCATE=2};
#define bmemcpy(mem1,mem2,size) memcpy((void *)mem1,(void *)mem2,size)
typedef Bit8u (MEMORY_ReadHandler)(Bit32u start);
typedef void (MEMORY_WriteHandler)(Bit32u start,Bit8u val);
typedef Bit32u PhysOff;
typedef Bit32u PhysPt;
typedef Bit8u * HostOff;
typedef Bit8u * HostPt;
typedef Bit32u RealPt;
struct PageEntry {
Bit8u type;
PhysOff base; /* Used to calculate relative offset */
struct {
MEMORY_WriteHandler * write;
MEMORY_ReadHandler * read;
} handler;
HostOff relocate; /* This points to host machine address */
};
struct EMM_Handle {
Bit16u next;
Bit16u size; /* Size in pages */
PhysOff phys_base;
HostOff host_base;
bool active;
bool free;
};
INLINE Bit16u PAGES(Bit32u bytes) {
if ((bytes & 4095) == 0) return (Bit16u)(bytes>>12);
return (Bit16u)(1+(bytes>>12));
}
extern Bit8u * memory;
extern EMM_Handle EMM_Handles[];
extern PageEntry * PageEntries[]; /* Number of pages */
bool MEMORY_TestSpecial(PhysOff off);
void MEMORY_SetupHandler(Bit32u page,Bit32u extra,PageEntry * handler);
void MEMORY_ResetHandler(Bit32u page,Bit32u pages);
void EMM_GetFree(Bit16u * maxblock,Bit16u * total);
void EMM_Allocate(Bit16u size,Bit16u * handle);
void EMM_Free(Bit16u handle);
/*
The folowing six functions are used everywhere in the end so these should be changed for
Working on big or little endian machines
*/
INLINE Bit8u readb(HostOff off) {
return *(Bit8u *)off;
};
INLINE Bit16u readw(HostOff off) {
return *(Bit16u *)off;
};
INLINE Bit32u readd(HostOff off) {
return *(Bit32u *)off;
};
INLINE void writeb(HostOff off,Bit8u val) {
*(Bit8u *)(off)=val;
};
INLINE void writew(HostOff off,Bit16u val) {
*(Bit16u *)(off)=val;
};
INLINE void writed(HostOff off,Bit32u val) {
*(Bit32u *)(off)=val;
};
/* The Folowing six functions are slower but they recognize the paged memory system */
//TODO maybe make em inline to go a bit faster
Bit8u mem_readb(PhysOff off);
Bit16u mem_readw(PhysOff off);
Bit32u mem_readd(PhysOff off);
void mem_writeb(PhysOff off,Bit8u val);
void mem_writew(PhysOff off,Bit16u val);
void mem_writed(PhysOff off,Bit32u val);
void MEM_BlockWrite(PhysOff off,void * data,Bitu size);
void MEM_BlockRead(PhysOff off,void * data,Bitu size);
void MEM_BlockCopy(PhysOff dest,PhysOff src,Bitu size);
void MEM_StrCopy(PhysOff off,char * data,Bitu size);
/* The folowing functions are all shortcuts to the above functions using physical addressing */
INLINE HostOff real_off(Bit16u seg,Bit32u off) {
return memory+(seg<<4)+off;
};
INLINE HostOff real_host(Bit16u seg,Bit32u off) {
return memory+(seg<<4)+off;
};
INLINE PhysOff real_phys(Bit16u seg,Bit32u off) {
return (seg<<4)+off;
};
INLINE Bit8u real_readb(Bit16u seg,Bit16u off) {
return mem_readb((seg<<4)+off);
}
INLINE Bit16u real_readw(Bit16u seg,Bit16u off) {
return mem_readw((seg<<4)+off);
}
INLINE Bit32u real_readd(Bit16u seg,Bit16u off) {
return mem_readd((seg<<4)+off);
}
//#define real_readb(seg,off) mem_readb(((seg)<<4)+(off))
//#define real_readw(seg,off) mem_readw(((seg)<<4)+(off))
//#define real_readd(seg,off) mem_readd(((seg)<<4)+(off))
INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) {
mem_writeb(((seg<<4)+off),val);
}
INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) {
mem_writew(((seg<<4)+off),val);
}
INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) {
mem_writed(((seg<<4)+off),val);
}
//#define real_writeb(seg,off,val) mem_writeb((((seg)<<4)+(off)),val)
//#define real_writew(seg,off,val) mem_writew((((seg)<<4)+(off)),val)
//#define real_writed(seg,off,val) mem_writed((((seg)<<4)+(off)),val)
inline Bit32u real_getvec(Bit8u num) {
return real_readd(0,(num<<2));
}
/*
inline void real_setvec(Bit8u num,Bit32u addr) {
real_writed(0,(num<<2),addr);
};
*/
INLINE Bit16u RealSeg(RealPt pt) {
return (Bit16u)(pt>>16);
}
INLINE Bit16u RealOff(RealPt pt) {
return (Bit16u)(pt&0xffff);
}
INLINE PhysPt Real2Phys(RealPt pt) {
return (RealSeg(pt)<<4) +RealOff(pt);
}
INLINE HostPt Real2Host(RealPt pt) {
return memory+(RealSeg(pt)<<4) +RealOff(pt);
}
INLINE RealPt RealMake(Bit16u seg,Bit16u off) {
return (seg<<16)+off;
}
INLINE void RealSetVec(Bit8u vec,RealPt pt) {
mem_writed(vec<<2,pt);
}
INLINE RealPt RealGetVec(Bit8u vec) {
return mem_readd(vec<<2);
}
#endif

View File

@ -1,114 +1,42 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: mixer.h,v 1.19 2009/04/28 21:48:24 harekiet Exp $ */
#ifndef DOSBOX_MIXER_H
#define DOSBOX_MIXER_H
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
typedef void (*MIXER_Handler)(Bitu len);
enum BlahModes {
MIXER_8MONO,MIXER_8STEREO,
MIXER_16MONO,MIXER_16STEREO
};
enum MixerModes {
M_8M,M_8S,
M_16M,M_16S
};
#define MIXER_BUFSIZE (16*1024)
#define MIXER_BUFMASK (MIXER_BUFSIZE-1)
extern Bit8u MixTemp[MIXER_BUFSIZE];
#define MAX_AUDIO ((1<<(16-1))-1)
#define MIN_AUDIO -(1<<(16-1))
class MixerChannel {
public:
void SetVolume(float _left,float _right);
void SetScale( float f );
void UpdateVolume(void);
void SetFreq(Bitu _freq);
void Mix(Bitu _needed);
void AddSilence(void); //Fill up until needed
template<class Type,bool stereo,bool signeddata,bool nativeorder>
void AddSamples(Bitu len, const Type* data);
void AddSamples_m8(Bitu len, const Bit8u * data);
void AddSamples_s8(Bitu len, const Bit8u * data);
void AddSamples_m8s(Bitu len, const Bit8s * data);
void AddSamples_s8s(Bitu len, const Bit8s * data);
void AddSamples_m16(Bitu len, const Bit16s * data);
void AddSamples_s16(Bitu len, const Bit16s * data);
void AddSamples_m16u(Bitu len, const Bit16u * data);
void AddSamples_s16u(Bitu len, const Bit16u * data);
void AddSamples_m32(Bitu len, const Bit32s * data);
void AddSamples_s32(Bitu len, const Bit32s * data);
void AddSamples_m16_nonnative(Bitu len, const Bit16s * data);
void AddSamples_s16_nonnative(Bitu len, const Bit16s * data);
void AddSamples_m16u_nonnative(Bitu len, const Bit16u * data);
void AddSamples_s16u_nonnative(Bitu len, const Bit16u * data);
void AddSamples_m32_nonnative(Bitu len, const Bit32s * data);
void AddSamples_s32_nonnative(Bitu len, const Bit32s * data);
void AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data
void FillUp(void);
void Enable(bool _yesno);
MIXER_Handler handler;
float volmain[2];
float scale;
Bit32s volmul[2];
Bitu freq_add,freq_index;
Bitu done,needed;
Bits last[2];
const char * name;
bool enabled;
MixerChannel * next;
};
MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,const char * name);
MixerChannel * MIXER_FindChannel(const char * name);
/* Find the device you want to delete with findchannel "delchan gets deleted" */
void MIXER_DelChannel(MixerChannel* delchan);
/* Object to maintain a mixerchannel; As all objects it registers itself with create
* and removes itself when destroyed. */
class MixerObject{
private:
bool installed;
char m_name[32];
public:
MixerObject():installed(false){};
MixerChannel* Install(MIXER_Handler handler,Bitu freq,const char * name);
~MixerObject();
};
/* PC Speakers functions, tightly related to the timer functions */
void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode);
void PCSPEAKER_SetType(Bitu mode);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
#define MIXER_8MONO 0
#define MIXER_8STEREO 1
#define MIXER_16MONO 2
#define MIXER_16STEREO 3
#define MAX_AUDIO ((1<<(16-1))-1)
#define MIN_AUDIO -(1<<(16-1))
struct MIXER_Channel;
MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * name);
void MIXER_SetVolume(MIXER_Channel * chan,Bit8u vol);
void MIXER_SetFreq(MIXER_Channel * chan,Bit32u freq);
void MIXER_SetMode(MIXER_Channel * chan,Bit8u mode);
void MIXER_Enable(MIXER_Channel * chan,bool enable);
void PCSPEAKER_Enable(bool enable);
void PCSPEAKER_SetFreq(Bit32u freq);

View File

@ -1,180 +1,180 @@
/* Standard data types used */
typedef unsigned char Bit8u;
typedef signed char Bit8s;
typedef unsigned short Bit16u;
typedef signed short Bit16s;
typedef unsigned long Bit32u;
typedef signed long Bit32s;
#if defined(_MSC_VER)
typedef unsigned __int64 Bit64u;
typedef signed __int64 Bit64s;
#else
typedef unsigned long long int Bit64u;
typedef signed long long int Bit64s;
#endif
/* Setting up pointers to all subfunctions */
#ifdef MODULE_WANT_IO_READ
typedef Bit8u (* IO_ReadHandler)(Bit32u port);
static void (* IO_RegisterReadHandler)(Bit32u port,IO_ReadHandler handler,char * name);
static void (* IO_FreeReadHandler)(Bit32u port);
#endif
#ifdef MODULE_WANT_IO_WRITE
typedef void (* IO_WriteHandler)(Bit32u port,Bit8u value);
static void (* IO_RegisterWriteHandler)(Bit32u port,IO_WriteHandler handler,char * name);
static void (* IO_FreeWriteHandler)(Bit32u port);
#endif
#ifdef MODULE_WANT_IRQ_EOI
typedef void (* IRQ_EOIHandler)(void);
static void (* IRQ_RegisterEOIHandler)(Bit32u irq,IRQ_EOIHandler handler,char * name);
static void (* IRQ_FreeEOIHandler)(Bit32u irq);
#endif
#ifdef MODULE_WANT_IRQ
static void (* IRQ_Activate)(Bit32u irq);
static void (* IRQ_Deactivate)(Bit32u irq);
#endif
#ifdef MODULE_WANT_TIMER
typedef void (* TIMER_MicroHandler)(void);
static void (* TIMER_RegisterMicroHandler)(TIMER_MicroHandler handler,Bit32u micro);
#endif
#ifdef MODULE_WANT_TIMER_TICK
typedef void (* TIMER_TickHandler)(Bit32u ticks);
static void (* TIMER_RegisterTickHandler)(TIMER_TickHandler handler);
#endif
/*
4 8-bit and 4 16-bit channels you can read data from
16-bit reads are word sized
*/
#ifdef MODULE_WANT_DMA_READ
static void (* DMA_8_Read)(Bit32u chan,Bit8u * data,Bit16u size);
static void (* DMA_16_Read)(Bit32u chan,Bit8u * data,Bit16u size);
#endif
/*
4 8-bit and 4 16-bit channels you can write data from
16-bit writes are word sized
*/
#ifdef MODULE_WANT_DMA_READ
static void (* DMA_8_Write)(Bit32u chan,Bit8u * data,Bit16u size);
static void (* DMA_16_Write)(Bit32u chan,Bit8u * data,Bit16u size);
#endif
#ifdef MODULE_WANT_MIXER
/* The len here means the amount of samples needed not the buffersize it needed to fill */
typedef void (* MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
/* Different types if modes a mixer channel can work in */
#define MIXER_8MONO 0
#define MIXER_8STEREO 1
#define MIXER_16MONO 2
#define MIXER_16STEREO 3
struct MIXER_Channel;
#define MAX_AUDIO ((1<<(16-1))-1)
#define MIN_AUDIO -(1<<(16-1))
MIXER_Channel *(* MIXER_AddChannel)(MIXER_MixHandler handler,Bit32u freq,char * name);
void (* MIXER_SetVolume)(MIXER_Channel * chan,Bit8u vol);
void (* MIXER_SetFreq)(MIXER_Channel * chan,Bit32u freq);
void (* MIXER_SetMode)(MIXER_Channel * chan,Bit8u mode);
void (* MIXER_Enable)(MIXER_Channel * chan,bool enable);
#endif
typedef bool (* MODULE_FindHandler)(char * name,void * * function);
typedef char *(* MODULE_StartHandler)(MODULE_FindHandler find_handler);
#define MODULE_START_PROC "ModuleStart"
#ifdef MODULE_START_FUNCTION
#include <stdio.h>
#define GET_FUNCTION(a) \
if (!find_handler(#a ,(void * *) &a)) { \
return "Can't find requested function"; \
};
#if defined (WIN32)
#include <windows.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" {
__declspec(dllexport)
#endif
char * ModuleStart (MODULE_FindHandler find_handler) {
#ifdef MODULE_WANT_IRQ_EOI
GET_FUNCTION(IRQ_RegisterEOIHandler);
GET_FUNCTION(IRQ_FreeEOIHandler);
#endif
#ifdef MODULE_WANT_IRQ
GET_FUNCTION(IRQ_Activate);
GET_FUNCTION(IRQ_Deactivate);
#endif
#ifdef MODULE_WANT_IO_READ
GET_FUNCTION(IO_RegisterReadHandler);
GET_FUNCTION(IO_FreeReadHandler);
#endif
#ifdef MODULE_WANT_IO_WRITE
GET_FUNCTION(IO_RegisterWriteHandler);
GET_FUNCTION(IO_FreeWriteHandler);
#endif
#ifdef MODULE_WANT_TIMER
GET_FUNCTION(TIMER_RegisterMicroHandler);
#endif
#ifdef MODULE_WANT_TIMER_TICKS
GET_FUNCTION(TIMER_RegisterTickHandler);
#endif
#ifdef MODULE_WANT_DMA_READ
GET_FUNCTION(DMA_8_Read);
GET_FUNCTION(DMA_16_Read);
#endif
#ifdef MODULE_WANT_DMA_WRITE
GET_FUNCTION(DMA_8_Write);
GET_FUNCTION(DMA_16_Write);
#endif
#ifdef MODULE_WANT_MIXER
GET_FUNCTION(MIXER_AddChannel);
GET_FUNCTION(MIXER_SetVolume);
GET_FUNCTION(MIXER_SetFreq);
GET_FUNCTION(MIXER_SetMode);
GET_FUNCTION(MIXER_Enable);
#endif
return MODULE_START_FUNCTION;
}
#if defined (WIN32)
}
#endif
#endif
/* Standard data types used */
typedef unsigned char Bit8u;
typedef signed char Bit8s;
typedef unsigned short Bit16u;
typedef signed short Bit16s;
typedef unsigned long Bit32u;
typedef signed long Bit32s;
#if defined(_MSC_VER)
typedef unsigned __int64 Bit64u;
typedef signed __int64 Bit64s;
#else
typedef unsigned long long int Bit64u;
typedef signed long long int Bit64s;
#endif
/* Setting up pointers to all subfunctions */
#ifdef MODULE_WANT_IO_READ
typedef Bit8u (* IO_ReadHandler)(Bit32u port);
static void (* IO_RegisterReadHandler)(Bit32u port,IO_ReadHandler handler,char * name);
static void (* IO_FreeReadHandler)(Bit32u port);
#endif
#ifdef MODULE_WANT_IO_WRITE
typedef void (* IO_WriteHandler)(Bit32u port,Bit8u value);
static void (* IO_RegisterWriteHandler)(Bit32u port,IO_WriteHandler handler,char * name);
static void (* IO_FreeWriteHandler)(Bit32u port);
#endif
#ifdef MODULE_WANT_IRQ_EOI
typedef void (* IRQ_EOIHandler)(void);
static void (* IRQ_RegisterEOIHandler)(Bit32u irq,IRQ_EOIHandler handler,char * name);
static void (* IRQ_FreeEOIHandler)(Bit32u irq);
#endif
#ifdef MODULE_WANT_IRQ
static void (* IRQ_Activate)(Bit32u irq);
static void (* IRQ_Deactivate)(Bit32u irq);
#endif
#ifdef MODULE_WANT_TIMER
typedef void (* TIMER_MicroHandler)(void);
static void (* TIMER_RegisterMicroHandler)(TIMER_MicroHandler handler,Bit32u micro);
#endif
#ifdef MODULE_WANT_TIMER_TICK
typedef void (* TIMER_TickHandler)(Bit32u ticks);
static void (* TIMER_RegisterTickHandler)(TIMER_TickHandler handler);
#endif
/*
4 8-bit and 4 16-bit channels you can read data from
16-bit reads are word sized
*/
#ifdef MODULE_WANT_DMA_READ
static void (* DMA_8_Read)(Bit32u chan,Bit8u * data,Bit16u size);
static void (* DMA_16_Read)(Bit32u chan,Bit8u * data,Bit16u size);
#endif
/*
4 8-bit and 4 16-bit channels you can write data from
16-bit writes are word sized
*/
#ifdef MODULE_WANT_DMA_READ
static void (* DMA_8_Write)(Bit32u chan,Bit8u * data,Bit16u size);
static void (* DMA_16_Write)(Bit32u chan,Bit8u * data,Bit16u size);
#endif
#ifdef MODULE_WANT_MIXER
/* The len here means the amount of samples needed not the buffersize it needed to fill */
typedef void (* MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
/* Different types if modes a mixer channel can work in */
#define MIXER_8MONO 0
#define MIXER_8STEREO 1
#define MIXER_16MONO 2
#define MIXER_16STEREO 3
struct MIXER_Channel;
#define MAX_AUDIO ((1<<(16-1))-1)
#define MIN_AUDIO -(1<<(16-1))
MIXER_Channel *(* MIXER_AddChannel)(MIXER_MixHandler handler,Bit32u freq,char * name);
void (* MIXER_SetVolume)(MIXER_Channel * chan,Bit8u vol);
void (* MIXER_SetFreq)(MIXER_Channel * chan,Bit32u freq);
void (* MIXER_SetMode)(MIXER_Channel * chan,Bit8u mode);
void (* MIXER_Enable)(MIXER_Channel * chan,bool enable);
#endif
typedef bool (* MODULE_FindHandler)(char * name,void * * function);
typedef char *(* MODULE_StartHandler)(MODULE_FindHandler find_handler);
#define MODULE_START_PROC "ModuleStart"
#ifdef MODULE_START_FUNCTION
#include <stdio.h>
#define GET_FUNCTION(a) \
if (!find_handler(#a ,(void * *) &a)) { \
return "Can't find requested function"; \
};
#if defined (WIN32)
#include <windows.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" {
__declspec(dllexport)
#endif
char * ModuleStart (MODULE_FindHandler find_handler) {
#ifdef MODULE_WANT_IRQ_EOI
GET_FUNCTION(IRQ_RegisterEOIHandler);
GET_FUNCTION(IRQ_FreeEOIHandler);
#endif
#ifdef MODULE_WANT_IRQ
GET_FUNCTION(IRQ_Activate);
GET_FUNCTION(IRQ_Deactivate);
#endif
#ifdef MODULE_WANT_IO_READ
GET_FUNCTION(IO_RegisterReadHandler);
GET_FUNCTION(IO_FreeReadHandler);
#endif
#ifdef MODULE_WANT_IO_WRITE
GET_FUNCTION(IO_RegisterWriteHandler);
GET_FUNCTION(IO_FreeWriteHandler);
#endif
#ifdef MODULE_WANT_TIMER
GET_FUNCTION(TIMER_RegisterMicroHandler);
#endif
#ifdef MODULE_WANT_TIMER_TICKS
GET_FUNCTION(TIMER_RegisterTickHandler);
#endif
#ifdef MODULE_WANT_DMA_READ
GET_FUNCTION(DMA_8_Read);
GET_FUNCTION(DMA_16_Read);
#endif
#ifdef MODULE_WANT_DMA_WRITE
GET_FUNCTION(DMA_8_Write);
GET_FUNCTION(DMA_16_Write);
#endif
#ifdef MODULE_WANT_MIXER
GET_FUNCTION(MIXER_AddChannel);
GET_FUNCTION(MIXER_SetVolume);
GET_FUNCTION(MIXER_SetFreq);
GET_FUNCTION(MIXER_SetMode);
GET_FUNCTION(MIXER_Enable);
#endif
return MODULE_START_FUNCTION;
}
#if defined (WIN32)
}
#endif
#endif

View File

@ -1,42 +1,28 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: mouse.h,v 1.14 2008/03/08 22:04:44 c2woody Exp $ */
#ifndef DOSBOX_MOUSE_H
#define DOSBOX_MOUSE_H
void Mouse_ShowCursor(void);
void Mouse_HideCursor(void);
bool Mouse_SetPS2State(bool use);
void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs);
void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate);
void Mouse_CursorSet(float x,float y);
void Mouse_ButtonPressed(Bit8u button);
void Mouse_ButtonReleased(Bit8u button);
void Mouse_AutoLock(bool enable);
void Mouse_NewVideoMode(void);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
void Mouse_ShowCursor(void);
void Mouse_HideCursor(void);
void Mouse_CursorMoved(float x,float y);
void Mouse_CursorSet(float x,float y);
void Mouse_ButtonPressed(Bit8u button);
void Mouse_ButtonReleased(Bit8u button);

View File

@ -1,366 +0,0 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: paging.h,v 1.32 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_PAGING_H
#define DOSBOX_PAGING_H
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
// disable this to reduce the size of the TLB
// NOTE: does not work with the dynamic core (dynrec is fine)
#define USE_FULL_TLB
class PageDirectory;
#define MEM_PAGE_SIZE (4096)
#define XMS_START (0x110)
#if defined(USE_FULL_TLB)
#define TLB_SIZE (1024*1024)
#else
#define TLB_SIZE 65536 // This must a power of 2 and greater then LINK_START
#define BANK_SHIFT 28
#define BANK_MASK 0xffff // always the same as TLB_SIZE-1?
#define TLB_BANKS ((1024*1024/TLB_SIZE)-1)
#endif
#define PFLAG_READABLE 0x1
#define PFLAG_WRITEABLE 0x2
#define PFLAG_HASROM 0x4
#define PFLAG_HASCODE 0x8 //Page contains dynamic code
#define PFLAG_NOCODE 0x10 //No dynamic code can be generated here
#define PFLAG_INIT 0x20 //No dynamic code can be generated here
#define LINK_START ((1024+64)/4) //Start right after the HMA
//Allow 128 mb of memory to be linked
#define PAGING_LINKS (128*1024/4)
class PageHandler {
public:
virtual ~PageHandler(void) { }
virtual Bitu readb(PhysPt addr);
virtual Bitu readw(PhysPt addr);
virtual Bitu readd(PhysPt addr);
virtual void writeb(PhysPt addr,Bitu val);
virtual void writew(PhysPt addr,Bitu val);
virtual void writed(PhysPt addr,Bitu val);
virtual HostPt GetHostReadPt(Bitu phys_page);
virtual HostPt GetHostWritePt(Bitu phys_page);
virtual bool readb_checked(PhysPt addr,Bit8u * val);
virtual bool readw_checked(PhysPt addr,Bit16u * val);
virtual bool readd_checked(PhysPt addr,Bit32u * val);
virtual bool writeb_checked(PhysPt addr,Bitu val);
virtual bool writew_checked(PhysPt addr,Bitu val);
virtual bool writed_checked(PhysPt addr,Bitu val);
Bitu flags;
};
/* Some other functions */
void PAGING_Enable(bool enabled);
bool PAGING_Enabled(void);
Bitu PAGING_GetDirBase(void);
void PAGING_SetDirBase(Bitu cr3);
void PAGING_InitTLB(void);
void PAGING_ClearTLB(void);
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page);
void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page);
void PAGING_UnlinkPages(Bitu lin_page,Bitu pages);
/* This maps the page directly, only use when paging is disabled */
void PAGING_MapPage(Bitu lin_page,Bitu phys_page);
bool PAGING_MakePhysPage(Bitu & page);
bool PAGING_ForcePageInit(Bitu lin_addr);
void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler);
void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler);
void MEM_ResetPageHandler(Bitu phys_page, Bitu pages);
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct X86_PageEntryBlock{
#ifdef WORDS_BIGENDIAN
Bit32u base:20;
Bit32u avl:3;
Bit32u g:1;
Bit32u pat:1;
Bit32u d:1;
Bit32u a:1;
Bit32u pcd:1;
Bit32u pwt:1;
Bit32u us:1;
Bit32u wr:1;
Bit32u p:1;
#else
Bit32u p:1;
Bit32u wr:1;
Bit32u us:1;
Bit32u pwt:1;
Bit32u pcd:1;
Bit32u a:1;
Bit32u d:1;
Bit32u pat:1;
Bit32u g:1;
Bit32u avl:3;
Bit32u base:20;
#endif
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif
union X86PageEntry {
Bit32u load;
X86_PageEntryBlock block;
};
#if !defined(USE_FULL_TLB)
typedef struct {
HostPt read;
HostPt write;
PageHandler * readhandler;
PageHandler * writehandler;
Bit32u phys_page;
} tlb_entry;
#endif
struct PagingBlock {
Bitu cr3;
Bitu cr2;
struct {
Bitu page;
PhysPt addr;
} base;
#if defined(USE_FULL_TLB)
struct {
HostPt read[TLB_SIZE];
HostPt write[TLB_SIZE];
PageHandler * readhandler[TLB_SIZE];
PageHandler * writehandler[TLB_SIZE];
Bit32u phys_page[TLB_SIZE];
} tlb;
#else
tlb_entry tlbh[TLB_SIZE];
tlb_entry *tlbh_banks[TLB_BANKS];
#endif
struct {
Bitu used;
Bit32u entries[PAGING_LINKS];
} links;
Bit32u firstmb[LINK_START];
bool enabled;
};
extern PagingBlock paging;
/* Some support functions */
PageHandler * MEM_GetPageHandler(Bitu phys_page);
/* Unaligned address handlers */
Bit16u mem_unalignedreadw(PhysPt address);
Bit32u mem_unalignedreadd(PhysPt address);
void mem_unalignedwritew(PhysPt address,Bit16u val);
void mem_unalignedwrited(PhysPt address,Bit32u val);
bool mem_unalignedreadw_checked(PhysPt address,Bit16u * val);
bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val);
bool mem_unalignedwritew_checked(PhysPt address,Bit16u val);
bool mem_unalignedwrited_checked(PhysPt address,Bit32u val);
#if defined(USE_FULL_TLB)
static INLINE HostPt get_tlb_read(PhysPt address) {
return paging.tlb.read[address>>12];
}
static INLINE HostPt get_tlb_write(PhysPt address) {
return paging.tlb.write[address>>12];
}
static INLINE PageHandler* get_tlb_readhandler(PhysPt address) {
return paging.tlb.readhandler[address>>12];
}
static INLINE PageHandler* get_tlb_writehandler(PhysPt address) {
return paging.tlb.writehandler[address>>12];
}
/* Use these helper functions to access linear addresses in readX/writeX functions */
static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
return (paging.tlb.phys_page[linePage>>12]<<12);
}
static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff);
}
#else
void PAGING_InitTLBBank(tlb_entry **bank);
static INLINE tlb_entry *get_tlb_entry(PhysPt address) {
Bitu index=(address>>12);
if (TLB_BANKS && (index > TLB_SIZE)) {
Bitu bank=(address>>BANK_SHIFT) - 1;
if (!paging.tlbh_banks[bank])
PAGING_InitTLBBank(&paging.tlbh_banks[bank]);
return &paging.tlbh_banks[bank][index & BANK_MASK];
}
return &paging.tlbh[index];
}
static INLINE HostPt get_tlb_read(PhysPt address) {
return get_tlb_entry(address)->read;
}
static INLINE HostPt get_tlb_write(PhysPt address) {
return get_tlb_entry(address)->write;
}
static INLINE PageHandler* get_tlb_readhandler(PhysPt address) {
return get_tlb_entry(address)->readhandler;
}
static INLINE PageHandler* get_tlb_writehandler(PhysPt address) {
return get_tlb_entry(address)->writehandler;
}
/* Use these helper functions to access linear addresses in readX/writeX functions */
static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
tlb_entry *entry = get_tlb_entry(linePage);
return (entry->phys_page<<12);
}
static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
tlb_entry *entry = get_tlb_entry(linAddr);
return (entry->phys_page<<12)|(linAddr&0xfff);
}
#endif
/* Special inlined memory reading/writing */
static INLINE Bit8u mem_readb_inline(PhysPt address) {
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) return host_readb(tlb_addr+address);
else return (Bit8u)(get_tlb_readhandler(address))->readb(address);
}
static INLINE Bit16u mem_readw_inline(PhysPt address) {
if ((address & 0xfff)<0xfff) {
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) return host_readw(tlb_addr+address);
else return (Bit16u)(get_tlb_readhandler(address))->readw(address);
} else return mem_unalignedreadw(address);
}
static INLINE Bit32u mem_readd_inline(PhysPt address) {
if ((address & 0xfff)<0xffd) {
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) return host_readd(tlb_addr+address);
else return (get_tlb_readhandler(address))->readd(address);
} else return mem_unalignedreadd(address);
}
static INLINE void mem_writeb_inline(PhysPt address,Bit8u val) {
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writeb(tlb_addr+address,val);
else (get_tlb_writehandler(address))->writeb(address,val);
}
static INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
if ((address & 0xfff)<0xfff) {
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writew(tlb_addr+address,val);
else (get_tlb_writehandler(address))->writew(address,val);
} else mem_unalignedwritew(address,val);
}
static INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
if ((address & 0xfff)<0xffd) {
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writed(tlb_addr+address,val);
else (get_tlb_writehandler(address))->writed(address,val);
} else mem_unalignedwrited(address,val);
}
static INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) {
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) {
*val=host_readb(tlb_addr+address);
return false;
} else return (get_tlb_readhandler(address))->readb_checked(address, val);
}
static INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) {
if ((address & 0xfff)<0xfff) {
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) {
*val=host_readw(tlb_addr+address);
return false;
} else return (get_tlb_readhandler(address))->readw_checked(address, val);
} else return mem_unalignedreadw_checked(address, val);
}
static INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) {
if ((address & 0xfff)<0xffd) {
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) {
*val=host_readd(tlb_addr+address);
return false;
} else return (get_tlb_readhandler(address))->readd_checked(address, val);
} else return mem_unalignedreadd_checked(address, val);
}
static INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) {
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) {
host_writeb(tlb_addr+address,val);
return false;
} else return (get_tlb_writehandler(address))->writeb_checked(address,val);
}
static INLINE bool mem_writew_checked(PhysPt address,Bit16u val) {
if ((address & 0xfff)<0xfff) {
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) {
host_writew(tlb_addr+address,val);
return false;
} else return (get_tlb_writehandler(address))->writew_checked(address,val);
} else return mem_unalignedwritew_checked(address,val);
}
static INLINE bool mem_writed_checked(PhysPt address,Bit32u val) {
if ((address & 0xfff)<0xffd) {
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) {
host_writed(tlb_addr+address,val);
return false;
} else return (get_tlb_writehandler(address))->writed_checked(address,val);
} else return mem_unalignedwrited_checked(address,val);
}
#endif

View File

@ -1,67 +1,44 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_PIC_H
#define DOSBOX_PIC_H
/* CPU Cycle Timing */
extern Bit32s CPU_Cycles;
extern Bit32s CPU_CycleLeft;
extern Bit32s CPU_CycleMax;
typedef void (PIC_EOIHandler) (void);
typedef void (* PIC_EventHandler)(Bitu val);
#define PIC_MAXIRQ 15
#define PIC_NOIRQ 0xFF
extern Bitu PIC_IRQCheck;
extern Bitu PIC_IRQActive;
extern Bitu PIC_Ticks;
static INLINE float PIC_TickIndex(void) {
return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax;
}
static INLINE Bits PIC_TickIndexND(void) {
return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles;
}
static INLINE Bits PIC_MakeCycles(double amount) {
return (Bits)(CPU_CycleMax*amount);
}
static INLINE double PIC_FullIndex(void) {
return PIC_Ticks+(double)PIC_TickIndex();
}
void PIC_ActivateIRQ(Bitu irq);
void PIC_DeActivateIRQ(Bitu irq);
void PIC_runIRQs(void);
bool PIC_RunQueue(void);
//Delay in milliseconds
void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val=0);
void PIC_RemoveEvents(PIC_EventHandler handler);
void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val);
void PIC_SetIRQMask(Bitu irq, bool masked);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __PIC_H
#define __PIC_H
typedef void (PIC_EOIHandler) (void);
typedef void (PIC_Function)(void);
extern Bit32u PIC_IRQCheck;
void PIC_ActivateIRQ(Bit32u irq);
void PIC_DeActivateIRQ(Bit32u irq);
void PIC_runIRQs(void);
void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name);
void PIC_FreeIRQ(Bit32u irq);
bool PIC_IRQActive(Bit32u irq);
/* A Queued function should never queue itself again this will go horribly wrong */
void PIC_QueueFunction(PIC_Function * function);
#endif

View File

@ -1,90 +1,58 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: programs.h,v 1.18 2009/03/11 20:18:37 qbix79 Exp $ */
#ifndef DOSBOX_PROGRAMS_H
#define DOSBOX_PROGRAMS_H
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#ifndef DOSBOX_DOS_INC_H
#include "dos_inc.h"
#endif
#ifndef CH_LIST
#define CH_LIST
#include <list>
#endif
#ifndef CH_STRING
#define CH_STRING
#include <string>
#endif
class CommandLine {
public:
CommandLine(int argc,char const * const argv[]);
CommandLine(char const * const name,char const * const cmdline);
const char * GetFileName(){ return file_name.c_str();}
bool FindExist(char const * const name,bool remove=false);
bool FindHex(char const * const name,int & value,bool remove=false);
bool FindInt(char const * const name,int & value,bool remove=false);
bool FindString(char const * const name,std::string & value,bool remove=false);
bool FindCommand(unsigned int which,std::string & value);
bool FindStringBegin(char const * const begin,std::string & value, bool remove=false);
bool FindStringRemain(char const * const name,std::string & value);
bool GetStringRemain(std::string & value);
unsigned int GetCount(void);
void Shift(unsigned int amount=1);
Bit16u Get_arglength();
private:
typedef std::list<std::string>::iterator cmd_it;
std::list<std::string> cmds;
std::string file_name;
bool FindEntry(char const * const name,cmd_it & it,bool neednext=false);
};
class Program {
public:
Program();
virtual ~Program(){
delete cmd;
delete psp;
}
std::string temp_line;
CommandLine * cmd;
DOS_PSP * psp;
virtual void Run(void)=0;
bool GetEnvStr(const char * entry,std::string & result);
bool GetEnvNum(Bitu num,std::string & result);
Bitu GetEnvCount(void);
bool SetEnv(const char * entry,const char * new_string);
void WriteOut(const char * format,...); /* Write to standard output */
void WriteOut_NoParsing(const char * format); /* Write to standard output, no parsing */
void ChangeToLongCmd();
};
typedef void (PROGRAMS_Main)(Program * * make);
void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __PROGRAM_H
#define __PROGRAM_H
#include <dosbox.h>
#include <dos_inc.h>
char * MSG_Get(char * msg);
struct PROGRAM_Info {
Bit16u psp_seg;
PSP psp_copy;
char full_name[32]; //Enough space for programs only on the z:\ drive
char * cmd_line;
};
typedef void (PROGRAMS_Main)(PROGRAM_Info * info);
void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main);
class Program {
public:
Program(PROGRAM_Info * program_info);
virtual void Run(void)=0;
char * GetEnvStr(char * env_entry);
char * GetEnvNum(Bit32u num);
Bit32u GetEnvCount(void);
bool SetEnv(char * env_entry,char * new_string);
void WriteOut(char * format,...); /* Write to standard output */
PROGRAM_Info * prog_info;
};
void SHELL_AddAutoexec(char * line,...);
#endif

View File

@ -1,169 +1,117 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_REGS_H
#define DOSBOX_REGS_H
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
#define FLAG_CF 0x00000001
#define FLAG_PF 0x00000004
#define FLAG_AF 0x00000010
#define FLAG_ZF 0x00000040
#define FLAG_SF 0x00000080
#define FLAG_OF 0x00000800
#define FLAG_TF 0x00000100
#define FLAG_IF 0x00000200
#define FLAG_DF 0x00000400
#define FLAG_IOPL 0x00003000
#define FLAG_NT 0x00004000
#define FLAG_VM 0x00020000
#define FLAG_AC 0x00040000
#define FLAG_ID 0x00200000
#define FMASK_TEST (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF)
#define FMASK_NORMAL (FMASK_TEST | FLAG_DF | FLAG_TF | FLAG_IF | FLAG_AC )
#define FMASK_ALL (FMASK_NORMAL | FLAG_IOPL | FLAG_NT)
#define SETFLAGBIT(TYPE,TEST) if (TEST) reg_flags|=FLAG_ ## TYPE; else reg_flags&=~FLAG_ ## TYPE
#define GETFLAG(TYPE) (reg_flags & FLAG_ ## TYPE)
#define GETFLAGBOOL(TYPE) ((reg_flags & FLAG_ ## TYPE) ? true : false )
#define GETFLAG_IOPL ((reg_flags & FLAG_IOPL) >> 12)
struct Segment {
Bit16u val;
PhysPt phys; /* The phyiscal address start in emulated machine */
};
enum SegNames { es=0,cs,ss,ds,fs,gs};
struct Segments {
Bitu val[8];
PhysPt phys[8];
};
union GenReg32 {
Bit32u dword[1];
Bit16u word[2];
Bit8u byte[4];
};
#ifdef WORDS_BIGENDIAN
#define DW_INDEX 0
#define W_INDEX 1
#define BH_INDEX 2
#define BL_INDEX 3
#else
#define DW_INDEX 0
#define W_INDEX 0
#define BH_INDEX 1
#define BL_INDEX 0
#endif
struct CPU_Regs {
GenReg32 regs[8],ip;
Bitu flags;
};
extern Segments Segs;
extern CPU_Regs cpu_regs;
static INLINE PhysPt SegPhys(SegNames index) {
return Segs.phys[index];
}
static INLINE Bit16u SegValue(SegNames index) {
return (Bit16u)Segs.val[index];
}
static INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) {
return RealMake(SegValue(index),off);
}
static INLINE void SegSet16(Bitu index,Bit16u val) {
Segs.val[index]=val;
Segs.phys[index]=val << 4;
}
enum {
REGI_AX, REGI_CX, REGI_DX, REGI_BX,
REGI_SP, REGI_BP, REGI_SI, REGI_DI
};
enum {
REGI_AL, REGI_CL, REGI_DL, REGI_BL,
REGI_AH, REGI_CH, REGI_DH, REGI_BH
};
//macros to convert a 3-bit register index to the correct register
#define reg_8l(reg) (cpu_regs.regs[(reg)].byte[BL_INDEX])
#define reg_8h(reg) (cpu_regs.regs[(reg)].byte[BH_INDEX])
#define reg_8(reg) ((reg) & 4 ? reg_8h((reg) & 3) : reg_8l((reg) & 3))
#define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX])
#define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX])
#define reg_al cpu_regs.regs[REGI_AX].byte[BL_INDEX]
#define reg_ah cpu_regs.regs[REGI_AX].byte[BH_INDEX]
#define reg_ax cpu_regs.regs[REGI_AX].word[W_INDEX]
#define reg_eax cpu_regs.regs[REGI_AX].dword[DW_INDEX]
#define reg_bl cpu_regs.regs[REGI_BX].byte[BL_INDEX]
#define reg_bh cpu_regs.regs[REGI_BX].byte[BH_INDEX]
#define reg_bx cpu_regs.regs[REGI_BX].word[W_INDEX]
#define reg_ebx cpu_regs.regs[REGI_BX].dword[DW_INDEX]
#define reg_cl cpu_regs.regs[REGI_CX].byte[BL_INDEX]
#define reg_ch cpu_regs.regs[REGI_CX].byte[BH_INDEX]
#define reg_cx cpu_regs.regs[REGI_CX].word[W_INDEX]
#define reg_ecx cpu_regs.regs[REGI_CX].dword[DW_INDEX]
#define reg_dl cpu_regs.regs[REGI_DX].byte[BL_INDEX]
#define reg_dh cpu_regs.regs[REGI_DX].byte[BH_INDEX]
#define reg_dx cpu_regs.regs[REGI_DX].word[W_INDEX]
#define reg_edx cpu_regs.regs[REGI_DX].dword[DW_INDEX]
#define reg_si cpu_regs.regs[REGI_SI].word[W_INDEX]
#define reg_esi cpu_regs.regs[REGI_SI].dword[DW_INDEX]
#define reg_di cpu_regs.regs[REGI_DI].word[W_INDEX]
#define reg_edi cpu_regs.regs[REGI_DI].dword[DW_INDEX]
#define reg_sp cpu_regs.regs[REGI_SP].word[W_INDEX]
#define reg_esp cpu_regs.regs[REGI_SP].dword[DW_INDEX]
#define reg_bp cpu_regs.regs[REGI_BP].word[W_INDEX]
#define reg_ebp cpu_regs.regs[REGI_BP].dword[DW_INDEX]
#define reg_ip cpu_regs.ip.word[W_INDEX]
#define reg_eip cpu_regs.ip.dword[DW_INDEX]
#define reg_flags cpu_regs.flags
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined __REGS_H
#define __REGS_H
#include <mem.h>
struct Flag_Info {
union {
Bit8u b;
Bit8u bs;
Bit16u w;
Bit16s ws;
Bit32u d;
Bit32s ds;
} var1,var2,result;
Bitu type;
Bitu prev_type;
bool cf,sf,pf,af,zf,of,df,tf,intf;
bool nt;
Bit8u io;
bool oldcf;
};
struct Segment {
Bit16u value;
bool special; /* Signal for pointing to special memory */
HostOff host; /* The address of start in host memory */
PhysOff phys; /* The phyiscal address start in emulated machine */
};
enum { cs=0,ds,es,fs,gs,ss};
extern Segment Segs[6];
extern Flag_Info flags;
//extern Regs regs;
void SetSegment_16(Bit32u seg,Bit16u val);
struct CPU_Regs {
union {
Bit32u d;
Bit16u w;
struct {
Bit8u l,h;
}b;
} ax,bx,cx,dx,si,di,sp,bp,ip;
};
extern CPU_Regs cpu_regs;
#define reg_al cpu_regs.ax.b.l
//extern Bit8u & reg_al=cpu_regs.ax.b.l;
#define reg_ah cpu_regs.ax.b.h
#define reg_ax cpu_regs.ax.w
#define reg_eax cpu_regs.ax.d
#define reg_bl cpu_regs.bx.b.l
#define reg_bh cpu_regs.bx.b.h
#define reg_bx cpu_regs.bx.w
#define reg_ebx cpu_regs.bx.d
#define reg_cl cpu_regs.cx.b.l
#define reg_ch cpu_regs.cx.b.h
#define reg_cx cpu_regs.cx.w
#define reg_ecx cpu_regs.cx.d
#define reg_dl cpu_regs.dx.b.l
#define reg_dh cpu_regs.dx.b.h
#define reg_dx cpu_regs.dx.w
#define reg_edx cpu_regs.dx.d
#define reg_si cpu_regs.si.w
#define reg_esi cpu_regs.si.d
#define reg_di cpu_regs.di.w
#define reg_edi cpu_regs.di.d
#define reg_sp cpu_regs.sp.w
#define reg_esp cpu_regs.sp.d
#define reg_bp cpu_regs.bp.w
#define reg_ebp cpu_regs.bp.d
#define reg_ip cpu_regs.ip.w
#define reg_eip cpu_regs.ip.d
#endif

View File

@ -1,98 +1,25 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_RENDER_H
#define DOSBOX_RENDER_H
// 0: complex scalers off, scaler cache off, some simple scalers off, memory requirements reduced
// 1: complex scalers off, scaler cache off, all simple scalers on
// 2: complex scalers off, scaler cache on
// 3: complex scalers on
#define RENDER_USE_ADVANCED_SCALERS 3
#include "../src/gui/render_scalers.h"
#define RENDER_SKIP_CACHE 16
//Enable this for scalers to support 0 input for empty lines
//#define RENDER_NULL_INPUT
typedef struct {
struct {
Bit8u red;
Bit8u green;
Bit8u blue;
Bit8u unused;
} rgb[256];
union {
Bit16u b16[256];
Bit32u b32[256];
} lut;
bool changed;
Bit8u modified[256];
Bitu first;
Bitu last;
} RenderPal_t;
typedef struct {
struct {
Bitu width, start;
Bitu height;
Bitu bpp;
bool dblw,dblh;
double ratio;
float fps;
} src;
struct {
Bitu count;
Bitu max;
Bitu index;
Bit8u hadSkip[RENDER_SKIP_CACHE];
} frameskip;
struct {
Bitu size;
scalerMode_t inMode;
scalerMode_t outMode;
scalerOperation_t op;
bool clearCache;
bool forced;
ScalerLineHandler_t lineHandler;
ScalerLineHandler_t linePalHandler;
ScalerComplexHandler_t complexHandler;
Bitu blocks, lastBlock;
Bitu outPitch;
Bit8u *outWrite;
Bitu cachePitch;
Bit8u *cacheRead;
Bitu inHeight, inLine, outLine;
} scale;
RenderPal_t pal;
bool updating;
bool active;
bool aspect;
bool fullFrame;
} Render_t;
extern Render_t render;
extern ScalerLineHandler_t RENDER_DrawLine;
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh);
bool RENDER_StartUpdate(void);
void RENDER_EndUpdate( );
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
typedef void RENDER_Handler(Bit8u * * data);
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags, RENDER_Handler * handler);
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);

View File

@ -1,361 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: serialport.h,v 1.16 2009/02/01 14:11:45 qbix79 Exp $ */
#ifndef DOSBOX_SERIALPORT_H
#define DOSBOX_SERIALPORT_H
#define SERIAL_DEBUG 0
// Uncomment this for a lot of debug messages:
//#define LOG_UART
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#ifndef DOSBOX_INOUT_H
#include "inout.h"
#endif
#ifndef DOSBOX_TIMER_H
#include "timer.h"
#endif
#ifndef DOSBOX_DOS_INC_H
#include "dos_inc.h"
#endif
#ifndef DOSBOX_PROGRAMS_H
#include "programs.h"
#endif
#if SERIAL_DEBUG
#include "hardware.h"
#endif
// Serial port interface
class CSerial {
public:
#if SERIAL_DEBUG
FILE * debugfp;
bool dbg_modemcontrol; // RTS,CTS,DTR,DSR,RI,CD
bool dbg_serialtraffic;
bool dbg_register;
bool dbg_interrupt;
bool dbg_aux;
#endif
static bool getBituSubstring(const char* name,Bitu* data, CommandLine* cmd);
bool InstallationSuccessful;// check after constructing. If
// something was wrong, delete it right away.
// Constructor takes com port number (0-3)
CSerial(Bitu id, CommandLine* cmd);
virtual ~CSerial();
IO_ReadHandleObject ReadHandler[8];
IO_WriteHandleObject WriteHandler[8];
float bytetime; // how long a byte takes to transmit/receive in milliseconds
void changeLineProperties();
Bitu idnumber;
void setEvent(Bit16u type, float duration);
void removeEvent(Bit16u type);
void handleEvent(Bit16u type);
virtual void handleUpperEvent(Bit16u type)=0;
// defines for event type
#define SERIAL_TX_LOOPBACK_EVENT 0
#define SERIAL_THR_LOOPBACK_EVENT 1
#define SERIAL_ERRMSG_EVENT 2
#define SERIAL_TX_EVENT 3
#define SERIAL_RX_EVENT 4
#define SERIAL_POLLING_EVENT 5
#define SERIAL_THR_EVENT 6
#define SERIAL_BASE_EVENT_COUNT 6
#define COMNUMBER idnumber+1
Bitu irq;
// CSerial requests an update of the input lines
virtual void updateMSR()=0;
// Control lines from prepherial to serial port
bool getDTR();
bool getRTS();
bool getRI();
bool getCD();
bool getDSR();
bool getCTS();
void setRI(bool value);
void setDSR(bool value);
void setCD(bool value);
void setCTS(bool value);
// From serial port to prepherial
// set output lines
virtual void setRTSDTR(bool rts, bool dtr)=0;
virtual void setRTS(bool val)=0;
virtual void setDTR(bool val)=0;
// Register access
void Write_THR(Bit8u data);
void Write_IER(Bit8u data);
void Write_FCR(Bit8u data);
void Write_LCR(Bit8u data);
void Write_MCR(Bit8u data);
// Really old hardware seems to have the delta part of this register writable
void Write_MSR(Bit8u data);
void Write_SPR(Bit8u data);
void Write_reserved(Bit8u data, Bit8u address);
Bitu Read_RHR();
Bitu Read_IER();
Bitu Read_ISR();
Bitu Read_LCR();
Bitu Read_MCR();
Bitu Read_LSR();
Bitu Read_MSR();
Bitu Read_SPR();
// If a byte comes from loopback or prepherial, put it in here.
void receiveByte(Bit8u data);
// If an error was received, put it here (in LSR register format)
void receiveError(Bit8u errorword);
// depratched
// connected device checks, if port can receive data:
bool CanReceiveByte();
// when THR was shifted to TX
void ByteTransmitting();
// When done sending, notify here
void ByteTransmitted();
// Transmit byte to prepherial
virtual void transmitByte(Bit8u val, bool first)=0;
// switch break state to the passed value
virtual void setBreak(bool value)=0;
// change baudrate, number of bits, parity, word length al at once
virtual void updatePortConfig(Bit16u divider, Bit8u lcr)=0;
void Init_Registers();
bool Putchar(Bit8u data, bool wait_dtr, bool wait_rts, Bitu timeout);
bool Getchar(Bit8u* data, Bit8u* lsr, bool wait_dsr, Bitu timeout);
private:
DOS_Device* mydosdevice;
// I used this spec: http://www.exar.com/products/st16c450v420.pdf
void ComputeInterrupts();
// a sub-interrupt is triggered
void rise(Bit8u priority);
// clears the pending sub-interrupt
void clear(Bit8u priority);
#define ERROR_PRIORITY 4 // overrun, parity error, frame error, break
#define RX_PRIORITY 1 // a byte has been received
#define TX_PRIORITY 2 // tx buffer has become empty
#define MSR_PRIORITY 8 // CRS, DSR, RI, DCD change
#define NONE_PRIORITY 0
Bit8u waiting_interrupts; // these are on, but maybe not enabled
// 16C450 (no FIFO)
// read/write name
Bit16u baud_divider;
Bit8u RHR; // r Receive Holding Register, also LSB of Divisor Latch (r/w)
#define RHR_OFFSET 0
// Data: whole byte
Bit8u THR; // w Transmit Holding Register
#define THR_OFFSET 0
// Data: whole byte
Bit8u IER; // r/w Interrupt Enable Register, also MSB of Divisor Latch
#define IER_OFFSET 1
bool irq_active;
#define RHR_INT_Enable_MASK 0x1
#define THR_INT_Enable_MASK 0x2
#define Receive_Line_INT_Enable_MASK 0x4
#define Modem_Status_INT_Enable_MASK 0x8
Bit8u ISR; // r Interrupt Status Register
#define ISR_OFFSET 2
#define ISR_CLEAR_VAL 0x1
#define ISR_ERROR_VAL 0x6
#define ISR_RX_VAL 0x4
#define ISR_TX_VAL 0x2
#define ISR_MSR_VAL 0x0
public:
Bit8u LCR; // r/w Line Control Register
private:
#define LCR_OFFSET 3
// bit0: word length bit0
// bit1: word length bit1
// bit2: stop bits
// bit3: parity enable
// bit4: even parity
// bit5: set parity
// bit6: set break
// bit7: divisor latch enable
#define LCR_BREAK_MASK 0x40
#define LCR_DIVISOR_Enable_MASK 0x80
#define LCR_PORTCONFIG_MASK 0x3F
#define LCR_PARITY_NONE 0x0
#define LCR_PARITY_ODD 0x8
#define LCR_PARITY_EVEN 0x18
#define LCR_PARITY_MARK 0x28
#define LCR_PARITY_SPACE 0x38
#define LCR_DATABITS_5 0x0
#define LCR_DATABITS_6 0x1
#define LCR_DATABITS_7 0x2
#define LCR_DATABITS_8 0x3
#define LCR_STOPBITS_1 0x0
#define LCR_STOPBITS_MORE_THAN_1 0x4
// Modem Control Register
// r/w
#define MCR_OFFSET 4
bool dtr; // bit0: DTR
bool rts; // bit1: RTS
bool op1; // bit2: OP1
bool op2; // bit3: OP2
bool loopback; // bit4: loop back enable
#define MCR_DTR_MASK 0x1
#define MCR_RTS_MASK 0x2
#define MCR_OP1_MASK 0x4
#define MCR_OP2_MASK 0x8
#define MCR_LOOPBACK_Enable_MASK 0x10
public:
Bit8u LSR; // r Line Status Register
private:
#define LSR_OFFSET 5
#define LSR_RX_DATA_READY_MASK 0x1
#define LSR_OVERRUN_ERROR_MASK 0x2
#define LSR_PARITY_ERROR_MASK 0x4
#define LSR_FRAMING_ERROR_MASK 0x8
#define LSR_RX_BREAK_MASK 0x10
#define LSR_TX_HOLDING_EMPTY_MASK 0x20
#define LSR_TX_EMPTY_MASK 0x40
#define LSR_ERROR_MASK 0x1e
// error printing
bool errormsg_pending;
Bitu framingErrors;
Bitu parityErrors;
Bitu overrunErrors;
Bitu overrunIF0;
Bitu breakErrors;
// Modem Status Register
// r
#define MSR_OFFSET 6
bool d_cts; // bit0: deltaCTS
bool d_dsr; // bit1: deltaDSR
bool d_ri; // bit2: deltaRI
bool d_cd; // bit3: deltaCD
bool cts; // bit4: CTS
bool dsr; // bit5: DSR
bool ri; // bit6: RI
bool cd; // bit7: CD
#define MSR_delta_MASK 0xf
#define MSR_LINE_MASK 0xf0
#define MSR_dCTS_MASK 0x1
#define MSR_dDSR_MASK 0x2
#define MSR_dRI_MASK 0x4
#define MSR_dCD_MASK 0x8
#define MSR_CTS_MASK 0x10
#define MSR_DSR_MASK 0x20
#define MSR_RI_MASK 0x40
#define MSR_CD_MASK 0x80
Bit8u SPR; // r/w Scratchpad Register
#define SPR_OFFSET 7
// For loopback purposes...
Bit8u loopback_data;
void transmitLoopbackByte(Bit8u val, bool value);
// 16C550 (FIFO)
// TODO
#define FCR_OFFSET 2
bool fifo_warn;
//Bit8u FCR; // FIFO Control Register
};
extern CSerial* serialports[];
const Bit8u serial_defaultirq[4] = { 4, 3, 4, 3 };
const Bit16u serial_baseaddr[4] = {0x3f8,0x2f8,0x3e8,0x2e8};
const char* const serial_comname[]={"COM1","COM2","COM3","COM4"};
// the COM devices
class device_COM : public DOS_Device {
public:
// Creates a COM device that communicates with the num-th parallel port, i.e. is LPTnum
device_COM(class CSerial* sc);
~device_COM();
bool Read(Bit8u * data,Bit16u * size);
bool Write(Bit8u * data,Bit16u * size);
bool Seek(Bit32u * pos,Bit32u type);
bool Close();
Bit16u GetInformation(void);
private:
CSerial* sclass;
};
#endif

View File

@ -1,331 +1,43 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: setup.h,v 1.40 2009/02/15 20:01:08 qbix79 Exp $ */
#ifndef DOSBOX_SETUP_H
#define DOSBOX_SETUP_H
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#pragma warning ( disable : 4290 )
#endif
#ifndef CH_LIST
#define CH_LIST
#include <list>
#endif
#ifndef CH_VECTOR
#define CH_VECTOR
#include <vector>
#endif
#ifndef CH_STRING
#define CH_STRING
#include <string>
#endif
class Hex {
private:
int _hex;
public:
Hex(int in):_hex(in) { };
Hex():_hex(0) { };
bool operator==(Hex const& other) {return _hex == other._hex;}
operator int () const { return _hex; }
};
class Value {
/*
* Multitype storage container that is aware of the currently stored type in it.
* Value st = "hello";
* Value in = 1;
* st = 12 //Exception
* in = 12 //works
*/
private:
Hex _hex;
bool _bool;
int _int;
std::string* _string;
double _double;
public:
class WrongType { }; // Conversion error class
enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type;
/* Constructors */
Value() :_string(0), type(V_NONE) { };
Value(Hex in) :_hex(in), type(V_HEX) { };
Value(int in) :_int(in), type(V_INT) { };
Value(bool in) :_bool(in), type(V_BOOL) { };
Value(double in) :_double(in), type(V_DOUBLE) { };
Value(std::string const& in) :_string(new std::string(in)),type(V_STRING) { };
Value(char const * const in) :_string(new std::string(in)),type(V_STRING) { };
Value(Value const& in):_string(0) {plaincopy(in);}
~Value() { destroy();};
Value(std::string const& in,Etype _t) :_string(0),type(V_NONE) {SetValue(in,_t);}
/* Assigment operators */
Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));}
Value& operator= (int in) throw(WrongType) { return copy(Value(in));}
Value& operator= (bool in) throw(WrongType) { return copy(Value(in));}
Value& operator= (double in) throw(WrongType) { return copy(Value(in));}
Value& operator= (std::string const& in) throw(WrongType) { return copy(Value(in));}
Value& operator= (char const * const in) throw(WrongType) { return copy(Value(in));}
Value& operator= (Value const& in) throw(WrongType) { return copy(Value(in));}
bool operator== (Value const & other);
operator bool () const throw(WrongType);
operator Hex () const throw(WrongType);
operator int () const throw(WrongType);
operator double () const throw(WrongType);
operator char const* () const throw(WrongType);
void SetValue(std::string const& in,Etype _type = V_CURRENT) throw(WrongType);
std::string ToString() const;
private:
void destroy() throw();
Value& copy(Value const& in) throw(WrongType);
void plaincopy(Value const& in) throw();
void set_hex(std::string const& in);
void set_int(std::string const&in);
void set_bool(std::string const& in);
void set_string(std::string const& in);
void set_double(std::string const& in);
};
class Property {
public:
struct Changeable { enum Value {Always, WhenIdle,OnlyAtStart};};
const std::string propname;
Property(std::string const& _propname, Changeable::Value when):propname(_propname),change(when) { }
void Set_values(const char * const * in);
void Set_help(std::string const& str);
char const* Get_help();
virtual void SetValue(std::string const& str)=0;
Value const& GetValue() const { return value;}
Value const& Get_Default_Value() const { return default_value; }
//CheckValue returns true if value is in suggested_values;
//Type specific properties are encouraged to override this and check for type
//specific features.
virtual bool CheckValue(Value const& in, bool warn);
//Set interval value to in or default if in is invalid. force always sets the value.
void SetVal(Value const& in, bool forced,bool warn=true) {if(forced || CheckValue(in,warn)) value = in; else value = default_value;}
virtual ~Property(){ }
virtual const std::vector<Value>& GetValues() const;
Value::Etype Get_type(){return default_value.type;}
protected:
Value value;
std::vector<Value> suggested_values;
typedef std::vector<Value>::iterator iter;
Value default_value;
const Changeable::Value change;
};
class Prop_int:public Property {
public:
Prop_int(std::string const& _propname,Changeable::Value when, int _value)
:Property(_propname,when) {
default_value = value = _value;
min = max = -1;
}
Prop_int(std::string const& _propname,Changeable::Value when, int _min,int _max,int _value)
:Property(_propname,when) {
default_value = value = _value;
min = _min;
max = _max;
}
void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;}
void SetValue(std::string const& in);
~Prop_int(){ }
virtual bool CheckValue(Value const& in, bool warn);
private:
Value min,max;
};
class Prop_double:public Property {
public:
Prop_double(std::string const & _propname, Changeable::Value when, double _value)
:Property(_propname,when){
default_value = value = _value;
}
void SetValue(std::string const& input);
~Prop_double(){ }
};
class Prop_bool:public Property {
public:
Prop_bool(std::string const& _propname, Changeable::Value when, bool _value)
:Property(_propname,when) {
default_value = value = _value;
}
void SetValue(std::string const& in);
~Prop_bool(){ }
};
class Prop_string:public Property{
public:
Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value)
:Property(_propname,when) {
default_value = value = _value;
}
void SetValue(std::string const& in);
virtual bool CheckValue(Value const& in, bool warn);
~Prop_string(){ }
};
class Prop_path:public Prop_string{
public:
std::string realpath;
Prop_path(std::string const& _propname, Changeable::Value when, char const * const _value)
:Prop_string(_propname,when,_value) {
default_value = value = _value;
realpath = _value;
}
void SetValue(std::string const& in);
~Prop_path(){ }
};
class Prop_hex:public Property {
public:
Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value)
:Property(_propname,when) {
default_value = value = _value;
}
void SetValue(std::string const& in);
~Prop_hex(){ }
};
#define NO_SUCH_PROPERTY "PROP_NOT_EXIST"
class Section {
private:
typedef void (*SectionFunction)(Section*);
/* Wrapper class around startup and shutdown functions. the variable
* canchange indicates it can be called on configuration changes */
struct Function_wrapper {
SectionFunction function;
bool canchange;
Function_wrapper(SectionFunction const _fun,bool _ch){
function=_fun;
canchange=_ch;
}
};
std::list<Function_wrapper> initfunctions;
std::list<Function_wrapper> destroyfunctions;
std::string sectionname;
public:
Section(std::string const& _sectionname):sectionname(_sectionname) { }
void AddInitFunction(SectionFunction func,bool canchange=false);
void AddDestroyFunction(SectionFunction func,bool canchange=false);
void ExecuteInit(bool initall=true);
void ExecuteDestroy(bool destroyall=true);
const char* GetName() const {return sectionname.c_str();}
virtual std::string GetPropValue(std::string const& _property) const =0;
virtual void HandleInputline(std::string const& _line)=0;
virtual void PrintData(FILE* outfile) const =0;
virtual ~Section() { /*Children must call executedestroy ! */}
};
class Prop_multival;
class Prop_multival_remain;
class Section_prop:public Section {
private:
std::list<Property*> properties;
typedef std::list<Property*>::iterator it;
typedef std::list<Property*>::const_iterator const_it;
public:
Section_prop(std::string const& _sectionname):Section(_sectionname){}
Prop_int* Add_int(std::string const& _propname, Property::Changeable::Value when, int _value=0);
Prop_string* Add_string(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL);
Prop_path* Add_path(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL);
Prop_bool* Add_bool(std::string const& _propname, Property::Changeable::Value when, bool _value=false);
Prop_hex* Add_hex(std::string const& _propname, Property::Changeable::Value when, Hex _value=0);
// void Add_double(char const * const _propname, double _value=0.0);
Prop_multival *Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep);
Prop_multival_remain *Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep);
Property* Get_prop(int index);
int Get_int(std::string const& _propname) const;
const char* Get_string(std::string const& _propname) const;
bool Get_bool(std::string const& _propname) const;
Hex Get_hex(std::string const& _propname) const;
double Get_double(std::string const& _propname) const;
Prop_path* Get_path(std::string const& _propname) const;
Prop_multival* Get_multival(std::string const& _propname) const;
Prop_multival_remain* Get_multivalremain(std::string const& _propname) const;
void HandleInputline(std::string const& gegevens);
void PrintData(FILE* outfile) const;
virtual std::string GetPropValue(std::string const& _property) const;
//ExecuteDestroy should be here else the destroy functions use destroyed properties
virtual ~Section_prop();
};
class Prop_multival:public Property{
protected:
Section_prop* section;
std::string seperator;
void make_default_value();
public:
Prop_multival(std::string const& _propname, Changeable::Value when,std::string const& sep):Property(_propname,when), section(new Section_prop("")),seperator(sep) {
default_value = value = "";
}
Section_prop *GetSection() { return section; }
const Section_prop *GetSection() const { return section; }
virtual void SetValue(std::string const& input);
virtual const std::vector<Value>& GetValues() const;
~Prop_multival() { delete section; }
}; //value bevat totale string. setvalue zet elk van de sub properties en checked die.
class Prop_multival_remain:public Prop_multival{
public:
Prop_multival_remain(std::string const& _propname, Changeable::Value when,std::string const& sep):Prop_multival(_propname,when,sep){ }
virtual void SetValue(std::string const& input);
};
class Section_line: public Section{
public:
Section_line(std::string const& _sectionname):Section(_sectionname){}
~Section_line(){ExecuteDestroy(true);}
void HandleInputline(std::string const& gegevens);
void PrintData(FILE* outfile) const;
virtual std::string GetPropValue(std::string const& _property) const;
std::string data;
};
class Module_base {
/* Base for all hardware and software "devices" */
protected:
Section* m_configuration;
public:
Module_base(Section* configuration){m_configuration=configuration;};
// Module_base(Section* configuration, SaveState* state) {};
virtual ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required
/* Returns true if succesful.*/
virtual bool Change_Config(Section* /*newconfig*/) {return false;} ;
};
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _SETUP_H_
#define _SETUP_H_
#include <cross.h>
enum { S_STRING,S_HEX,S_INT,S_BOOL};
typedef char *(String_Handler)(char * input);
typedef char *(Hex_Handler)(Bitu * input);
typedef char *(Int_Handler)(Bits * input);
typedef char *(Bool_Handler)(bool input);
class Setup {
private:
int argc;
char * * argv;
};
extern char dosbox_basedir[CROSS_LEN];
#endif

View File

@ -1,144 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell.h,v 1.26 2009/03/23 10:55:35 qbix79 Exp $ */
#ifndef DOSBOX_SHELL_H
#define DOSBOX_SHELL_H
#include <ctype.h>
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#ifndef DOSBOX_PROGRAMS_H
#include "programs.h"
#endif
#include <string>
#include <list>
#define CMD_MAXLINE 4096
#define CMD_MAXCMDS 20
#define CMD_OLDSIZE 4096
extern Bitu call_shellstop;
/* first_shell is used to add and delete stuff from the shell env
* by "external" programs. (config) */
extern Program * first_shell;
class DOS_Shell;
class BatchFile {
public:
BatchFile(DOS_Shell * host,char const* const name, char const * const cmd_line);
virtual ~BatchFile();
virtual bool ReadLine(char * line);
bool Goto(char * where);
void Shift(void);
Bit16u file_handle;
Bit32u location;
bool echo;
DOS_Shell * shell;
BatchFile * prev;
CommandLine * cmd;
};
class AutoexecEditor;
class DOS_Shell : public Program {
private:
friend class AutoexecEditor;
std::list<std::string> l_history, l_completion;
char *completion_start;
Bit16u completion_index;
public:
DOS_Shell();
void Run(void);
void RunInternal(void); //for command /C
/* A load of subfunctions */
void ParseLine(char * line);
Bitu GetRedirection(char *s, char **ifn, char **ofn,bool * append);
void InputCommand(char * line);
void ShowPrompt();
void DoCommand(char * cmd);
bool Execute(char * name,char * args);
/* Checks if it matches a hardware-property */
bool CheckConfig(char* cmd_in,char*line);
/* Some internal used functions */
char * Which(char * name);
/* Some supported commands */
void CMD_HELP(char * args);
void CMD_CLS(char * args);
void CMD_COPY(char * args);
void CMD_DIR(char * args);
void CMD_DELETE(char * args);
void CMD_ECHO(char * args);
void CMD_EXIT(char * args);
void CMD_MKDIR(char * args);
void CMD_CHDIR(char * args);
void CMD_RMDIR(char * args);
void CMD_SET(char * args);
void CMD_IF(char * args);
void CMD_GOTO(char * args);
void CMD_TYPE(char * args);
void CMD_REM(char * args);
void CMD_RENAME(char * args);
void CMD_CALL(char * args);
void SyntaxError(void);
void CMD_PAUSE(char * args);
void CMD_SUBST(char* args);
void CMD_LOADHIGH(char* args);
void CMD_CHOICE(char * args);
void CMD_ATTRIB(char * args);
void CMD_PATH(char * args);
void CMD_SHIFT(char * args);
void CMD_VER(char * args);
/* The shell's variables */
Bit16u input_handle;
BatchFile * bf;
bool echo;
bool exit;
bool call;
};
struct SHELL_Cmd {
const char * name; /* Command name*/
Bit32u flags; /* Flags about the command */
void (DOS_Shell::*handler)(char * args); /* Handler for this command */
const char * help; /* String with command help */
};
/* Object to manage lines in the autoexec.bat The lines get removed from
* the file if the object gets destroyed. The environment is updated
* as well if the line set a a variable */
class AutoexecObject{
private:
bool installed;
std::string buf;
public:
AutoexecObject():installed(false){ };
void Install(std::string const &in);
void InstallBefore(std::string const &in);
~AutoexecObject();
private:
void CreateAutoexec(void);
};
#endif

View File

@ -1,60 +1,63 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: support.h,v 1.17 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_SUPPORT_H
#define DOSBOX_SUPPORT_H
#include <string.h>
#include <string>
#include <ctype.h>
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
#if defined (_MSC_VER) /* MS Visual C++ */
#define strcasecmp(a,b) stricmp(a,b)
#define strncasecmp(a,b,n) _strnicmp(a,b,n)
#endif
#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0)
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
void strreplace(char * str,char o,char n);
char *ltrim(char *str);
char *rtrim(char *str);
char *trim(char * str);
char * upcase(char * str);
char * lowcase(char * str);
bool ScanCMDBool(char * cmd,char const * const check);
char * ScanCMDRemain(char * cmd);
char * StripWord(char *&cmd);
bool IsDecWord(char * word);
bool IsHexWord(char * word);
Bits ConvDecWord(char * word);
Bits ConvHexWord(char * word);
void upcase(std::string &str);
void lowcase(std::string &str);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined __SUPPORT_H
#define __SUPPORT_H
#include <dosbox.h>
#include <string.h>
#include <ctype.h>
#if defined (_MSC_VER) /* MS Visual C++ */
#define strcasecmp(a,b) stricmp(a,b)
#define strncasecmp(a,b,n) _strnicmp(a,b,n)
// if (stricmp(name,devices[index]->name)==0) return index;
#else
//if (strcasecmp(name,devices[index]->name)==0) return index;
//#define nocasestrcmp(a,b) stricmp(a,b)
#endif
void strreplace(char * str,char o,char n);
char *ltrim(char *str);
void rtrim(char * const str);
char *trim(char *str);
bool wildcmp(char *wild, char *string);
bool ScanCMDBool(char * cmd,char * check);
char * ScanCMDRemain(char * cmd);
bool ScanCMDHex(char * cmd,char * check,Bits * result);
char * StripWord(char * cmd);
INLINE char * upcase(char * str) {
char * oldstr=str;
while (*str) *str++=toupper(*str);
return oldstr;
}
INLINE char * lowcase(char * str) {
char * oldstr=str;
while (*str) *str++=tolower(*str);
return oldstr;
}
#endif

View File

@ -1,38 +1,53 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_TIMER_H
#define DOSBOX_TIMER_H
/* underlying clock rate in HZ */
#include <SDL.h>
#define PIT_TICK_RATE 1193182
#define GetTicks() SDL_GetTicks()
typedef void (*TIMER_TickHandler)(void);
/* Register a function that gets called everytime if 1 or more ticks pass */
void TIMER_AddTickHandler(TIMER_TickHandler handler);
void TIMER_DelTickHandler(TIMER_TickHandler handler);
/* This will add 1 milliscond to all timers */
void TIMER_AddTick(void);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _TIMER_H_
#define _TIMER_H_
/* underlying clock rate in HZ */
#include <SDL/SDL.h>
extern Bit32u LastTicks;
#define GetTicks() SDL_GetTicks()
typedef void (*TIMER_TickHandler)(Bitu ticks);
typedef void (*TIMER_MicroHandler)(void);
typedef void (*TIMER_DelayHandler)(void);
typedef void TIMER_Block;
/* Register a function that gets called everytime if 1 or more ticks pass */
TIMER_Block * TIMER_RegisterTickHandler(TIMER_TickHandler handler);
/* Register a function to be called every x microseconds */
TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro);
/* Register a function to be called once after x microseconds */
TIMER_Block * TIMER_RegisterDelayHandler(TIMER_DelayHandler handler,Bitu delay);
/* Set the microseconds value to a new value */
void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro);
/* This function should be called very often to support very high res timers
Although with the new timer code it doesn't matter that much */
void TIMER_CheckPIT(void);
/* This will add ms ticks to support the timer handlers */
void TIMER_AddTicks(Bit32u ticks);
#endif

View File

@ -1,509 +0,0 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga.h,v 1.46 2009/03/15 11:28:34 c2woody Exp $ */
#ifndef DOSBOX_VGA_H
#define DOSBOX_VGA_H
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
//Don't enable keeping changes and mapping lfb probably...
#define VGA_LFB_MAPPED
//#define VGA_KEEP_CHANGES
#define VGA_CHANGE_SHIFT 9
class PageHandler;
enum VGAModes {
M_CGA2, M_CGA4,
M_EGA, M_VGA,
M_LIN4, M_LIN8, M_LIN15, M_LIN16, M_LIN32,
M_TEXT,
M_HERC_GFX, M_HERC_TEXT,
M_CGA16, M_TANDY2, M_TANDY4, M_TANDY16, M_TANDY_TEXT,
M_ERROR
};
#define CLK_25 25175
#define CLK_28 28322
#define MIN_VCO 180000
#define MAX_VCO 360000
#define S3_CLOCK_REF 14318 /* KHz */
#define S3_CLOCK(_M,_N,_R) ((S3_CLOCK_REF * ((_M) + 2)) / (((_N) + 2) * (1 << (_R))))
#define S3_MAX_CLOCK 150000 /* KHz */
#define S3_XGA_1024 0x00
#define S3_XGA_1152 0x01
#define S3_XGA_640 0x40
#define S3_XGA_800 0x80
#define S3_XGA_1280 0xc0
#define S3_XGA_WMASK (S3_XGA_640|S3_XGA_800|S3_XGA_1024|S3_XGA_1152|S3_XGA_1280)
#define S3_XGA_8BPP 0x00
#define S3_XGA_16BPP 0x10
#define S3_XGA_32BPP 0x30
#define S3_XGA_CMASK (S3_XGA_8BPP|S3_XGA_16BPP|S3_XGA_32BPP)
typedef struct {
bool attrindex;
} VGA_Internal;
typedef struct {
/* Memory handlers */
Bitu mh_mask;
/* Video drawing */
Bitu display_start;
Bitu real_start;
bool retrace; /* A retrace is active */
Bitu scan_len;
Bitu cursor_start;
/* Some other screen related variables */
Bitu line_compare;
bool chained; /* Enable or Disabled Chain 4 Mode */
bool compatible_chain4;
/* Pixel Scrolling */
Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */
Bit8u hlines_skip;
Bit8u bytes_skip;
Bit8u addr_shift;
/* Specific stuff memory write/read handling */
Bit8u read_mode;
Bit8u write_mode;
Bit8u read_map_select;
Bit8u color_dont_care;
Bit8u color_compare;
Bit8u data_rotate;
Bit8u raster_op;
Bit32u full_bit_mask;
Bit32u full_map_mask;
Bit32u full_not_map_mask;
Bit32u full_set_reset;
Bit32u full_not_enable_set_reset;
Bit32u full_enable_set_reset;
Bit32u full_enable_and_set_reset;
} VGA_Config;
typedef struct {
bool resizing;
Bitu width;
Bitu height;
Bitu blocks;
Bitu address;
Bitu panning;
Bitu bytes_skip;
Bit8u *linear_base;
Bitu linear_mask;
Bitu address_add;
Bitu line_length;
Bitu address_line_total;
Bitu address_line;
Bitu lines_total;
Bitu lines_done;
Bitu lines_scaled;
Bitu split_line;
Bitu parts_total;
Bitu parts_lines;
Bitu parts_left;
Bitu byte_panning_shift;
struct {
double framestart;
double vrstart, vrend; // V-retrace
double hrstart, hrend; // H-retrace
double hblkstart, hblkend; // H-blanking
double vblkstart, vblkend; // V-Blanking
double vdend, vtotal;
double hdend, htotal;
double parts;
} delay;
double aspect_ratio;
bool double_scan;
bool doublewidth,doubleheight;
Bit8u font[64*1024];
Bit8u * font_tables[2];
Bitu blinking;
struct {
Bitu address;
Bit8u sline,eline;
Bit8u count,delay;
Bit8u enabled;
} cursor;
bool vret_triggered;
} VGA_Draw;
typedef struct {
Bit8u curmode;
Bit16u originx, originy;
Bit8u fstackpos, bstackpos;
Bit8u forestack[3];
Bit8u backstack[3];
Bit16u startaddr;
Bit8u posx, posy;
Bit8u mc[64][64];
} VGA_HWCURSOR;
typedef struct {
Bit8u reg_lock1;
Bit8u reg_lock2;
Bit8u reg_31;
Bit8u reg_35;
Bit8u reg_36; // RAM size
Bit8u reg_3a; // 4/8/doublepixel bit in there
Bit8u reg_40; // 8415/A functionality register
Bit8u reg_41; // BIOS flags
Bit8u reg_43;
Bit8u reg_45; // Hardware graphics cursor
Bit8u reg_50;
Bit8u reg_51;
Bit8u reg_52;
Bit8u reg_55;
Bit8u reg_58;
Bit8u reg_6b; // LFB BIOS scratchpad
Bit8u ex_hor_overflow;
Bit8u ex_ver_overflow;
Bit16u la_window;
Bit8u misc_control_2;
Bit8u ext_mem_ctrl;
Bitu xga_screen_width;
VGAModes xga_color_mode;
struct {
Bit8u r;
Bit8u n;
Bit8u m;
} clk[4],mclk;
struct {
Bit8u lock;
Bit8u cmd;
} pll;
VGA_HWCURSOR hgc;
} VGA_S3;
typedef struct {
Bit8u mode_control;
Bit8u enable_bits;
} VGA_HERC;
typedef struct {
Bit8u index;
Bit8u htotal;
Bit8u hdend;
Bit8u hsyncp;
Bit8u syncw;
Bit8u vtotal;
Bit8u vdend;
Bit8u vadjust;
Bit8u vsyncp;
Bit8u vsyncw;
Bit8u max_scanline;
Bit8u lpen_low, lpen_high;
Bit8u cursor_start;
Bit8u cursor_end;
} VGA_OTHER;
typedef struct {
Bit8u pcjr_flipflop;
Bit8u mode_control;
Bit8u color_select;
Bit8u disp_bank;
Bit8u reg_index;
Bit8u gfx_control;
Bit8u palette_mask;
Bit8u extended_ram;
Bit8u border_color;
Bit8u line_mask, line_shift;
Bit8u draw_bank, mem_bank;
Bit8u *draw_base, *mem_base;
Bitu addr_mask;
} VGA_TANDY;
typedef struct {
Bit8u index;
Bit8u reset;
Bit8u clocking_mode;
Bit8u map_mask;
Bit8u character_map_select;
Bit8u memory_mode;
} VGA_Seq;
typedef struct {
Bit8u palette[16];
Bit8u mode_control;
Bit8u horizontal_pel_panning;
Bit8u overscan_color;
Bit8u color_plane_enable;
Bit8u color_select;
Bit8u index;
Bit8u enabled;
} VGA_Attr;
typedef struct {
Bit8u horizontal_total;
Bit8u horizontal_display_end;
Bit8u start_horizontal_blanking;
Bit8u end_horizontal_blanking;
Bit8u start_horizontal_retrace;
Bit8u end_horizontal_retrace;
Bit8u vertical_total;
Bit8u overflow;
Bit8u preset_row_scan;
Bit8u maximum_scan_line;
Bit8u cursor_start;
Bit8u cursor_end;
Bit8u start_address_high;
Bit8u start_address_low;
Bit8u cursor_location_high;
Bit8u cursor_location_low;
Bit8u vertical_retrace_start;
Bit8u vertical_retrace_end;
Bit8u vertical_display_end;
Bit8u offset;
Bit8u underline_location;
Bit8u start_vertical_blanking;
Bit8u end_vertical_blanking;
Bit8u mode_control;
Bit8u line_compare;
Bit8u index;
bool read_only;
} VGA_Crtc;
typedef struct {
Bit8u index;
Bit8u set_reset;
Bit8u enable_set_reset;
Bit8u color_compare;
Bit8u data_rotate;
Bit8u read_map_select;
Bit8u mode;
Bit8u miscellaneous;
Bit8u color_dont_care;
Bit8u bit_mask;
} VGA_Gfx;
typedef struct {
Bit8u red;
Bit8u green;
Bit8u blue;
} RGBEntry;
typedef struct {
Bit8u bits; /* DAC bits, usually 6 or 8 */
Bit8u pel_mask;
Bit8u pel_index;
Bit8u state;
Bit8u write_index;
Bit8u read_index;
Bitu first_changed;
Bit8u combine[16];
RGBEntry rgb[0x100];
Bit16u xlat16[256];
} VGA_Dac;
typedef struct {
Bitu readStart, writeStart;
Bitu bankMask;
Bitu bank_read_full;
Bitu bank_write_full;
Bit8u bank_read;
Bit8u bank_write;
Bitu bank_size;
} VGA_SVGA;
typedef union {
Bit32u d;
Bit8u b[4];
} VGA_Latch;
typedef struct {
Bit8u* linear;
Bit8u* linear_orgptr;
} VGA_Memory;
typedef struct {
//Add a few more just to be safe
Bit8u* map; /* allocated dynamically: [(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32] */
Bit8u checkMask, frame, writeMask;
bool active;
Bit32u clearMask;
Bit32u start, last;
Bit32u lastAddress;
} VGA_Changes;
typedef struct {
Bit32u page;
Bit32u addr;
Bit32u mask;
PageHandler *handler;
} VGA_LFB;
typedef struct {
VGAModes mode; /* The mode the vga system is in */
VGAModes lastmode;
Bits screenflip;
Bit8u misc_output;
VGA_Draw draw;
VGA_Config config;
VGA_Internal internal;
/* Internal module groups */
VGA_Seq seq;
VGA_Attr attr;
VGA_Crtc crtc;
VGA_Gfx gfx;
VGA_Dac dac;
VGA_Latch latch;
VGA_S3 s3;
VGA_SVGA svga;
VGA_HERC herc;
VGA_TANDY tandy;
VGA_OTHER other;
VGA_Memory mem;
Bit32u vmemwrap; /* this is assumed to be power of 2 */
Bit8u* fastmem; /* memory for fast (usually 16-color) rendering, always twice as big as vmemsize */
Bit8u* fastmem_orgptr;
Bit32u vmemsize;
#ifdef VGA_KEEP_CHANGES
VGA_Changes changes;
#endif
VGA_LFB lfb;
} VGA_Type;
/* Functions for different resolutions */
void VGA_SetMode(VGAModes mode);
void VGA_DetermineMode(void);
void VGA_SetupHandlers(void);
void VGA_StartResize(Bitu delay=50);
void VGA_SetupDrawing(Bitu val);
void VGA_CheckScanLength(void);
void VGA_ChangedBank(void);
/* Some DAC/Attribute functions */
void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal);
void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue);
void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
/* The VGA Subfunction startups */
void VGA_SetupAttr(void);
void VGA_SetupMemory(Section* sec);
void VGA_SetupDAC(void);
void VGA_SetupCRTC(void);
void VGA_SetupMisc(void);
void VGA_SetupGFX(void);
void VGA_SetupSEQ(void);
void VGA_SetupOther(void);
void VGA_SetupXGA(void);
/* Some Support Functions */
void VGA_SetClock(Bitu which,Bitu target);
void VGA_DACSetEntirePalette(void);
void VGA_StartRetrace(void);
void VGA_StartUpdateLFB(void);
void VGA_SetBlinking(Bitu enabled);
void VGA_SetCGA2Table(Bit8u val0,Bit8u val1);
void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3);
void VGA_ActivateHardwareCursor(void);
void VGA_KillDrawing(void);
extern VGA_Type vga;
/* Support for modular SVGA implementation */
/* Video mode extra data to be passed to FinishSetMode_SVGA().
This structure will be in flux until all drivers (including S3)
are properly separated. Right now it contains only three overflow
fields in S3 format and relies on drivers re-interpreting those.
For reference:
ver_overflow:X|line_comp10|X|vretrace10|X|vbstart10|vdispend10|vtotal10
hor_overflow:X|X|X|hretrace8|X|hblank8|hdispend8|htotal8
offset is not currently used by drivers (useful only for S3 itself)
It also contains basic int10 mode data - number, vtotal, htotal
*/
typedef struct {
Bit8u ver_overflow;
Bit8u hor_overflow;
Bitu offset;
Bitu modeNo;
Bitu htotal;
Bitu vtotal;
} VGA_ModeExtraData;
// Vector function prototypes
typedef void (*tWritePort)(Bitu reg,Bitu val,Bitu iolen);
typedef Bitu (*tReadPort)(Bitu reg,Bitu iolen);
typedef void (*tFinishSetMode)(Bitu crtc_base, VGA_ModeExtraData* modeData);
typedef void (*tDetermineMode)();
typedef void (*tSetClock)(Bitu which,Bitu target);
typedef Bitu (*tGetClock)();
typedef bool (*tHWCursorActive)();
typedef bool (*tAcceptsMode)(Bitu modeNo);
struct SVGA_Driver {
tWritePort write_p3d5;
tReadPort read_p3d5;
tWritePort write_p3c5;
tReadPort read_p3c5;
tWritePort write_p3c0;
tReadPort read_p3c1;
tWritePort write_p3cf;
tReadPort read_p3cf;
tFinishSetMode set_video_mode;
tDetermineMode determine_mode;
tSetClock set_clock;
tGetClock get_clock;
tHWCursorActive hardware_cursor_active;
tAcceptsMode accepts_mode;
};
extern SVGA_Driver svga;
void SVGA_Setup_S3Trio(void);
void SVGA_Setup_TsengET4K(void);
void SVGA_Setup_TsengET3K(void);
void SVGA_Setup_ParadisePVGA1A(void);
void SVGA_Setup_Driver(void);
// Amount of video memory required for a mode, implemented in int10_modes.cpp
Bitu VideoModeMemSize(Bitu mode);
extern Bit32u ExpandTable[256];
extern Bit32u FillTable[16];
extern Bit32u CGA_2_Table[16];
extern Bit32u CGA_4_Table[256];
extern Bit32u CGA_4_HiRes_Table[256];
extern Bit32u CGA_16_Table[256];
extern Bit32u TXT_Font_Table[16];
extern Bit32u TXT_FG_Table[16];
extern Bit32u TXT_BG_Table[16];
extern Bit32u Expand16Table[4][16];
extern Bit32u Expand16BigTable[0x10000];
#endif

View File

@ -1,85 +1,50 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: video.h,v 1.25 2008/08/24 16:43:06 qbix79 Exp $ */
#ifndef DOSBOX_VIDEO_H
#define DOSBOX_VIDEO_H
#define REDUCE_JOYSTICK_POLLING
typedef enum {
GFX_CallBackReset,
GFX_CallBackStop,
GFX_CallBackRedraw
} GFX_CallBackFunctions_t;
typedef void (*GFX_CallBack_t)( GFX_CallBackFunctions_t function );
struct GFX_PalEntry {
Bit8u r;
Bit8u g;
Bit8u b;
Bit8u unused;
};
#define GFX_CAN_8 0x0001
#define GFX_CAN_15 0x0002
#define GFX_CAN_16 0x0004
#define GFX_CAN_32 0x0008
#define GFX_LOVE_8 0x0010
#define GFX_LOVE_15 0x0020
#define GFX_LOVE_16 0x0040
#define GFX_LOVE_32 0x0080
#define GFX_RGBONLY 0x0100
#define GFX_SCALING 0x1000
#define GFX_HARDWARE 0x2000
#define GFX_CAN_RANDOM 0x4000 //If the interface can also do random access surface
void GFX_Events(void);
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries);
Bitu GFX_GetBestMode(Bitu flags);
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue);
Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t cb);
void GFX_ResetScreen(void);
void GFX_Start(void);
void GFX_Stop(void);
void GFX_SwitchFullScreen(void);
bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch);
void GFX_EndUpdate( const Bit16u *changedLines );
void GFX_GetSize(int &width, int &height, bool &fullscreen);
void GFX_LosingFocus(void);
#if defined (WIN32)
bool GFX_SDLUsingWinDIB(void);
#endif
#if defined (REDUCE_JOYSTICK_POLLING)
void MAPPER_UpdateJoysticks(void);
#endif
/* Mouse related */
void GFX_CaptureMouse(void);
extern bool mouselocked; //true if mouse is confined to window
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __VIDEO_H
#define __VIDEO_H
typedef void (GFX_DrawHandler)(Bit8u * vidstart);
/* Used to reply to the renderer what size to set */
typedef void (GFX_ResizeHandler)(Bitu * width,Bitu * height);
struct GFX_PalEntry {
Bit8u r;
Bit8u g;
Bit8u b;
Bit8u unused;
};
struct GFX_Info {
Bitu width,height,bpp,pitch;
};
extern GFX_Info gfx_info;
void GFX_Events(void);
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries);
void GFX_SetDrawHandler(GFX_DrawHandler * handler);
void GFX_Resize(Bitu width,Bitu height,Bitu bpp,GFX_ResizeHandler * resize);
void GFX_Start(void);
void GFX_Stop(void);
void GFX_SwitchFullScreen(void);
#endif

251
install-sh Normal file
View File

@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
:
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
:
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
:
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
:
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
:
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
:
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

336
missing Normal file
View File

@ -0,0 +1,336 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing 0.4 - GNU automake"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them.
You can get \`$1Help2man' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
# We have makeinfo, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
tar)
shift
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
fi
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar ${1+"$@"} && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar ${1+"$@"} && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" ${1+"$@"} && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" ${1+"$@"} && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequirements for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0

101
mkinstalldirs Normal file
View File

@ -0,0 +1,101 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case "${1}" in
-h | --help | --h* ) # -h for help
echo "${usage}" 1>&2; exit 0 ;;
-m ) # -m PERM arg
shift
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
dirmode="${1}"
shift ;;
-- ) shift; break ;; # stop option processing
-* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
* ) break ;; # first non-opt arg
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi ;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi ;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 3
# End:
# mkinstalldirs ends here

View File

@ -1,149 +0,0 @@
!define VER_MAYOR 0
!define VER_MINOR 72
!define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer"
!define COMP_NAME "DOSBox Team"
!define COPYRIGHT "Copyright © 2002-2008 DOSBox Team"
!define DESCRIPTION "DOSBox Installer"
VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0"
VIAddVersionKey "ProductName" "${APP_NAME}"
VIAddVersionKey "CompanyName" "${COMP_NAME}"
VIAddVersionKey "FileDescription" "${DESCRIPTION}"
VIAddVersionKey "FileVersion" "${VER_MAYOR}.${VER_MINOR}.0.0"
VIAddVersionKey "ProductVersion" "${VER_MAYOR}, ${VER_MINOR}, 0, 0"
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
; The name of the installer
Name "${APP_NAME}"
; The file to write
OutFile "DOSBox${VER_MAYOR}.${VER_MINOR}-win32-installer.exe"
; The default installation directory
InstallDir "$PROGRAMFILES\DOSBox-${VER_MAYOR}.${VER_MINOR}"
; The text to prompt the user to enter a directory
DirText "This will install DOSBox v${VER_MAYOR}.${VER_MINOR} on your computer. Choose a directory"
SetCompressor /solid lzma
LicenseData COPYING
LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" "Next >"
; Else vista enables compatibility mode
RequestExecutionLevel admin
ComponentText "Select components for DOSBox"
; The stuff to install
Section "!Core files" Core
; Set output path to the installation directory.
ClearErrors
SetOutPath $INSTDIR
IfErrors error_createdir
SectionIn RO
; Put file there
CreateDirectory "$INSTDIR\capture"
CreateDirectory "$INSTDIR\zmbv"
File /oname=README.txt README
File /oname=COPYING.txt COPYING
File /oname=THANKS.txt THANKS
File /oname=NEWS.txt NEWS
File /oname=AUTHORS.txt AUTHORS
File /oname=INSTALL.txt INSTALL
File DOSBox.exe
File dosbox.conf
File SDL.dll
File SDL_net.dll
File /oname=zmbv\zmbv.dll zmbv.dll
File /oname=zmbv\zmbv.inf zmbv.inf
File /oname=zmbv\README.txt README.video
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole -conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk" "$INSTDIR\README.txt"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk" "notepad.exe" "$INSTDIR\dosbox.conf"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\capture"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk" "$INSTDIR\zmbv\README.txt"
;change outpath so the working directory gets set to zmbv
SetOutPath "$INSTDIR\zmbv"
; Shortcut creation depends on wether we are 9x of NT
ClearErrors
ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
IfErrors we_9x we_nt
we_nt:
;shortcut for win NT
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll32" "setupapi,InstallHinfSection DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf"
goto end
we_9x:
;shortcut for we_9x
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll" "setupx.dll,InstallHinfSection DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf"
end:
SetOutPath $INSTDIR
WriteUninstaller "uninstall.exe"
goto end_section
error_createdir:
MessageBox MB_OK "Can't create DOSBox program directory, aborting."
Abort
goto end_section
end_section:
SectionEnd ; end the section
Section "Desktop Shortcut" SecDesktop
CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
SectionEnd ; end the section
UninstallText "This will uninstall DOSBox v${VER_MAYOR}.${VER_MINOR}. Hit next to continue."
Section "Uninstall"
Delete "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk"
; remove registry keys
; remove files
Delete $INSTDIR\README.txt
Delete $INSTDIR\COPYING.txt
Delete $INSTDIR\THANKS.txt
Delete $INSTDIR\NEWS.txt
Delete $INSTDIR\AUTHORS.txt
Delete $INSTDIR\INSTALL.txt
Delete $INSTDIR\DOSBox.exe
Delete $INSTDIR\dosbox.conf
Delete $INSTDIR\SDL.dll
Delete $INSTDIR\SDL_net.dll
Delete $INSTDIR\zmbv\zmbv.dll
Delete $INSTDIR\zmbv\zmbv.inf
Delete $INSTDIR\zmbv\README.txt
;Files left by sdl taking over the console
Delete $INSTDIR\stdout.txt
Delete $INSTDIR\stderr.txt
; MUST REMOVE UNINSTALLER, too
Delete $INSTDIR\uninstall.exe
; remove shortcuts, if any.
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk"
; remove directories used.
RMDir "$INSTDIR\zmbv"
RMDir "$INSTDIR\capture"
RMDir "$INSTDIR"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
SectionEnd
; eof

View File

@ -1,32 +0,0 @@
#!/usr/bin/perl
use integer;
open (THEFILE,'>','../src/hardware/ega-switch.h')
or die "Can't open my file $!";
print THEFILE "switch (bit_mask) {\n";
for ($i = 0; $i < 256; $i++) {
print THEFILE "\tcase $i:\n";
$b=128;
$add=0;
do {
if ($i & $b) {
print THEFILE "\t{\n";
print THEFILE "\t\tBit8u color=0;\n";
print THEFILE "\t\tif (pixels.b[0] & $b) color|=1;\n";
print THEFILE "\t\tif (pixels.b[1] & $b) color|=2;\n";
print THEFILE "\t\tif (pixels.b[2] & $b) color|=4;\n";
print THEFILE "\t\tif (pixels.b[3] & $b) color|=8;\n";
print THEFILE "\t\t*(write_pixels+$add)=color;\n";
print THEFILE "\t\t*(write_pixels+$add+512*1024)=color;\n";
print THEFILE "\t}\n";
}
$b=$b >> 1;
$add=$add+1;
} until ($b == 0);
print THEFILE "\tbreak;\n";
}
print THEFILE "}\n";
close (THEFILE);

View File

@ -1,25 +0,0 @@
#!/usr/bin/perl
use integer;
open (THEFILE,'>','../src/hardware/font-switch.h')
or die "Can't open my file $!";
print THEFILE "switch (bit_mask) {\n";
for ($i = 0; $i < 256; $i++) {
print THEFILE "\tcase $i:\n";
$b=128;
$add=0;
do {
if ($i & $b) {
print THEFILE "\t\t*(draw+$add)=fg;\n";
} else {
print THEFILE "\t\t*(draw+$add)=bg;\n";
}
$b=$b >> 1;
$add=$add+1;
} until ($b == 0);
print THEFILE "\tbreak;\n";
}
print THEFILE "}\n";
close (THEFILE);

26
settings.h Normal file
View File

@ -0,0 +1,26 @@
/* Enable the debugger */
//#define C_DEBUG
/* Enable logging of debug information */
//#define C_LOGGING
/* Use multi threading to speed up things on multi cpu's, also gives a nice frame-skipping effect :) */
#define C_THREADED
/* Enable debugging for several modules, requires C_LOGGING */
#define DEBUG_SBLASTER /* SoundBlaster Debugging*/
#define DEBUG_DMA /* DMA Debugging */
#define DEBUG_DOS /* DOS Debugging */
#define LOG_MSG S_Warn
#ifdef C_LOGGING
#define LOG_DEBUG S_Warn
#define LOG_WARN S_Warn
#define LOG_ERROR S_Warn
#else
#define LOG_DEBUG
#define LOG_WARN
#define LOG_ERROR
#endif

View File

@ -1,20 +1,10 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
SUBDIRS = cpu debug dos fpu gui hardware libs ints misc shell platform
bin_PROGRAMS = dosbox
if HAVE_WINDRES
ico_stuff = winres.rc
endif
.rc.o:
$(WINDRES) -o $@ $<
dosbox_SOURCES = dosbox.cpp $(ico_stuff)
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a
EXTRA_DIST = winres.rc dosbox.ico
AM_CPPFLAGS = -I$(top_srcdir)/include
SUBDIRS = cpu debug dos fpu gui hardware ints misc shell platform
bin_PROGRAMS = dosbox
dosbox_SOURCES = dosbox.cpp
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
ints/libints.a misc/libmisc.a shell/libshell.a -lcurses
EXTRA_DIST = dosbox.lang

420
src/Makefile.in Normal file
View File

@ -0,0 +1,420 @@
# Makefile.in generated by automake 1.6.1 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
AM_CPPFLAGS = -I$(top_srcdir)/include
SUBDIRS = cpu debug dos fpu gui hardware ints misc shell platform
bin_PROGRAMS = dosbox
dosbox_SOURCES = dosbox.cpp
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
ints/libints.a misc/libmisc.a shell/libshell.a -lcurses
EXTRA_DIST = dosbox.lang
subdir = src
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
bin_PROGRAMS = dosbox$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
am_dosbox_OBJECTS = dosbox.$(OBJEXT)
dosbox_OBJECTS = $(am_dosbox_OBJECTS)
dosbox_DEPENDENCIES = cpu/libcpu.a debug/libdebug.a dos/libdos.a \
fpu/libfpu.a hardware/libhardware.a gui/libgui.a ints/libints.a \
misc/libmisc.a shell/libshell.a
dosbox_LDFLAGS =
DEFS = @DEFS@
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dosbox.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
CXXFLAGS = @CXXFLAGS@
DIST_SOURCES = $(dosbox_SOURCES)
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
uninstall-info-recursive all-recursive install-data-recursive \
install-exec-recursive installdirs-recursive install-recursive \
uninstall-recursive check-recursive installcheck-recursive
DIST_COMMON = Makefile.am Makefile.in
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = $(dosbox_SOURCES)
all: all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnits src/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
p1=`echo "$$p1" | sed -e 's,^.*/,,'`; \
f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
f=`echo "$$f" | sed -e 's,^.*/,,'`; \
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
rm -f $(DESTDIR)$(bindir)/$$f; \
done
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
dosbox$(EXEEXT): $(dosbox_OBJECTS) $(dosbox_DEPENDENCIES)
@rm -f dosbox$(EXEEXT)
$(CXXLINK) $(dosbox_LDFLAGS) $(dosbox_OBJECTS) $(dosbox_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dosbox.Po@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
CXXDEPMODE = @CXXDEPMODE@
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(PROGRAMS)
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(bindir)
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-recursive
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am: install-binPROGRAMS
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
clean-binPROGRAMS clean-generic clean-recursive distclean \
distclean-compile distclean-depend distclean-generic \
distclean-recursive distclean-tags distdir dvi dvi-am \
dvi-recursive info info-am info-recursive install install-am \
install-binPROGRAMS install-data install-data-am \
install-data-recursive install-exec install-exec-am \
install-exec-recursive install-info install-info-am \
install-info-recursive install-man install-recursive \
install-strip installcheck installcheck-am installdirs \
installdirs-am installdirs-recursive maintainer-clean \
maintainer-clean-generic maintainer-clean-recursive mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-recursive \
tags tags-recursive uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-info-am \
uninstall-info-recursive uninstall-recursive
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,7 +1,5 @@
SUBDIRS = core_full core_normal core_dyn_x86 core_dynrec
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
paging.cpp lazyflags.h core_normal.cpp core_simple.cpp core_prefetch.cpp \
core_dyn_x86.cpp core_dynrec.cpp
SUBDIRS = core_16
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp

401
src/cpu/Makefile.in Normal file
View File

@ -0,0 +1,401 @@
# Makefile.in generated by automake 1.6.1 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
SUBDIRS = core_16
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp
subdir = src/cpu
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
libcpu_a_AR = $(AR) cru
libcpu_a_LIBADD =
am_libcpu_a_OBJECTS = callback.$(OBJEXT) cpu.$(OBJEXT) flags.$(OBJEXT) \
modrm.$(OBJEXT) slow_16.$(OBJEXT)
libcpu_a_OBJECTS = $(am_libcpu_a_OBJECTS)
DEFS = @DEFS@
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/callback.Po ./$(DEPDIR)/cpu.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/flags.Po ./$(DEPDIR)/modrm.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/slow_16.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
CXXFLAGS = @CXXFLAGS@
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libcpu_a_SOURCES)
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
uninstall-info-recursive all-recursive install-data-recursive \
install-exec-recursive installdirs-recursive install-recursive \
uninstall-recursive check-recursive installcheck-recursive
DIST_COMMON = Makefile.am Makefile.in
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = $(libcpu_a_SOURCES)
all: all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnits src/cpu/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
AR = ar
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libcpu.a: $(libcpu_a_OBJECTS) $(libcpu_a_DEPENDENCIES)
-rm -f libcpu.a
$(libcpu_a_AR) libcpu.a $(libcpu_a_OBJECTS) $(libcpu_a_LIBADD)
$(RANLIB) libcpu.a
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modrm.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slow_16.Po@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
CXXDEPMODE = @CXXDEPMODE@
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(LIBRARIES)
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-recursive
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
clean-generic clean-noinstLIBRARIES clean-recursive distclean \
distclean-compile distclean-depend distclean-generic \
distclean-recursive distclean-tags distdir dvi dvi-am \
dvi-recursive info info-am info-recursive install install-am \
install-data install-data-am install-data-recursive \
install-exec install-exec-am install-exec-recursive \
install-info install-info-am install-info-recursive install-man \
install-recursive install-strip installcheck installcheck-am \
installdirs installdirs-am installdirs-recursive \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-recursive tags tags-recursive \
uninstall uninstall-am uninstall-info-am \
uninstall-info-recursive uninstall-recursive
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,575 +1,172 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: callback.cpp,v 1.40 2009/03/03 18:30:41 c2woody Exp $ */
#include <stdlib.h>
#include <string.h>
#include "dosbox.h"
#include "callback.h"
#include "mem.h"
#include "cpu.h"
/* CallBack are located at 0xF100:0 (see CB_SEG in callback.h)
And they are 16 bytes each and you can define them to behave in certain ways like a
far return or and IRET
*/
CallBack_Handler CallBack_Handlers[CB_MAX];
char* CallBack_Description[CB_MAX];
static Bitu call_stop,call_idle,call_default,call_default2;
Bitu call_priv_io;
static Bitu illegal_handler(void) {
E_Exit("Illegal CallBack Called");
return 1;
}
Bitu CALLBACK_Allocate(void) {
for (Bitu i=1;(i<CB_MAX);i++) {
if (CallBack_Handlers[i]==&illegal_handler) {
CallBack_Handlers[i]=0;
return i;
}
}
E_Exit("CALLBACK:Can't allocate handler.");
return 0;
}
void CALLBACK_DeAllocate(Bitu in) {
CallBack_Handlers[in]=&illegal_handler;
}
void CALLBACK_Idle(void) {
/* this makes the cpu execute instructions to handle irq's and then come back */
Bitu oldIF=GETFLAG(IF);
SETFLAGBIT(IF,true);
Bit16u oldcs=SegValue(cs);
Bit32u oldeip=reg_eip;
SegSet16(cs,CB_SEG);
reg_eip=call_idle*CB_SIZE;
DOSBOX_RunMachine();
reg_eip=oldeip;
SegSet16(cs,oldcs);
SETFLAGBIT(IF,oldIF);
if (!CPU_CycleAutoAdjust && CPU_Cycles>0)
CPU_Cycles=0;
}
static Bitu default_handler(void) {
LOG(LOG_CPU,LOG_ERROR)("Illegal Unhandled Interrupt Called %X",lastint);
return CBRET_NONE;
}
static Bitu stop_handler(void) {
return CBRET_STOP;
}
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) {
reg_sp-=4;
mem_writew(SegPhys(ss)+reg_sp,call_stop*CB_SIZE);
mem_writew(SegPhys(ss)+reg_sp+2,CB_SEG);
Bit32u oldeip=reg_eip;
Bit16u oldcs=SegValue(cs);
reg_eip=off;
SegSet16(cs,seg);
DOSBOX_RunMachine();
reg_eip=oldeip;
SegSet16(cs,oldcs);
}
void CALLBACK_RunRealInt(Bit8u intnum) {
Bit32u oldeip=reg_eip;
Bit16u oldcs=SegValue(cs);
reg_eip=(CB_MAX*CB_SIZE)+(intnum*6);
SegSet16(cs,CB_SEG);
DOSBOX_RunMachine();
reg_eip=oldeip;
SegSet16(cs,oldcs);
}
void CALLBACK_SZF(bool val) {
Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF;
Bit16u newZF=(val==true) << 6;
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newZF));
}
void CALLBACK_SCF(bool val) {
Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFFE;
Bit16u newCF=(val==true);
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF));
}
void CALLBACK_SetDescription(Bitu nr, const char* descr) {
if (descr) {
CallBack_Description[nr] = new char[strlen(descr)+1];
strcpy(CallBack_Description[nr],descr);
} else
CallBack_Description[nr] = 0;
}
const char* CALLBACK_GetDescription(Bitu nr) {
if (nr>=CB_MAX) return 0;
return CallBack_Description[nr];
}
Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_cb=true) {
if (callback>=CB_MAX)
return 0;
switch (type) {
case CB_RETN:
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02, callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xC3); //A RETN Instruction
return (use_cb?5:1);
case CB_RETF:
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02, callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xCB); //A RETF Instruction
return (use_cb?5:1);
case CB_RETF8:
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02, callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xCA); //A RETF 8 Instruction
phys_writew(physAddress+0x01,(Bit16u)0x0008);
return (use_cb?7:3);
case CB_IRET:
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction
return (use_cb?5:1);
case CB_IRETD:
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x66); //An IRETD Instruction
phys_writeb(physAddress+0x01,(Bit8u)0xCF);
return (use_cb?6:2);
case CB_IRET_STI:
phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI
if (use_cb) {
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x03, callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
return (use_cb?6:2);
case CB_IRET_EOI_PIC1:
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
phys_writeb(physAddress+0x01,(Bit8u)0xb0); // mov al, 0x20
phys_writeb(physAddress+0x02,(Bit8u)0x20);
phys_writeb(physAddress+0x03,(Bit8u)0xe6); // out 0x20, al
phys_writeb(physAddress+0x04,(Bit8u)0x20);
phys_writeb(physAddress+0x05,(Bit8u)0x58); // pop ax
phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction
return (use_cb?0x0b:0x07);
case CB_IRQ0: // timer int8
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
phys_writeb(physAddress+0x01,(Bit8u)0x52); // push dx
phys_writeb(physAddress+0x02,(Bit8u)0x1e); // push ds
phys_writew(physAddress+0x03,(Bit16u)0x1ccd); // int 1c
phys_writeb(physAddress+0x05,(Bit8u)0xfa); // cli
phys_writeb(physAddress+0x06,(Bit8u)0x1f); // pop ds
phys_writeb(physAddress+0x07,(Bit8u)0x5a); // pop dx
phys_writew(physAddress+0x08,(Bit16u)0x20b0); // mov al, 0x20
phys_writew(physAddress+0x0a,(Bit16u)0x20e6); // out 0x20, al
phys_writeb(physAddress+0x0c,(Bit8u)0x58); // pop ax
phys_writeb(physAddress+0x0d,(Bit8u)0xcf); //An IRET Instruction
return (use_cb?0x12:0x0e);
case CB_IRQ1: // keyboard int9
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60
phys_writew(physAddress+0x03,(Bit16u)0x4fb4); // mov ah, 0x4f
phys_writeb(physAddress+0x05,(Bit8u)0xf9); // stc
phys_writew(physAddress+0x06,(Bit16u)0x15cd); // int 15
if (use_cb) {
phys_writew(physAddress+0x08,(Bit16u)0x0473); // jc skip
phys_writeb(physAddress+0x0a,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x0b,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x0c,callback); //The immediate word
// jump here to (skip):
physAddress+=6;
}
phys_writeb(physAddress+0x08,(Bit8u)0xfa); // cli
phys_writew(physAddress+0x09,(Bit16u)0x20b0); // mov al, 0x20
phys_writew(physAddress+0x0b,(Bit16u)0x20e6); // out 0x20, al
phys_writeb(physAddress+0x0d,(Bit8u)0x58); // pop ax
phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction
return (use_cb?0x15:0x0f);
case CB_IRQ9: // pic cascade interrupt
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
phys_writew(physAddress+0x01,(Bit16u)0x61b0); // mov al, 0x61
phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al
phys_writew(physAddress+0x05,(Bit16u)0x0acd); // int a
phys_writeb(physAddress+0x07,(Bit8u)0xfa); // cli
phys_writeb(physAddress+0x08,(Bit8u)0x58); // pop ax
phys_writeb(physAddress+0x09,(Bit8u)0xcf); //An IRET Instruction
return (use_cb?0x0e:0x0a);
case CB_IRQ12: // ps2 mouse int74
if (!use_cb) E_Exit("int74 callback must implement a callback handler!");
phys_writeb(physAddress+0x00,(Bit8u)0x1e); // push ds
phys_writeb(physAddress+0x01,(Bit8u)0x06); // push es
phys_writew(physAddress+0x02,(Bit16u)0x6066); // pushad
phys_writeb(physAddress+0x04,(Bit8u)0xfc); // cld
phys_writeb(physAddress+0x05,(Bit8u)0xfb); // sti
phys_writeb(physAddress+0x06,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x07,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x08,callback); //The immediate word
return 0x0a;
case CB_IRQ12_RET: // ps2 mouse int74 return
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xfa); // cli
phys_writew(physAddress+0x01,(Bit16u)0x20b0); // mov al, 0x20
phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al
phys_writew(physAddress+0x05,(Bit16u)0x20e6); // out 0x20, al
phys_writew(physAddress+0x07,(Bit16u)0x6166); // popad
phys_writeb(physAddress+0x09,(Bit8u)0x07); // pop es
phys_writeb(physAddress+0x0a,(Bit8u)0x1f); // pop ds
phys_writeb(physAddress+0x0b,(Bit8u)0xcf); //An IRET Instruction
return (use_cb?0x10:0x0c);
case CB_IRQ6_PCJR: // pcjr keyboard interrupt
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60
phys_writew(physAddress+0x03,(Bit16u)0xe03c); // cmp al, 0xe0
if (use_cb) {
phys_writew(physAddress+0x05,(Bit16u)0x0674); // je skip
phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x09,callback); //The immediate word
physAddress+=4;
} else {
phys_writew(physAddress+0x05,(Bit16u)0x0274); // je skip
}
phys_writew(physAddress+0x07,(Bit16u)0x09cd); // int 9
// jump here to (skip):
phys_writeb(physAddress+0x09,(Bit8u)0xfa); // cli
phys_writew(physAddress+0x0a,(Bit16u)0x20b0); // mov al, 0x20
phys_writew(physAddress+0x0c,(Bit16u)0x20e6); // out 0x20, al
phys_writeb(physAddress+0x0e,(Bit8u)0x58); // pop ax
phys_writeb(physAddress+0x0f,(Bit8u)0xcf); //An IRET Instruction
return (use_cb?0x14:0x10);
case CB_MOUSE:
phys_writew(physAddress+0x00,(Bit16u)0x07eb); // jmp i33hd
physAddress+=9;
// jump here to (i33hd):
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction
return (use_cb?0x0e:0x0a);
case CB_INT16:
phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI
if (use_cb) {
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x03, callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
for (Bitu i=0;i<=0x0b;i++) phys_writeb(physAddress+0x02+i,0x90);
phys_writew(physAddress+0x0e,(Bit16u)0xedeb); //jmp callback
return (use_cb?0x10:0x0c);
case CB_INT29: // fast console output
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
phys_writew(physAddress+0x01,(Bit16u)0x0eb4); // mov ah, 0x0e
phys_writew(physAddress+0x03,(Bit16u)0x10cd); // int 10
phys_writeb(physAddress+0x05,(Bit8u)0x58); // pop ax
phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction
return (use_cb?0x0b:0x07);
case CB_HOOKABLE:
phys_writeb(physAddress+0x00,(Bit8u)0xEB); //jump near
phys_writeb(physAddress+0x01,(Bit8u)0x03); //offset
phys_writeb(physAddress+0x02,(Bit8u)0x90); //NOP
phys_writeb(physAddress+0x03,(Bit8u)0x90); //NOP
phys_writeb(physAddress+0x04,(Bit8u)0x90); //NOP
if (use_cb) {
phys_writeb(physAddress+0x05,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x06,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x07,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x05,(Bit8u)0xCB); //A RETF Instruction
return (use_cb?0x0a:0x06);
case CB_TDE_IRET: // TandyDAC end transfer
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
phys_writeb(physAddress+0x01,(Bit8u)0xb8); // mov ax, 0x91fb
phys_writew(physAddress+0x02,(Bit16u)0x91fb);
phys_writew(physAddress+0x04,(Bit16u)0x15cd); // int 15
phys_writeb(physAddress+0x06,(Bit8u)0xfa); // cli
phys_writew(physAddress+0x07,(Bit16u)0x20b0); // mov al, 0x20
phys_writew(physAddress+0x09,(Bit16u)0x20e6); // out 0x20, al
phys_writeb(physAddress+0x0b,(Bit8u)0x58); // pop ax
phys_writeb(physAddress+0x0c,(Bit8u)0xcf); //An IRET Instruction
return (use_cb?0x11:0x0d);
/* case CB_IPXESR: // IPX ESR
if (!use_cb) E_Exit("ipx esr must implement a callback handler!");
phys_writeb(physAddress+0x00,(Bit8u)0x1e); // push ds
phys_writeb(physAddress+0x01,(Bit8u)0x06); // push es
phys_writew(physAddress+0x02,(Bit16u)0xa00f); // push fs
phys_writew(physAddress+0x04,(Bit16u)0xa80f); // push gs
phys_writeb(physAddress+0x06,(Bit8u)0x60); // pusha
phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x09,callback); //The immediate word
phys_writeb(physAddress+0x0b,(Bit8u)0xCB); //A RETF Instruction
return 0x0c;
case CB_IPXESR_RET: // IPX ESR return
if (use_cb) E_Exit("ipx esr return must not implement a callback handler!");
phys_writeb(physAddress+0x00,(Bit8u)0xfa); // cli
phys_writew(physAddress+0x01,(Bit16u)0x20b0); // mov al, 0x20
phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al
phys_writew(physAddress+0x05,(Bit16u)0x20e6); // out 0x20, al
phys_writeb(physAddress+0x07,(Bit8u)0x61); // popa
phys_writew(physAddress+0x08,(Bit16u)0xA90F); // pop gs
phys_writew(physAddress+0x0a,(Bit16u)0xA10F); // pop fs
phys_writeb(physAddress+0x0c,(Bit8u)0x07); // pop es
phys_writeb(physAddress+0x0d,(Bit8u)0x1f); // pop ds
phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction
return 0x0f; */
case CB_INT21:
phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI
if (use_cb) {
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x03, callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
phys_writeb(physAddress+0x02,(Bit8u)0xCB); //A RETF Instruction
return (use_cb?7:3);
default:
E_Exit("CALLBACK:Setup:Illegal type %d",type);
}
return 0;
}
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr) {
if (callback>=CB_MAX) return false;
CALLBACK_SetupExtra(callback,type,CALLBACK_PhysPointer(callback)+0,(handler!=NULL));
CallBack_Handlers[callback]=handler;
CALLBACK_SetDescription(callback,descr);
return true;
}
Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr) {
if (callback>=CB_MAX) return 0;
Bitu csize=CALLBACK_SetupExtra(callback,type,addr,(handler!=NULL));
if (csize>0) {
CallBack_Handlers[callback]=handler;
CALLBACK_SetDescription(callback,descr);
}
return csize;
}
void CALLBACK_RemoveSetup(Bitu callback) {
for (Bitu i = 0;i < 16;i++) {
phys_writeb(CALLBACK_PhysPointer(callback)+i ,(Bit8u) 0x00);
}
}
CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){
if(!installed) return;
if(m_type == CALLBACK_HandlerObject::SETUP) {
if(vectorhandler.installed){
//See if we are the current handler. if so restore the old one
if(RealGetVec(vectorhandler.interrupt) == Get_RealPointer()) {
RealSetVec(vectorhandler.interrupt,vectorhandler.old_vector);
} else
LOG(LOG_MISC,LOG_WARN)("Interrupt vector changed on %X %s",vectorhandler.interrupt,CALLBACK_GetDescription(m_callback));
}
CALLBACK_RemoveSetup(m_callback);
} else if(m_type == CALLBACK_HandlerObject::SETUPAT){
E_Exit("Callback:SETUP at not handled yet.");
} else if(m_type == CALLBACK_HandlerObject::NONE){
//Do nothing. Merely DeAllocate the callback
} else E_Exit("what kind of callback is this!");
if(CallBack_Description[m_callback]) delete [] CallBack_Description[m_callback];
CallBack_Description[m_callback] = 0;
CALLBACK_DeAllocate(m_callback);
}
void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,const char* description){
if(!installed) {
installed=true;
m_type=SETUP;
m_callback=CALLBACK_Allocate();
CALLBACK_Setup(m_callback,handler,type,description);
} else E_Exit("Allready installed");
}
void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description){
if(!installed) {
installed=true;
m_type=SETUP;
m_callback=CALLBACK_Allocate();
CALLBACK_Setup(m_callback,handler,type,addr,description);
} else E_Exit("Allready installed");
}
void CALLBACK_HandlerObject::Allocate(CallBack_Handler handler,const char* description) {
if(!installed) {
installed=true;
m_type=NONE;
m_callback=CALLBACK_Allocate();
CALLBACK_SetDescription(m_callback,description);
CallBack_Handlers[m_callback]=handler;
} else E_Exit("Allready installed");
}
void CALLBACK_HandlerObject::Set_RealVec(Bit8u vec){
if(!vectorhandler.installed) {
vectorhandler.installed=true;
vectorhandler.interrupt=vec;
RealSetVec(vec,Get_RealPointer(),vectorhandler.old_vector);
} else E_Exit ("double usage of vector handler");
}
void CALLBACK_Init(Section* sec) {
Bitu i;
for (i=0;i<CB_MAX;i++) {
CallBack_Handlers[i]=&illegal_handler;
}
/* Setup the Stop Handler */
call_stop=CALLBACK_Allocate();
CallBack_Handlers[call_stop]=stop_handler;
CALLBACK_SetDescription(call_stop,"stop");
phys_writeb(CALLBACK_PhysPointer(call_stop)+0,0xFE);
phys_writeb(CALLBACK_PhysPointer(call_stop)+1,0x38);
phys_writew(CALLBACK_PhysPointer(call_stop)+2,call_stop);
/* Setup the idle handler */
call_idle=CALLBACK_Allocate();
CallBack_Handlers[call_idle]=stop_handler;
CALLBACK_SetDescription(call_idle,"idle");
for (i=0;i<=11;i++) phys_writeb(CALLBACK_PhysPointer(call_idle)+i,0x90);
phys_writeb(CALLBACK_PhysPointer(call_idle)+12,0xFE);
phys_writeb(CALLBACK_PhysPointer(call_idle)+13,0x38);
phys_writew(CALLBACK_PhysPointer(call_idle)+14,call_idle);
/* Default handlers for unhandled interrupts that have to be non-null */
call_default=CALLBACK_Allocate();
CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default");
call_default2=CALLBACK_Allocate();
CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default");
/* Only setup default handler for first half of interrupt table */
for (i=0;i<0x40;i++) {
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
}
/* Setup block of 0xCD 0xxx instructions */
PhysPt rint_base=(CB_SEG << 4)+CB_MAX*CB_SIZE;
for (i=0;i<=0xff;i++) {
phys_writeb(rint_base,0xCD);
phys_writeb(rint_base+1,i);
phys_writeb(rint_base+2,0xFE);
phys_writeb(rint_base+3,0x38);
phys_writew(rint_base+4,call_stop);
rint_base+=6;
}
// setup a few interrupt handlers that point to bios IRETs by default
real_writed(0,0x0e*4,CALLBACK_RealPointer(call_default2)); //design your own railroad
real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d
real_writed(0,0x67*4,CALLBACK_RealPointer(call_default));
real_writed(0,0x68*4,CALLBACK_RealPointer(call_default));
real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff
//real_writed(0,0xf*4,0); some games don't like it
call_priv_io=CALLBACK_Allocate();
// virtualizable in-out opcodes
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x00,(Bit8u)0xec); // in al, dx
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x01,(Bit8u)0xcb); // retf
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x02,(Bit8u)0xed); // in ax, dx
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x03,(Bit8u)0xcb); // retf
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x04,(Bit8u)0x66); // in eax, dx
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x05,(Bit8u)0xed);
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x06,(Bit8u)0xcb); // retf
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x08,(Bit8u)0xee); // out dx, al
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x09,(Bit8u)0xcb); // retf
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0a,(Bit8u)0xef); // out dx, ax
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0b,(Bit8u)0xcb); // retf
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0c,(Bit8u)0x66); // out dx, eax
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0d,(Bit8u)0xef);
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0e,(Bit8u)0xcb); // retf
}
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include "dosbox.h"
#include "callback.h"
#include "mem.h"
#include "cpu.h"
/* CallBack are located at 0xC800:0
And they are 16 bytes each and you can define them to behave in certain ways like a
far return or and IRET
*/
CallBack_Handler CallBack_Handlers[CB_MAX];
static Bitu call_runint16,call_idle,call_default,call_runfar16;
static Bitu illegal_handler(void) {
E_Exit("Illegal CallBack Called");
return 1;
}
/* when this returns -1 all CallBacks are taken */
Bitu CALLBACK_Allocate(void) {
for (Bitu i=0;(i<CB_MAX);i++) {
if (CallBack_Handlers[i]==&illegal_handler) {
CallBack_Handlers[i]=0;
return i;
}
}
E_Exit("CALLBACK:Can't allocate handler.");
return 0;
}
void CALLBACK_Idle(void) {
/* this makes the cpu execute instructions to handle irq's and then come back */
Bit16u oldcs=Segs[cs].value;
Bit32u oldeip=reg_eip;
SetSegment_16(cs,CB_SEG);
reg_eip=call_idle<<4;
DOSBOX_RunMachine();
reg_eip=oldeip;
SetSegment_16(cs,oldcs);
}
static Bitu default_handler(void) {
LOG_WARN("Illegal Unhandled Interrupt Called %d",lastint);
return CBRET_NONE;
};
static Bitu stop_handler(void) {
return CBRET_STOP;
};
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) {
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+1,off);
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+3,seg);
Bit32u oldeip=reg_eip;
Bit16u oldcs=Segs[cs].value;
reg_eip=call_runfar16<<4;
SetSegment_16(cs,CB_SEG);
DOSBOX_RunMachine();
reg_eip=oldeip;
SetSegment_16(cs,oldcs);
}
void CALLBACK_RunRealInt(Bit8u intnum) {
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+1,intnum);
Bit32u oldeip=reg_eip;
Bit16u oldcs=Segs[cs].value;
reg_eip=call_runint16<<4;
SetSegment_16(cs,CB_SEG);
DOSBOX_RunMachine();
reg_eip=oldeip;
SetSegment_16(cs,oldcs);
}
void CALLBACK_SZF(bool val) {
Bit16u tempf=real_readw(Segs[ss].value,reg_sp+4) & 0xFFBF;
Bit16u newZF=(val==true) << 6;
real_writew(Segs[ss].value,reg_sp+4,(tempf | newZF));
};
void CALLBACK_SCF(bool val) {
Bit16u tempf=real_readw(Segs[ss].value,reg_sp+4) & 0xFFFE;
Bit16u newCF=(val==true);
real_writew(Segs[ss].value,reg_sp+4,(tempf | newCF));
};
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) {
if (callback>=CB_MAX) return false;
switch (type) {
case CB_RETF:
real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4
real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction
real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word
real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCB); //A RETF Instruction
break;
case CB_IRET:
real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4
real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction
real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word
real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCF); //An IRET Instruction
break;
default:
E_Exit("CALLBACK:Setup:Illegal type %d",type);
}
CallBack_Handlers[callback]=handler;
return true;
}
void CALLBACK_Init(void) {
Bitu i;
for (i=0;i<CB_MAX;i++) {
CallBack_Handlers[i]=&illegal_handler;
}
/* Setup the Software interrupt handler */
call_runint16=CALLBACK_Allocate();
CallBack_Handlers[call_runint16]=stop_handler;
real_writeb((Bit16u)CB_SEG,(call_runint16<<4),0xCD);
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+2,0xFE);
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+3,0x38);
real_writew((Bit16u)CB_SEG,(call_runint16<<4)+4,call_runint16);
/* Setup the Far Call handler */
call_runfar16=CALLBACK_Allocate();
CallBack_Handlers[call_runfar16]=stop_handler;
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4),0x9A);
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4)+5,0xFE);
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4)+6,0x38);
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+7,call_runfar16);
/* Setup the idle handler */
call_idle=CALLBACK_Allocate();
CallBack_Handlers[call_idle]=stop_handler;
for (i=0;i<=11;i++) real_writeb((Bit16u)CB_SEG,(call_idle<<4)+i,0x90);
real_writeb((Bit16u)CB_SEG,(call_idle<<4)+12,0xFE);
real_writeb((Bit16u)CB_SEG,(call_idle<<4)+13,0x38);
real_writew((Bit16u)CB_SEG,(call_idle<<4)+14,call_idle);
/* Setup all Interrupt to point to the default handler */
call_default=CALLBACK_Allocate();
CALLBACK_Setup(call_default,&default_handler,CB_IRET);
for (i=0;i<256;i++) {
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
}
}

View File

@ -0,0 +1,3 @@
noinst_HEADERS = helpers.h instructions.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \
prefix_66_of.h

244
src/cpu/core_16/Makefile.in Normal file
View File

@ -0,0 +1,244 @@
# Makefile.in generated by automake 1.6.1 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AWK = @AWK@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
DEPDIR = @DEPDIR@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
STRIP = @STRIP@
VERSION = @VERSION@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
noinst_HEADERS = helpers.h instructions.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \
prefix_66_of.h
subdir = src/cpu/core_16
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
HEADERS = $(noinst_HEADERS)
DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnits src/cpu/core_16/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
uninstall-am: uninstall-info-am
.PHONY: GTAGS all all-am check check-am clean clean-generic distclean \
distclean-generic distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic tags uninstall uninstall-am \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

76
src/cpu/core_16/helpers.h Normal file
View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define GetEAa \
EAPoint eaa=(*lookupEATable)[rm]();
#define GetRMEAa \
GetRM; \
GetEAa;
#define RMEbGb(inst) \
{ \
GetRMrb; \
if (rm >= 0xc0 ) {GetEArb;inst(*earb,*rmrb,LoadRb,SaveRb);} \
else {GetEAa;inst(eaa,*rmrb,LoadMb,SaveMb);} \
}
#define RMGbEb(inst) \
{ \
GetRMrb; \
if (rm >= 0xc0 ) {GetEArb;inst(*rmrb,*earb,LoadRb,SaveRb);} \
else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \
}
#define RMEwGw(inst) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \
}
#define RMGwEw(inst) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \
else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \
}
#define RMEdGd(inst) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \
else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \
}
#define RMGdEd(inst) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \
else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \
}
#define ALIb(inst) \
{ inst(reg_al,Fetchb(),LoadRb,SaveRb)}
#define AXIw(inst) \
{ inst(reg_ax,Fetchw(),LoadRw,SaveRw);}
#define EAXId(inst) \
{ inst(reg_eax,Fetchd(),LoadRd,SaveRd);}

View File

@ -0,0 +1,593 @@
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Jumps */
/*
Could perhaps do some things with 8 and 16 bit operations like shifts, doing them in 32 bit regs
*/
#define JumpSIb(blah) \
if (blah) { \
ADDIPFAST(Fetchbs()); \
} else { \
ADDIPFAST(1); \
}
#define JumpSIw(blah) \
if (blah) { \
ADDIPFAST(Fetchws()); \
} else { \
ADDIPFAST(2); \
}
#define INTERRUPT(blah) \
{ \
Bit8u new_num=blah; \
SAVEIP; \
Interrupt(new_num); \
LOADIP; \
}
/* All Byte genereal instructions */
#define ADDB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b+flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_ADDb;
#define ADCB(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b+flags.var2.b+flags.oldcf; \
save(op1,flags.result.b); \
flags.type=t_ADCb;
#define SBBB(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b-(flags.var2.b+flags.oldcf); \
save(op1,flags.result.b); \
flags.type=t_SBBb;
#define SUBB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b-flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_SUBb;
#define ORB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b | flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_ORb;
#define XORB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b ^ flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_XORb;
#define ANDB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b & flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_ANDb;
#define CMPB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b-flags.var2.b; \
flags.type=t_CMPb;
#define TESTB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b & flags.var2.b; \
flags.type=t_TESTb;
/* All Word General instructions */
#define ADDW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w+flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_ADDw;
#define ADCW(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w+flags.var2.w+flags.oldcf; \
save(op1,flags.result.w); \
flags.type=t_ADCw;
#define SBBW(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w-(flags.var2.w+flags.oldcf); \
save(op1,flags.result.w); \
flags.type=t_SBBw;
#define SUBW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w-flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_SUBw;
#define ORW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w | flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_ORw;
#define XORW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w ^ flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_XORw;
#define ANDW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w & flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_ANDw;
#define CMPW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w-flags.var2.w; \
flags.type=t_CMPw;
#define TESTW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w & flags.var2.w; \
flags.type=t_TESTw;
/* All DWORD General Instructions */
#define ADDD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d+flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_ADDd;
#define ADCD(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d+flags.var2.d+flags.oldcf; \
save(op1,flags.result.d); \
flags.type=t_ADCd;
#define SBBD(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d-(flags.var2.d+flags.oldcf); \
save(op1,flags.result.d); \
flags.type=t_SBBd;
#define SUBD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d-flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_SUBd;
#define ORD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d | flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_ORd;
#define XORD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d ^ flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_XORd;
#define ANDD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d & flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_ANDd;
#define CMPD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d-flags.var2.d; \
flags.type=t_CMPd;
#define TESTD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d & flags.var2.d; \
flags.type=t_TESTd;
#define INCB(op1,load,save) \
LoadCF;flags.result.b=load(op1)+1; \
save(op1,flags.result.b); \
flags.type=t_INCb; \
#define INCW(op1,load,save) \
LoadCF;flags.result.w=load(op1)+1; \
save(op1,flags.result.w); \
flags.type=t_INCw;
#define INCD(op1,load,save) \
LoadCF;flags.result.d=load(op1)+1; \
save(op1,flags.result.d); \
flags.type=t_INCd;
#define DECB(op1,load,save) \
LoadCF;flags.result.b=load(op1)-1; \
save(op1,flags.result.b); \
flags.type=t_DECb;
#define DECW(op1,load,save) \
LoadCF;flags.result.w=load(op1)-1; \
save(op1,flags.result.w); \
flags.type=t_DECw;
#define DECD(op1,load,save) \
LoadCF;flags.result.d=load(op1)-1; \
save(op1,flags.result.d); \
flags.type=t_DECd;
#define NOTDONE \
SUBIP(1);E_Exit("CPU:Opcode %2X Unhandled",Fetchb());
#define NOTDONE66 \
SUBIP(1);E_Exit("CPU:Opcode 66:%2X Unhandled",Fetchb());
//TODO Maybe make this into a bigger split up because of the rm >=0xc0 this seems make it a bit slower
//TODO set Zero and Sign flag in one run
#define ROLB(op1,op2,load,save) \
if (!(op2&0x07)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.var1.b=load(op1);flags.var2.b=op2&0x07; \
flags.result.b=(flags.var1.b << flags.var2.b) | \
(flags.var1.b >> (8-flags.var2.b)); \
save(op1,flags.result.b); \
flags.type=t_ROLb;
#define ROLW(op1,op2,load,save) \
if (!(op2&0x0F)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.var1.w=load(op1);flags.var2.b=op2&0x0F; \
flags.result.w=(flags.var1.w << flags.var2.b) | \
(flags.var1.w >> (16-flags.var2.b)); \
save(op1,flags.result.w); \
flags.type=t_ROLw;
#define ROLD(op1,op2,load,save) \
if (!(op2&0x0F)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.var1.d=load(op1);flags.var2.b=op2&0x0F; \
flags.result.d=(flags.var1.d << flags.var2.b) | \
(flags.var1.d >> (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_ROLd;
#define RORB(op1,op2,load,save) \
if (!(op2&0x07)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.var1.b=load(op1);flags.var2.b=op2&0x07; \
flags.result.b=(flags.var1.b >> flags.var2.b) | \
(flags.var1.b << (8-flags.var2.b)); \
save(op1,flags.result.b); \
flags.type=t_RORb;
#define RORW(op1,op2,load,save) \
if (!(op2&0x0F)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.var1.w=load(op1);flags.var2.b=op2&0x0F; \
flags.result.w=(flags.var1.w >> flags.var2.b) | \
(flags.var1.w << (16-flags.var2.b)); \
save(op1,flags.result.w); \
flags.type=t_RORw;
#define RORD(op1,op2,load,save) \
if (!(op2&0x0F)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.var1.d=load(op1);flags.var2.b=op2&0x0F; \
flags.result.d=(flags.var1.d >> flags.var2.b) | \
(flags.var1.d << (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_RORd;
#define RCLB(op1,op2,load,save) \
if (!(op2%9)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.cf=get_CF();flags.type=t_RCLb; \
flags.var1.b=load(op1);flags.var2.b=op2%9; \
flags.result.b=(flags.var1.b << flags.var2.b) | \
(flags.cf << (flags.var2.b-1)) | \
(flags.var1.b >> (9-flags.var2.b)); \
save(op1,flags.result.b);
#define RCLW(op1,op2,load,save) \
if (!(op2%17)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.cf=get_CF();flags.type=t_RCLw; \
flags.var1.w=load(op1);flags.var2.b=op2%17; \
flags.result.w=(flags.var1.w << flags.var2.b) | \
(flags.cf << (flags.var2.b-1)) | \
(flags.var1.w >> (17-flags.var2.b)); \
save(op1,flags.result.w);
#define RCLD(op1,op2,load,save) \
if (!op2) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.cf=get_CF();flags.type=t_RCLd; \
flags.var1.d=load(op1);flags.var2.b=op2; \
if (flags.var2.b==1) { \
flags.result.d=flags.var1.d << 1 | flags.cf; \
} else { \
flags.result.d=(flags.var1.d << flags.var2.b) | \
(flags.cf << (flags.var2.b-1)) | \
(flags.var1.d >> (33-flags.var2.b)); \
} \
save(op1,flags.result.d);
#define RCRB(op1,op2,load,save) \
if (!(op2%9)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.cf=get_CF();flags.type=t_RCRb; \
flags.var1.b=load(op1);flags.var2.b=op2%9; \
flags.result.b=(flags.var1.b >> flags.var2.b) | \
(flags.cf << (8-flags.var2.b)) | \
(flags.var1.b << (9-flags.var2.b)); \
save(op1,flags.result.b);
#define RCRW(op1,op2,load,save) \
if (!(op2%17)) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.cf=get_CF();flags.type=t_RCRw; \
flags.var1.w=load(op1);flags.var2.b=op2%17; \
flags.result.w=(flags.var1.w >> flags.var2.b) | \
(flags.cf << (16-flags.var2.b)) | \
(flags.var1.w << (17-flags.var2.b)); \
save(op1,flags.result.w);
#define RCRD(op1,op2,load,save) \
if (!op2) break; \
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
flags.cf=get_CF();flags.type=t_RCRd; \
flags.var1.d=load(op1);flags.var2.b=op2; \
if (flags.var2.b==1) { \
flags.result.d=flags.var1.d >> 1 | flags.cf << 31; \
} else { \
flags.result.d=(flags.var1.d >> flags.var2.b) | \
(flags.cf << (32-flags.var2.b)) | \
(flags.var1.d << (33-flags.var2.b)); \
} \
save(op1,flags.result.d);
#define SHLB(op1,op2,load,save) \
if (!op2) break; \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b << flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_SHLb;
#define SHLW(op1,op2,load,save) \
if (!op2) break; \
flags.var1.w=load(op1);flags.var2.b=op2; \
flags.result.w=flags.var1.w << flags.var2.b; \
save(op1,flags.result.w); \
flags.type=t_SHLw;
#define SHLD(op1,op2,load,save) \
if (!op2) break; \
flags.var1.d=load(op1);flags.var2.b=op2; \
flags.result.d=flags.var1.d << flags.var2.b; \
save(op1,flags.result.d); \
flags.type=t_SHLd;
#define SHRB(op1,op2,load,save) \
if (!op2) break; \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b >> flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_SHRb;
#define SHRW(op1,op2,load,save) \
if (!op2) break; \
flags.var1.w=load(op1);flags.var2.b=op2; \
flags.result.w=flags.var1.w >> flags.var2.b; \
save(op1,flags.result.w); \
flags.type=t_SHRw;
#define SHRD(op1,op2,load,save) \
if (!op2) break; \
flags.var1.d=load(op1);flags.var2.b=op2; \
flags.result.d=flags.var1.d >> flags.var2.b; \
save(op1,flags.result.d); \
flags.type=t_SHRd;
#define SARB(op1,op2,load,save) \
if (!op2) break; \
flags.var1.b=load(op1);flags.var2.b=op2; \
if (flags.var2.b>8) flags.var2.b=8; \
if (flags.var1.b & 0x80) { \
flags.result.b=(flags.var1.b >> flags.var2.b)| \
(0xff << (8 - flags.var2.b)); \
} else { \
flags.result.b=flags.var1.b >> flags.var2.b; \
} \
save(op1,flags.result.b); \
flags.type=t_SARb;
#define SARW(op1,op2,load,save) \
if (!op2) break; \
flags.var1.w=load(op1);flags.var2.b=op2; \
if (flags.var2.b>16) flags.var2.b=16; \
if (flags.var1.w & 0x8000) { \
flags.result.w=(flags.var1.w >> flags.var2.b)| \
(0xffff << (16 - flags.var2.b)); \
} else { \
flags.result.w=flags.var1.w >> flags.var2.b; \
} \
save(op1,flags.result.w); \
flags.type=t_SARw;
#define SARD(op1,op2,load,save) \
if (!op2) break; \
flags.var1.d=load(op1);flags.var2.b=op2; \
if (flags.var1.d & 0x80000000) { \
flags.result.d=(flags.var1.d >> flags.var2.b)| \
(0xffffffff << (32 - flags.var2.b)); \
} else { \
flags.result.d=flags.var1.d >> flags.var2.b; \
} \
save(op1,flags.result.d); \
flags.type=t_SARd;
#define GRP2B(blah) \
{ \
GetRM; \
if (rm >= 0xc0) { \
GetEArb; \
Bit8u val=blah & 0x1f; \
switch (rm&0x38) { \
case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \
case 0x08:RORB(*earb,val,LoadRb,SaveRb);break; \
case 0x10:RCLB(*earb,val,LoadRb,SaveRb);break; \
case 0x18:RCRB(*earb,val,LoadRb,SaveRb);break; \
case 0x20:/* SHL and SAL are the same */ \
case 0x30:SHLB(*earb,val,LoadRb,SaveRb);break; \
case 0x28:SHRB(*earb,val,LoadRb,SaveRb);break; \
case 0x38:SARB(*earb,val,LoadRb,SaveRb);break; \
} \
} else { \
GetEAa; \
Bit8u val=blah & 0x1f; \
switch (rm & 0x38) { \
case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break; \
case 0x08:RORB(eaa,val,LoadMb,SaveMb);break; \
case 0x10:RCLB(eaa,val,LoadMb,SaveMb);break; \
case 0x18:RCRB(eaa,val,LoadMb,SaveMb);break; \
case 0x20:/* SHL and SAL are the same */ \
case 0x30:SHLB(eaa,val,LoadMb,SaveMb);break; \
case 0x28:SHRB(eaa,val,LoadMb,SaveMb);break; \
case 0x38:SARB(eaa,val,LoadMb,SaveMb);break; \
} \
} \
}
#define GRP2W(blah) \
{ \
GetRM; \
if (rm >= 0xc0) { \
GetEArw; \
Bit8u val=blah & 0x1f; \
switch (rm&0x38) { \
case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \
case 0x08:RORW(*earw,val,LoadRw,SaveRw);break; \
case 0x10:RCLW(*earw,val,LoadRw,SaveRw);break; \
case 0x18:RCRW(*earw,val,LoadRw,SaveRw);break; \
case 0x20:/* SHL and SAL are the same */ \
case 0x30:SHLW(*earw,val,LoadRw,SaveRw);break; \
case 0x28:SHRW(*earw,val,LoadRw,SaveRw);break; \
case 0x38:SARW(*earw,val,LoadRw,SaveRw);break; \
} \
} else { \
GetEAa; \
Bit8u val=blah & 0x1f; \
switch (rm & 0x38) { \
case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break; \
case 0x08:RORW(eaa,val,LoadMw,SaveMw);break; \
case 0x10:RCLW(eaa,val,LoadMw,SaveMw);break; \
case 0x18:RCRW(eaa,val,LoadMw,SaveMw);break; \
case 0x20:/* SHL and SAL are the same */ \
case 0x30:SHLW(eaa,val,LoadMw,SaveMw);break; \
case 0x28:SHRW(eaa,val,LoadMw,SaveMw);break; \
case 0x38:SARW(eaa,val,LoadMw,SaveMw);break; \
} \
} \
}
#define GRP2D(blah) \
{ \
GetRM; \
if (rm >= 0xc0) { \
GetEArd; \
Bit8u val=blah & 0x1f; \
switch (rm&0x38) { \
case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \
case 0x08:RORD(*eard,val,LoadRd,SaveRd);break; \
case 0x10:RCLD(*eard,val,LoadRd,SaveRd);break; \
case 0x18:RCRD(*eard,val,LoadRd,SaveRd);break; \
case 0x20:/* SHL and SAL are the same */ \
case 0x30:SHLD(*eard,val,LoadRd,SaveRd);break; \
case 0x28:SHRD(*eard,val,LoadRd,SaveRd);break; \
case 0x38:SARD(*eard,val,LoadRd,SaveRd);break; \
} \
} else { \
GetEAa; \
Bit8u val=blah & 0x1f; \
switch (rm & 0x38) { \
case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break; \
case 0x08:RORD(eaa,val,LoadMd,SaveMd);break; \
case 0x10:RCLD(eaa,val,LoadMd,SaveMd);break; \
case 0x18:RCRD(eaa,val,LoadMd,SaveMd);break; \
case 0x20:/* SHL and SAL are the same */ \
case 0x30:SHLD(eaa,val,LoadMd,SaveMd);break; \
case 0x28:SHRD(eaa,val,LoadMd,SaveMd);break; \
case 0x38:SARD(eaa,val,LoadMd,SaveMd);break; \
} \
} \
}
/* let's hope bochs has it correct with the higher than 16 shifts */
#define DSHLW(op1,op2,op3,load,save) \
flags.var1.d=(load(op1)<<16)|op2;flags.var2.b=op3; \
Bit32u tempd=flags.var1.d << flags.var2.b; \
if (flags.var2.b>16) tempd |= (op2 << (flags.var2.b - 16)); \
flags.result.w=(Bit16u)(tempd >> 16); \
save(op1,flags.result.w); \
flags.type=t_DSHLw;
#define DSHLD(op1,op2,op3,load,save) \
flags.var1.d=load(op1);flags.var2.b=op3; \
flags.result.d=(flags.var1.d << flags.var2.b) | (op2 >> (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_DSHLd;
#define DSHRW(op1,op2,op3,load,save) \
flags.var1.d=(load(op1)<<16)|op2;flags.var2.b=op3; \
Bit32u tempd=flags.var1.d >> flags.var2.b; \
if (flags.var2.b>16) tempd |= (op2 << (32-flags.var2.b )); \
flags.result.w=(Bit16u)(tempd); \
save(op1,flags.result.w); \
flags.type=t_DSHRw;
#define DSHRD(op1,op2,op3,load,save) \
flags.var1.d=load(op1);flags.var2.b=op3; \
flags.result.d=(flags.var1.d >> flags.var2.b) | (op2 << (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_DSHRd;

1488
src/cpu/core_16/main.h Normal file

File diff suppressed because it is too large Load Diff

469
src/cpu/core_16/prefix_66.h Normal file
View File

@ -0,0 +1,469 @@
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
restart_66:
switch(Fetchb()) {
case 0x01: /* ADD Ed,Gd */
RMEdGd(ADDD);break;
case 0x03: /* ADD Gd,Ed */
RMGdEd(ADDD);break;
case 0x05: /* ADD EAX,Id */
EAXId(ADDD);break;
case 0x09: /* OR Ew,Gw */
RMEdGd(ORD);break;
case 0x0b: /* OR Gd,Ed */
RMGdEd(ORD);break;
case 0x0d: /* OR EAX,Id */
EAXId(ORD);break;
case 0x0f: /* 2 Byte opcodes */
#include "prefix_66_of.h"
break;
case 0x11: /* ADC Ed,Gd */
RMEdGd(ADCD);break;
case 0x13: /* ADC Gd,Ed */
RMGdEd(ADCD);break;
case 0x15: /* ADC EAX,Id */
EAXId(ADCD);break;
case 0x19: /* SBB Ed,Gd */
RMEdGd(SBBD);break;
case 0x1b: /* SBB Gd,Ed */
RMGdEd(SBBD);break;
case 0x1d: /* SBB EAX,Id */
EAXId(SBBD);break;
case 0x21: /* AND Ed,Gd */
RMEdGd(ANDD);break;
case 0x23: /* AND Gd,Ed */
RMGdEd(ANDD);break;
case 0x25: /* AND EAX,Id */
EAXId(ANDD);break;
case 0x29: /* SUB Ed,Gd */
RMEdGd(SUBD);break;
case 0x2b: /* SUB Gd,Ed */
RMGdEd(SUBD);break;
case 0x2d: /* SUB EAX,Id */
EAXId(SUBD);break;
case 0x31: /* XOR Ed,Gd */
RMEdGd(XORD);break;
case 0x33: /* XOR Gd,Ed */
RMGdEd(XORD);break;
case 0x35: /* XOR EAX,Id */
EAXId(XORD);break;
case 0x39: /* CMP Ed,Gd */
RMEdGd(CMPD);break;
case 0x3b: /* CMP Gd,Ed */
RMGdEd(CMPD);break;
case 0x3d: /* CMP EAX,Id */
EAXId(CMPD);break;
case 0x26: /* SEG ES: */
SegPrefix_66(es);break;
case 0x2e: /* SEG CS: */
SegPrefix_66(cs);break;
case 0x36: /* SEG SS: */
SegPrefix_66(ss);break;
case 0x3e: /* SEG DS: */
SegPrefix_66(ds);break;
case 0x40: /* INC EAX */
INCD(reg_eax,LoadRd,SaveRd);break;
case 0x41: /* INC ECX */
INCD(reg_ecx,LoadRd,SaveRd);break;
case 0x42: /* INC EDX */
INCD(reg_edx,LoadRd,SaveRd);break;
case 0x43: /* INC EBX */
INCD(reg_ebx,LoadRd,SaveRd);break;
case 0x44: /* INC ESP */
INCD(reg_esp,LoadRd,SaveRd);break;
case 0x45: /* INC EBP */
INCD(reg_ebp,LoadRd,SaveRd);break;
case 0x46: /* INC ESI */
INCD(reg_esi,LoadRd,SaveRd);break;
case 0x47: /* INC EDI */
INCD(reg_edi,LoadRd,SaveRd);break;
case 0x48: /* DEC EAX */
DECD(reg_eax,LoadRd,SaveRd);break;
case 0x49: /* DEC ECX */
DECD(reg_ecx,LoadRd,SaveRd);break;
case 0x4a: /* DEC EDX */
DECD(reg_edx,LoadRd,SaveRd);break;
case 0x4b: /* DEC EBX */
DECD(reg_ebx,LoadRd,SaveRd);break;
case 0x4c: /* DEC ESP */
DECD(reg_esp,LoadRd,SaveRd);break;
case 0x4d: /* DEC EBP */
DECD(reg_ebp,LoadRd,SaveRd);break;
case 0x4e: /* DEC ESI */
DECD(reg_esi,LoadRd,SaveRd);break;
case 0x4f: /* DEC EDI */
DECD(reg_edi,LoadRd,SaveRd);break;
case 0x50: /* PUSH EAX */
Push_32(reg_eax);break;
case 0x51: /* PUSH ECX */
Push_32(reg_ecx);break;
case 0x52: /* PUSH EDX */
Push_32(reg_edx);break;
case 0x53: /* PUSH EBX */
Push_32(reg_ebx);break;
case 0x54: /* PUSH ESP */
Push_32(reg_esp);break;
case 0x55: /* PUSH EBP */
Push_32(reg_ebp);break;
case 0x56: /* PUSH ESI */
Push_32(reg_esi);break;
case 0x57: /* PUSH EDI */
Push_32(reg_edi);break;
case 0x58: /* POP EAX */
reg_eax=Pop_32();break;
case 0x59: /* POP ECX */
reg_ecx=Pop_32();break;
case 0x5a: /* POP EDX */
reg_edx=Pop_32();break;
case 0x5b: /* POP EBX */
reg_ebx=Pop_32();break;
case 0x5c: /* POP ESP */
reg_esp=Pop_32();break;
case 0x5d: /* POP EBP */
reg_ebp=Pop_32();break;
case 0x5e: /* POP ESI */
reg_esi=Pop_32();break;
case 0x5f: /* POP EDI */
reg_edi=Pop_32();break;
case 0x60: /* PUSHAD */
Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
break;
case 0x61: /* POPAD */
reg_edi=Pop_32();reg_edi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
break;
case 0x68: /* PUSH Id */
Push_32(Fetchd());break;
case 0x69: /* IMUL Gd,Ed,Id */
{
GetRMrd;
Bit64s res;
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*eards) * (Bit64s)Fetchds();}
else {GetEAa;res=(Bit64s)LoadMds(eaa) * (Bit64s)Fetchds();}
*rmrd=(Bit32s)(res);
flags.type=t_MUL;
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
else {flags.cf=true;flags.of=true;}
break;
};
case 0x6a: /* PUSH Ib */
Push_32(Fetchbs());break;
case 0x81: /* Grpl Ed,Id */
{
GetRM;
if (rm>= 0xc0) {
GetEArd;Bit32u id=Fetchd();
switch (rm & 0x38) {
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
case 0x08: ORD(*eard,id,LoadRd,SaveRd);break;
case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break;
case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break;
case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break;
case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break;
case 0x30:XORD(*eard,id,LoadRd,SaveRd);break;
case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break;
}
} else {
GetEAa;Bit32u id=Fetchb();
switch (rm & 0x38) {
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
case 0x08: ORD(eaa,id,LoadMd,SaveMd);break;
case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break;
case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break;
case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break;
case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break;
case 0x30:XORD(eaa,id,LoadMd,SaveMd);break;
case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break;
}
}
}
break;
case 0x83: /* Grpl Ed,Ix */
{
GetRM;
if (rm>= 0xc0) {
GetEArd;Bit32u id=(Bit32s)Fetchbs();
switch (rm & 0x38) {
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
case 0x08: ORD(*eard,id,LoadRd,SaveRd);break;
case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break;
case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break;
case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break;
case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break;
case 0x30:XORD(*eard,id,LoadRd,SaveRd);break;
case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break;
}
} else {
GetEAa;Bit32u id=(Bit32s)Fetchbs();
switch (rm & 0x38) {
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
case 0x08: ORD(eaa,id,LoadMd,SaveMd);break;
case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break;
case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break;
case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break;
case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break;
case 0x30:XORD(eaa,id,LoadMd,SaveMd);break;
case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break;
}
}
}
break;
case 0x8f: /* POP Ed */
{
GetRM;
if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();}
else {GetEAa;SaveMd(eaa,Pop_32());}
break;
}
case 0x89: /* MOV Ed,Gd */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;}
else {GetEAa;SaveMd(eaa,*rmrd);}
break;
}
case 0x99: /* CDQ */
if (reg_eax & 0x80000000) reg_edx=0xffffffff;
else reg_edx=0;
break;
case 0x8b: /* MOV Gd,Ed */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;}
else {GetEAa;*rmrd=LoadMd(eaa);}
break;
}
case 0x8c:
LOG_WARN("CPU:66:8c looped back");
break;
case 0x9c: /* PUSHFD */
{
Bit32u pflags=
(get_CF() << 0) | (get_PF() << 2) | (get_AF() << 4) |
(get_ZF() << 6) | (get_SF() << 7) | (flags.tf << 8) |
(flags.intf << 9) |(flags.df << 10) | (get_OF() << 11) |
(flags.io << 12) | (flags.nt <<14);
Push_32(pflags);
break;
}
case 0x9d: /* POPFD */
{
Save_Flagsw((Bit16u)(Pop_32()&0xffff));
break;
}
case 0xa1: /* MOV EAX,Ow */
if (segprefix_on) {
reg_eax=LoadMd(segprefix_base+Fetchw());
SegPrefixReset;
} else {
reg_eax=LoadMd(SegBase(ds)+Fetchw());
}
break;
case 0xa3: /* MOV Ow,EAX */
if (segprefix_on) {
SaveMd((segprefix_base+Fetchw()),reg_eax);
SegPrefixReset;
} else {
SaveMd((SegBase(ds)+Fetchw()),reg_eax);
}
break;
case 0xa5: /* MOVSD */
{
stringSI;stringDI;SaveMd(to,LoadMd(from));
if (flags.df) { reg_si-=4;reg_di-=4; }
else { reg_si+=4;reg_di+=4;}
}
break;
case 0xab: /* STOSD */
{
stringDI;
SaveMd(to,reg_eax);
if (flags.df) { reg_di-=4; }
else {reg_di+=4;}
break;
}
case 0xad: /* LODSD */
{
stringSI;
reg_eax=LoadMd(from);
if (flags.df) { reg_si-=4;}
else {reg_si+=4;}
break;
}
case 0xaf: /* SCASD */
{
stringDI;
CMPD(reg_eax,LoadMd(to),LoadRd,0);
if (flags.df) { reg_di-=4; }
else {reg_di+=4;}
break;
}
case 0xb8: /* MOV EAX,Id */
reg_eax=Fetchd();break;
case 0xb9: /* MOV ECX,Id */
reg_ecx=Fetchd();break;
case 0xba: /* MOV EDX,Iw */
reg_edx=Fetchd();break;
case 0xbb: /* MOV EBX,Id */
reg_ebx=Fetchd();break;
case 0xbc: /* MOV ESP,Id */
reg_esp=Fetchd();break;
case 0xbd: /* MOV EBP.Id */
reg_ebp=Fetchd();break;
case 0xbe: /* MOV ESI,Id */
reg_esi=Fetchd();break;
case 0xbf: /* MOV EDI,Id */
reg_edi=Fetchd();break;
case 0xc1: /* GRP2 Ed,Ib */
GRP2D(Fetchb());break;
case 0xc7: /* MOV Ed,Id */
{
GetRM;
if (rm>0xc0) {GetEArd;*eard=Fetchd();}
else {GetEAa;SaveMd(eaa,Fetchd());}
break;
}
case 0xd1: /* GRP2 Ed,1 */
GRP2D(1);break;
case 0xd3: /* GRP2 Ed,CL */
GRP2D(reg_cl);break;
case 0xf7: /* GRP3 Ed(,Id) */
{
union { Bit64u u;Bit64s s;} temp;
union {Bit64u u;Bit64s s;} quotient;
GetRM;
switch (rm & 0x38) {
case 0x00: /* TEST Ed,Id */
case 0x08: /* TEST Ed,Id Undocumented*/
{
if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
break;
}
case 0x10: /* NOT Ed */
{
if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
break;
}
case 0x18: /* NEG Ed */
{
flags.type=t_NEGd;
if (rm >= 0xc0 ) {
GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d;
*eard=flags.result.d;
} else {
GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d;
SaveMd(eaa,flags.result.d);
}
break;
}
case 0x20: /* MUL EAX,Ed */
{
flags.type=t_MUL;
if (rm >= 0xc0 ) {GetEArd;temp.u=(Bit64s)reg_eax * (Bit64u)(*eard);}
else {GetEAa;temp.u=(Bit64u)reg_eax * (Bit64u)LoadMd(eaa);}
reg_eax=(Bit32u)(temp.u & 0xffffffff);reg_eax=(Bit32u)(temp.u >> 32);
flags.cf=flags.of=(reg_edx !=0);
break;
}
case 0x28: /* IMUL EAX,Ed */
{
flags.type=t_MUL;
if (rm >= 0xc0 ) {GetEArd;temp.s=(Bit64s)reg_eax * (Bit64s)(*eards);}
else {GetEAa;temp.s=(Bit64s)reg_eax * (Bit64s)LoadMds(eaa);}
reg_eax=Bit32u(temp.u & 0xffffffff);reg_edx=(Bit32u)(temp.u >> 32);
if ( (reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) {
flags.cf=flags.of=false;
} else if ( (reg_edx==0x00000000) && (reg_eax<0x80000000) ) {
flags.cf=flags.of=false;
} else {
flags.cf=flags.of=true;
}
break;
}
case 0x30: /* DIV Ed */
{
// flags.type=t_DIV;
Bit32u val;
if (rm >= 0xc0 ) {GetEArd;val=*eard;}
else {GetEAa;val=LoadMd(eaa);}
if (val==0) {Interrupt(0);break;}
temp.u=(((Bit64u)reg_edx)<<32)|reg_eax;
quotient.u=temp.u/val;
reg_edx=(Bit32u)(temp.u % val);
reg_eax=(Bit32u)(quotient.u & 0xffffffff);
if (quotient.u>0xffffffff)
Interrupt(0);
break;
}
case 0x38: /* IDIV Ed */
{
// flags.type=t_DIV;
Bit32s val;
if (rm >= 0xc0 ) {GetEArd;val=*eards;}
else {GetEAa;val=LoadMds(eaa);}
if (val==0) {Interrupt(0);break;}
temp.s=(((Bit64u)reg_edx)<<32)|reg_eax;
quotient.s=(temp.s/val);
reg_edx=(Bit32s)(temp.s % val);
reg_eax=(Bit32s)(quotient.s);
if (quotient.s!=(Bit32s)reg_eax)
Interrupt(0);
break;
}
}
break;
}
case 0xff: /* Group 5 */
{
GetRM;
switch (rm & 0x38) {
case 0x00: /* INC Ew */
flags.cf=get_CF();flags.type=t_INCd;
if (rm >= 0xc0 ) {GetEArd;flags.result.d=*eard+=1;}
else {GetEAa;flags.result.d=LoadMd(eaa)+1;SaveMd(eaa,flags.result.d);}
break;
case 0x08: /* DEC Ew */
flags.cf=get_CF();flags.type=t_DECd;
if (rm >= 0xc0 ) {GetEArd;flags.result.d=*eard-=1;}
else {GetEAa;flags.result.d=LoadMd(eaa)-1;SaveMd(eaa,flags.result.d);}
break;
case 0x30: /* Push Ed */
if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);}
else {GetEAa;Push_32(LoadMd(eaa));}
break;
default:
E_Exit("CPU:66:GRP5:Illegal call %2X",rm & 0x38);
break;
}
break;
}
default:
NOTDONE66;
}

View File

@ -0,0 +1,124 @@
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
switch (Fetchb()) {
case 0xa4: /* SHLD Ed,Gd,Ib */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;DSHLD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);}
else {GetEAa;DSHLD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
break;
}
case 0xac: /* SHRD Ed,Gd,Ib */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);}
else {GetEAa;DSHRD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
break;
}
case 0xb6: /* MOVZX Gd,Eb */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
else {GetEAa;*rmrd=LoadMb(eaa);}
break;
}
case 0xaf: /* IMUL Gd,Ed */
{
GetRMrd;
Bit64s res;
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*rmrd) * (Bit64s)(*eards);}
else {GetEAa;res=(Bit64s)(*rmrd) * (Bit64s)LoadMds(eaa);}
*rmrd=(Bit32s)(res);
flags.type=t_MUL;
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
else {flags.cf=true;flags.of=true;}
break;
};
case 0xb7: /* MOVXZ Gd,Ew */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;}
else {GetEAa;*rmrd=LoadMw(eaa);}
break;
}
case 0xba: /* GRP8 Ed,Ib */
{
GetRM;
if (rm >= 0xc0 ) {
GetEArd;
Bit32u mask=1 << (Fetchb() & 31);
flags.cf=(*eard & mask)>0;
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
*eard|=mask;
break;
case 0x30: /* BTR */
*eard&=~mask;
break;
case 0x38: /* BTC */
if (flags.cf) *eard&=~mask;
else *eard|=mask;
break;
}
} else {
GetEAa;Bit32u old=LoadMd(eaa);
Bit32u mask=1 << (Fetchb() & 31);
flags.cf=(old & mask)>0;
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
SaveMd(eaa,old|mask);
break;
case 0x30: /* BTR */
SaveMd(eaa,old & ~mask);
break;
case 0x38: /* BTC */
if (flags.cf) old&=~mask;
else old|=mask;
SaveMd(eaa,old);
break;
}
}
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
break;
}
case 0xbe: /* MOVSX Gd,Eb */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earbs;}
else {GetEAa;*rmrd=LoadMbs(eaa);}
break;
}
case 0xbf: /* MOVSX Gd,Ew */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earws;}
else {GetEAa;*rmrd=LoadMws(eaa);}
break;
}
default:
SUBIP(1);
E_Exit("CPU:Opcode 66:0F:%2X Unhandled",Fetchb());
}

188
src/cpu/core_16/prefix_of.h Normal file
View File

@ -0,0 +1,188 @@
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
switch(Fetchb()) {
case 0x01: /* GRP 7 */
{
GetRM;
switch (rm & 0x38) {
case 0x20: /* SMSW */
/* Let's seriously fake this call */
if (rm>0xc0) {GetEArw;*earw=0;}
else {GetEAa;SaveMw(eaa,0);}
break;
default:
E_Exit("CPU:GRP7:Illegal call %2X",rm);
}
}
break;
case 0x80: /* JO */
JumpSIw(get_OF());break;
case 0x81: /* JNO */
JumpSIw(!get_OF());break;
case 0x82: /* JB */
JumpSIw(get_CF());break;
case 0x83: /* JNB */
JumpSIw(!get_CF());break;
case 0x84: /* JZ */
JumpSIw(get_ZF());break;
case 0x85: /* JNZ */
JumpSIw(!get_ZF()); break;
case 0x86: /* JBE */
JumpSIw(get_CF() || get_ZF());break;
case 0x87: /* JNBE */
JumpSIw(!get_CF() && !get_ZF());break;
case 0x88: /* JS */
JumpSIw(get_SF());break;
case 0x89: /* JNS */
JumpSIw(!get_SF());break;
case 0x8a: /* JP */
JumpSIw(get_PF());break;
case 0x8b: /* JNP */
JumpSIw(!get_PF());break;
case 0x8c: /* JL */
JumpSIw(get_SF() != get_OF());break;
case 0x8d: /* JNL */
JumpSIw(get_SF() == get_OF());break;
case 0x8e: /* JLE */
JumpSIw(get_ZF() || (get_SF() != get_OF()));break;
case 0x8f: /* JNLE */
JumpSIw((get_SF() == get_OF()) && !get_ZF());break;
case 0xa0: /* PUSH FS */
Push_16(Segs[fs].value);break;
case 0xa1: /* POP FS */
SetSegment_16(fs,Pop_16());break;
case 0xa4: /* SHLD Ew,Gw,Ib */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);}
else {GetEAa;DSHLW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);}
break;
}
case 0xa5: /* SHLD Ew,Gw,CL */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,reg_cl,LoadRw,SaveRw);}
else {GetEAa;DSHLW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);}
break;
}
case 0xa8: /* PUSH GS */
Push_16(Segs[gs].value);break;
case 0xa9: /* POP GS */
SetSegment_16(gs,Pop_16());break;
case 0xac: /* SHRD Ew,Gw,Ib */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);}
else {GetEAa;DSHRW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);}
break;
}
case 0xad: /* SHRD Ew,Gw,CL */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,reg_cl,LoadRw,SaveRw);}
else {GetEAa;DSHRW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);}
break;
}
case 0xaf: /* IMUL Gw,Ew */
{
GetRMrw;
Bit32s res;
if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*rmrw) * (Bit32s)(*earws);}
else {GetEAa;res=(Bit32s)(*rmrw) *(Bit32s)LoadMws(eaa);}
*rmrw=res & 0xFFFF;
flags.type=t_MUL;
if ((res> -32768) && (res<32767)) {flags.cf=false;flags.of=false;}
else {flags.cf=true;flags.of=true;}
break;
}
case 0xb4: /* LFS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);SetSegment_16(fs,LoadMw(eaa+2));
break;
}
case 0xb5: /* LGS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);SetSegment_16(gs,LoadMw(eaa+2));
break;
}
case 0xb6: /* MOVZX Gw,Eb */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;}
else {GetEAa;*rmrw=LoadMb(eaa);}
break;
}
case 0xba: /* GRP8 Ew,Ib */
{
GetRM;
if (rm >= 0xc0 ) {
GetEArw;
Bit16u mask=1 << (Fetchb() & 15);
flags.cf=(*earw & mask)>0;
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
*earw|=mask;
break;
case 0x30: /* BTR */
*earw&=~mask;
break;
case 0x38: /* BTC */
if (flags.cf) *earw&=~mask;
else *earw|=mask;
break;
}
} else {
GetEAa;Bit16u old=LoadMw(eaa);
Bit16u mask=1 << (Fetchb() & 15);
flags.cf=(old & mask)>0;
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
SaveMw(eaa,old|mask);
break;
case 0x30: /* BTR */
SaveMw(eaa,old & ~mask);
break;
case 0x38: /* BTC */
if (flags.cf) old&=~mask;
else old|=mask;
SaveMw(eaa,old);
break;
}
}
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
break;
}
case 0xbe: /* MOVSX Gw,Eb */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earbs;}
else {GetEAa;*rmrw=LoadMbs(eaa);}
break;
}
default:
SUBIP(1);
E_Exit("CPU:Opcode 0F:%2X Unhandled",Fetchb());
}

View File

@ -1,31 +1,20 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le.h,v 1.2 2008/09/02 20:44:41 c2woody Exp $ */
/* ARMv4 (little endian) backend (switcher) by M-HT */
#include "risc_armv4le-common.h"
// choose your destiny:
#include "risc_armv4le-thumb-niw.h"
//#include "risc_armv4le-thumb-iw.h"
//#include "risc_armv4le-thumb.h"
//#include "risc_armv4le-s3.h"
//#include "risc_armv4le-o3.h"
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Setup the CS:IP and SS:SP Pointers */
LOADIP;

View File

@ -1,34 +1,19 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __XMS_H__
#define __XMS_H__
Bitu XMS_QueryFreeMemory (Bit16u& largestFree, Bit16u& totalFree);
Bitu XMS_AllocateMemory (Bitu size, Bit16u& handle);
Bitu XMS_FreeMemory (Bitu handle);
Bitu XMS_MoveMemory (PhysPt bpt);
Bitu XMS_LockMemory (Bitu handle, Bit32u& address);
Bitu XMS_UnlockMemory (Bitu handle);
Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size);
Bitu XMS_ResizeMemory (Bitu handle, Bitu newSize);
Bitu XMS_EnableA20 (bool enable);
Bitu XMS_GetEnabledA20 (void);
#endif
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
SAVEIP;

191
src/cpu/core_16/support.h Normal file
View File

@ -0,0 +1,191 @@
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
EAPoint IPPoint;
#define SUBIP(a) IPPoint-=a
#define SETIP(a) IPPoint=SegBase(cs)+a
#define GETIP (Bit16u)(IPPoint-SegBase(cs))
#define SAVEIP reg_ip=GETIP
#define LOADIP IPPoint=SegBase(cs)+reg_ip
/*
#define ADDIP(a) { \
Bit16u add_ip=(Bit16u)(IPPoint-SegBase(cs)); \
add_ip+=a; \
IPPoint=SegBase(cs)+add_ip; \
}
*/
static INLINE void ADDIP(Bit16u add) {
// Bit16u oldip=(IPPoint-SegBase(cs));
// oldip+=add;
// IPPoint=SegBase(cs)+oldip;
IPPoint=SegBase(cs)+((Bit16u)(((Bit16u)(IPPoint-SegBase(cs)))+(Bit16u)add));
}
static INLINE void ADDIPFAST(Bit16s blah) {
IPPoint+=blah;
}
#define ERRORRETURN(a) { error_ret=a;goto errorreturn; }
static INLINE Bit8u Fetchb() {
Bit8u temp=LoadMb(IPPoint);
IPPoint+=1;
return temp;
}
static INLINE Bit16u Fetchw() {
Bit16u temp=LoadMw(IPPoint);
IPPoint+=2;
return temp;
}
static INLINE Bit32u Fetchd() {
Bit32u temp=LoadMd(IPPoint);
IPPoint+=4;
return temp;
}
static INLINE Bit8s Fetchbs() {
return Fetchb();
}
static INLINE Bit16s Fetchws() {
return Fetchw();
}
static INLINE Bit32s Fetchds() {
return Fetchd();
}
static INLINE void Push_16(Bit16u blah) {
reg_sp-=2;
SaveMw(SegBase(ss)+reg_sp,blah);
};
static INLINE void Push_32(Bit32u blah) {
reg_sp-=4;
SaveMd(SegBase(ss)+reg_sp,blah);
};
static INLINE Bit16u Pop_16() {
Bit16u temp=LoadMw(SegBase(ss)+reg_sp);
reg_sp+=2;
return temp;
};
static INLINE Bit32u Pop_32() {
Bit32u temp=LoadMd(SegBase(ss)+reg_sp);
reg_sp+=4;
return temp;
};
#define stringDI \
EAPoint to; \
to=SegBase(es)+reg_di
#define stringSI \
EAPoint from; \
if (segprefix_on) { \
from=(segprefix_base+reg_si); \
SegPrefixReset; \
} else { \
from=SegBase(ds)+reg_si; \
}
#include "helpers.h"
#include "table_ea.h"
#include "../modrm.h"
#include "instructions.h"
static INLINE void Rep_66(Bit16s direct,EAPoint from,EAPoint to) {
bool again;
do {
again=false;
Bit8u repcode=Fetchb();
switch (repcode) {
case 0x26: /* ES Prefix */
again=true;
from=SegBase(es);
break;
case 0x2e: /* CS Prefix */
again=true;
from=SegBase(cs);
break;
case 0x36: /* SS Prefix */
again=true;
from=SegBase(ss);
break;
case 0x3e: /* DS Prefix */
again=true;
from=SegBase(ds);
break;
case 0xa5: /* REP MOVSD */
for (;reg_cx>0;reg_cx--) {
SaveMd(to+reg_di,LoadMd(from+reg_si));
reg_di+=direct*4;
reg_si+=direct*4;
}
break;
case 0xab: /* REP STOSW */
for (;reg_cx>0;reg_cx--) {
SaveMd(to+reg_di,reg_eax);
reg_di+=direct*4;
}
break;
default:
E_Exit("CPU:Opcode 66:Illegal REP prefix %2X",repcode);
}
} while (again);
}
//flags.io and nt shouldn't be compiled for 386
#define Save_Flagsw(FLAGW) \
{ \
flags.type=t_UNKNOWN; \
flags.cf =(FLAGW & 0x001)>0;flags.pf =(FLAGW & 0x004)>0; \
flags.af =(FLAGW & 0x010)>0;flags.zf =(FLAGW & 0x040)>0; \
flags.sf =(FLAGW & 0x080)>0;flags.tf =(FLAGW & 0x100)>0; \
flags.intf =(FLAGW & 0x200)>0; \
flags.df =(FLAGW & 0x400)>0;flags.of =(FLAGW & 0x800)>0; \
flags.io =(FLAGW >> 12) & 0x03; \
flags.nt =(FLAGW & 0x4000)>0; \
if (flags.intf && PIC_IRQCheck) { \
SAVEIP; \
PIC_runIRQs(); \
LOADIP; \
} \
if (flags.tf) E_Exit("CPU:Trap Flag not supported"); \
}
// if (flags.tf) { \
// cpudecoder=CPU_Real_16_Slow_Decode_Special; \
// return CBRET_NONE; \
// } \

283
src/cpu/core_16/table_ea.h Normal file
View File

@ -0,0 +1,283 @@
/*
* Copyright (C) 2002 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Some variables for EA Loolkup */
typedef EAPoint (*GetEATable[256])(void);
static GetEATable * lookupEATable;
static EAPoint segprefix_base;
static bool segprefix_on=false;
#define SegPrefix(blah) \
segprefix_base=SegBase(blah); \
segprefix_on=true; \
lookupEATable=&GetEA_16_s; \
goto restart; \
#define SegPrefix_66(blah) \
segprefix_base=SegBase(blah); \
segprefix_on=true; \
lookupEATable=&GetEA_16_s; \
goto restart_66; \
#define SegPrefixReset \
segprefix_on=false;lookupEATable=&GetEA_16_n;
/* The MOD/RM Decoder for EA for this decoder's addressing modes */
static EAPoint EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); }
static EAPoint EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); }
static EAPoint EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); }
static EAPoint EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); }
static EAPoint EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); }
static EAPoint EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); }
static EAPoint EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());}
static EAPoint EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); }
static EAPoint EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
static EAPoint EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
static EAPoint EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
static EAPoint EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
static EAPoint EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); }
static EAPoint EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); }
static EAPoint EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); }
static EAPoint EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); }
static EAPoint EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
static EAPoint EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
static EAPoint EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
static EAPoint EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
static EAPoint EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); }
static EAPoint EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); }
static EAPoint EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); }
static EAPoint EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); }
static GetEATable GetEA_16_n={
/* 00 */
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
/* 01 */
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
/* 10 */
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
/* 11 These are illegal so make em 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define prefixed(val) EAPoint ret=segprefix_base+val;SegPrefixReset;return ret;
static EAPoint EA_16_00_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si)) }
static EAPoint EA_16_01_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di)) }
static EAPoint EA_16_02_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si)) }
static EAPoint EA_16_03_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di)) }
static EAPoint EA_16_04_s(void) { prefixed((Bit16u)(reg_si)) }
static EAPoint EA_16_05_s(void) { prefixed((Bit16u)(reg_di)) }
static EAPoint EA_16_06_s(void) { prefixed((Bit16u)(Fetchw())) }
static EAPoint EA_16_07_s(void) { prefixed((Bit16u)(reg_bx)) }
static EAPoint EA_16_40_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs())) }
static EAPoint EA_16_41_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs())) }
static EAPoint EA_16_42_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs())) }
static EAPoint EA_16_43_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs())) }
static EAPoint EA_16_44_s(void) { prefixed((Bit16u)(reg_si+Fetchbs())) }
static EAPoint EA_16_45_s(void) { prefixed((Bit16u)(reg_di+Fetchbs())) }
static EAPoint EA_16_46_s(void) { prefixed((Bit16u)(reg_bp+Fetchbs())) }
static EAPoint EA_16_47_s(void) { prefixed((Bit16u)(reg_bx+Fetchbs())) }
static EAPoint EA_16_80_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws())) }
static EAPoint EA_16_81_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws())) }
static EAPoint EA_16_82_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws())) }
static EAPoint EA_16_83_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws())) }
static EAPoint EA_16_84_s(void) { prefixed((Bit16u)(reg_si+Fetchws())) }
static EAPoint EA_16_85_s(void) { prefixed((Bit16u)(reg_di+Fetchws())) }
static EAPoint EA_16_86_s(void) { prefixed((Bit16u)(reg_bp+Fetchws())) }
static EAPoint EA_16_87_s(void) { prefixed((Bit16u)(reg_bx+Fetchws())) }
static GetEATable GetEA_16_s={
/* 00 */
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
/* 01 */
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
/* 10 */
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
/* 11 These are illegal so make em 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
INLINE EAPoint Sib(Bitu mode) {
Bit8u sib=Fetchb();
EAPoint base;
switch (sib&7) {
case 0: /* EAX Base */
base=SegBase(ds)+reg_eax;break;
case 1: /* ECX Base */
base=SegBase(ds)+reg_ecx;break;
case 2: /* EDX Base */
base=SegBase(ds)+reg_edx;break;
case 3: /* EBX Base */
base=SegBase(ds)+reg_ebx;break;
case 4: /* ESP Base */
base=SegBase(ds)+reg_esp;break;
case 5: /* #1 Base */
if (!mode) {
base=SegBase(ds)+Fetchd();break;
} else {
base=SegBase(ss)+reg_ebp;break;
}
case 6: /* ESI Base */
base=SegBase(ds)+reg_esi;break;
case 7: /* EDI Base */
base=SegBase(ds)+reg_edi;break;
}
Bitu shift=sib >> 6;
switch ((sib >>3) &7) {
case 0: /* EAX Index */
base+=(Bit32s)reg_eax<<shift;break;
case 1: /* ECX Index */
base+=(Bit32s)reg_ecx<<shift;break;
case 2: /* EDX Index */
base+=(Bit32s)reg_edx<<shift;break;
case 3: /* EBX Index */
base+=(Bit32s)reg_ebx<<shift;break;
case 4: /* None */
break;
case 5: /* EBP Index */
base+=(Bit32s)reg_ebp<<shift;break;
case 6: /* ESI Index */
base+=(Bit32s)reg_esi<<shift;break;
case 7: /* EDI Index */
base+=(Bit32s)reg_edi<<shift;break;
};
return base;
};
static EAPoint EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
static EAPoint EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
static EAPoint EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
static EAPoint EA_32_03_n(void) { return SegBase(ds)+reg_ebx; }
static EAPoint EA_32_04_n(void) { return Sib(0);}
static EAPoint EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
static EAPoint EA_32_06_n(void) { return SegBase(ss)+reg_esi; }
static EAPoint EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
static EAPoint EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
static EAPoint EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
static EAPoint EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
static EAPoint EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
static EAPoint EA_32_44_n(void) { return Sib(1)+Fetchbs();}
static EAPoint EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); }
static EAPoint EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); }
static EAPoint EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); }
static EAPoint EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); }
static EAPoint EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); }
static EAPoint EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); }
static EAPoint EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); }
static EAPoint EA_32_84_n(void) { return Sib(2)+Fetchds();}
static EAPoint EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); }
static EAPoint EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); }
static EAPoint EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); }
static GetEATable GetEA_32_n={
/* 00 */
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
/* 01 */
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
/* 10 */
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
/* 11 These are illegal so make em 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

View File

@ -1,476 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: core_dyn_x86.cpp,v 1.34 2007/11/24 17:26:48 c2woody Exp $ */
#include "dosbox.h"
#if (C_DYNAMIC_X86)
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#if defined (WIN32)
#include <windows.h>
#include <winbase.h>
#endif
#if (C_HAVE_MPROTECT)
#include <sys/mman.h>
#include <limits.h>
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
#endif /* C_HAVE_MPROTECT */
#include "callback.h"
#include "regs.h"
#include "mem.h"
#include "cpu.h"
#include "debug.h"
#include "paging.h"
#include "inout.h"
#include "fpu.h"
#define CACHE_MAXSIZE (4096*3)
#define CACHE_TOTAL (1024*1024*8)
#define CACHE_PAGES (512)
#define CACHE_BLOCKS (64*1024)
#define CACHE_ALIGN (16)
#define DYN_HASH_SHIFT (4)
#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT)
#define DYN_LINKS (16)
#if 0
#define DYN_LOG LOG_MSG
#else
#define DYN_LOG
#endif
#if C_FPU
#define CPU_FPU 1 //Enable FPU escape instructions
#endif
enum {
G_EAX,G_ECX,G_EDX,G_EBX,
G_ESP,G_EBP,G_ESI,G_EDI,
G_ES,G_CS,G_SS,G_DS,G_FS,G_GS,
G_FLAGS,G_NEWESP,G_EIP,
G_EA,G_STACK,G_CYCLES,
G_TMPB,G_TMPW,G_SHIFT,
G_EXIT,
G_MAX,
};
enum SingleOps {
SOP_INC,SOP_DEC,
SOP_NOT,SOP_NEG,
};
enum DualOps {
DOP_ADD,DOP_ADC,
DOP_SUB,DOP_SBB,
DOP_CMP,DOP_XOR,
DOP_AND,DOP_OR,
DOP_TEST,
DOP_MOV,
DOP_XCHG,
};
enum ShiftOps {
SHIFT_ROL,SHIFT_ROR,
SHIFT_RCL,SHIFT_RCR,
SHIFT_SHL,SHIFT_SHR,
SHIFT_SAL,SHIFT_SAR,
};
enum BranchTypes {
BR_O,BR_NO,BR_B,BR_NB,
BR_Z,BR_NZ,BR_BE,BR_NBE,
BR_S,BR_NS,BR_P,BR_NP,
BR_L,BR_NL,BR_LE,BR_NLE
};
enum BlockReturn {
BR_Normal=0,
BR_Cycles,
BR_Link1,BR_Link2,
BR_Opcode,
#if (C_DEBUG)
BR_OpcodeFull,
#endif
BR_Iret,
BR_CallBack,
BR_SMCBlock
};
#define SMC_CURRENT_BLOCK 0xffff
#define DYNFLG_HAS16 0x1 //Would like 8-bit host reg support
#define DYNFLG_HAS8 0x2 //Would like 16-bit host reg support
#define DYNFLG_LOAD 0x4 //Load value when accessed
#define DYNFLG_SAVE 0x8 //Needs to be saved back at the end of block
#define DYNFLG_CHANGED 0x10 //Value is in a register and changed from load
#define DYNFLG_ACTIVE 0x20 //Register has an active value
class GenReg;
class CodePageHandler;
struct DynReg {
Bitu flags;
GenReg * genreg;
void * data;
};
enum DynAccess {
DA_d,DA_w,
DA_bh,DA_bl
};
enum ByteCombo {
BC_ll,BC_lh,
BC_hl,BC_hh,
};
static DynReg DynRegs[G_MAX];
#define DREG(_WHICH_) &DynRegs[G_ ## _WHICH_ ]
static struct {
Bitu ea,tmpb,tmpd,stack,shift,newesp;
} extra_regs;
static void IllegalOption(const char* msg) {
E_Exit("DynCore: illegal option in %s",msg);
}
#include "core_dyn_x86/cache.h"
static struct {
Bitu callback;
Bit32u readdata;
} core_dyn;
static struct {
Bit32u state[32];
FPU_P_Reg temp,temp2;
Bit32u dh_fpu_enabled;
Bit32u state_used;
Bit32u cw,host_cw;
Bit8u temp_state[128];
} dyn_dh_fpu;
#include "core_dyn_x86/risc_x86.h"
struct DynState {
DynReg regs[G_MAX];
};
static void dyn_flags_host_to_gen(void) {
gen_dop_word(DOP_MOV,true,DREG(EXIT),DREG(FLAGS));
gen_dop_word_imm(DOP_AND,true,DREG(EXIT),FMASK_TEST);
gen_load_flags(DREG(EXIT));
gen_releasereg(DREG(EXIT));
gen_releasereg(DREG(FLAGS));
}
static void dyn_flags_gen_to_host(void) {
gen_save_flags(DREG(EXIT));
gen_dop_word_imm(DOP_AND,true,DREG(EXIT),FMASK_TEST);
gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FMASK_TEST);
gen_dop_word(DOP_OR,true,DREG(FLAGS),DREG(EXIT)); //flags are marked for save
gen_releasereg(DREG(EXIT));
gen_releasereg(DREG(FLAGS));
}
static void dyn_savestate(DynState * state) {
for (Bitu i=0;i<G_MAX;i++) {
state->regs[i].flags=DynRegs[i].flags;
state->regs[i].genreg=DynRegs[i].genreg;
}
}
static void dyn_loadstate(DynState * state) {
for (Bitu i=0;i<G_MAX;i++) {
gen_setupreg(&DynRegs[i],&state->regs[i]);
}
}
static void dyn_synchstate(DynState * state) {
for (Bitu i=0;i<G_MAX;i++) {
gen_synchreg(&DynRegs[i],&state->regs[i]);
}
}
static void dyn_saveregister(DynReg * src_reg, DynReg * dst_reg) {
dst_reg->flags=src_reg->flags;
dst_reg->genreg=src_reg->genreg;
}
static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) {
dst_reg->flags=src_reg->flags;
dst_reg->genreg=src_reg->genreg;
dst_reg->genreg->dynreg=dst_reg; // necessary when register has been released
}
#include "core_dyn_x86/decoder.h"
#if defined (_MSC_VER)
#define DH_FPU_SAVE_REINIT \
{ \
__asm { \
__asm fnsave dyn_dh_fpu.state[0] \
} \
dyn_dh_fpu.state_used=false; \
dyn_dh_fpu.state[0]|=0x3f; \
}
#else
#define DH_FPU_SAVE_REINIT \
{ \
__asm__ volatile ( \
"fnsave %0 \n" \
: \
: "m" (dyn_dh_fpu.state[0]) \
: "memory" \
); \
dyn_dh_fpu.state_used=false; \
dyn_dh_fpu.state[0]|=0x3f; \
}
#endif
Bits CPU_Core_Dyn_X86_Run(void) {
/* Determine the linear address of CS:EIP */
restart_core:
PhysPt ip_point=SegPhys(cs)+reg_eip;
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
CodePageHandler * chandler=0;
if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) {
CPU_Exception(cpu.exception.which,cpu.exception.error);
goto restart_core;
}
if (!chandler) {
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
return CPU_Core_Normal_Run();
}
/* Find correct Dynamic Block to run */
CacheBlock * block=chandler->FindCacheBlock(ip_point&4095);
if (!block) {
if (!chandler->invalidation_map || (chandler->invalidation_map[ip_point&4095]<4)) {
block=CreateCacheBlock(chandler,ip_point,32);
} else {
Bitu old_cycles=CPU_Cycles;
CPU_Cycles=1;
Bits nc_retcode=CPU_Core_Normal_Run();
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
if (!nc_retcode) {
CPU_Cycles=old_cycles-1;
goto restart_core;
}
CPU_CycleLeft+=old_cycles;
return nc_retcode;
}
}
run_block:
cache.block.running=0;
BlockReturn ret=gen_runcode(block->cache.start);
switch (ret) {
case BR_Iret:
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) {
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
return debugCallback;
}
#endif
if (!GETFLAG(TF)) goto restart_core;
cpudecoder=CPU_Core_Dyn_X86_Trap_Run;
if (!dyn_dh_fpu.state_used) return CBRET_NONE;
DH_FPU_SAVE_REINIT
return CBRET_NONE;
case BR_Normal:
/* Maybe check if we staying in the same page? */
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
goto restart_core;
case BR_Cycles:
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
if (!dyn_dh_fpu.state_used) return CBRET_NONE;
DH_FPU_SAVE_REINIT
return CBRET_NONE;
case BR_CallBack:
if (!dyn_dh_fpu.state_used) return core_dyn.callback;
DH_FPU_SAVE_REINIT
return core_dyn.callback;
case BR_SMCBlock:
// LOG_MSG("selfmodification of running block at %x:%x",SegValue(cs),reg_eip);
cpu.exception.which=0;
// fallthrough, let the normal core handle the block-modifying instruction
case BR_Opcode:
CPU_CycleLeft+=CPU_Cycles;
CPU_Cycles=1;
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
return CPU_Core_Normal_Run();
#if (C_DEBUG)
case BR_OpcodeFull:
CPU_CycleLeft+=CPU_Cycles;
CPU_Cycles=1;
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
return CPU_Core_Full_Run();
#endif
case BR_Link1:
case BR_Link2:
{
Bitu temp_ip=SegPhys(cs)+reg_eip;
CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_readhandler(temp_ip);
if (temp_handler->flags & PFLAG_HASCODE) {
block=temp_handler->FindCacheBlock(temp_ip & 4095);
if (!block) goto restart_core;
cache.block.running->LinkTo(ret==BR_Link2,block);
goto run_block;
}
}
goto restart_core;
}
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
return CBRET_NONE;
}
Bits CPU_Core_Dyn_X86_Trap_Run(void) {
Bits oldCycles = CPU_Cycles;
CPU_Cycles = 1;
cpu.trap_skip = false;
Bits ret=CPU_Core_Normal_Run();
if (!cpu.trap_skip) CPU_HW_Interrupt(1);
CPU_Cycles = oldCycles-1;
cpudecoder = &CPU_Core_Dyn_X86_Run;
return ret;
}
void CPU_Core_Dyn_X86_Init(void) {
Bits i;
/* Setup the global registers and their flags */
for (i=0;i<G_MAX;i++) DynRegs[i].genreg=0;
DynRegs[G_EAX].data=&reg_eax;
DynRegs[G_EAX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_ECX].data=&reg_ecx;
DynRegs[G_ECX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EDX].data=&reg_edx;
DynRegs[G_EDX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EBX].data=&reg_ebx;
DynRegs[G_EBX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EBP].data=&reg_ebp;
DynRegs[G_EBP].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_ESP].data=&reg_esp;
DynRegs[G_ESP].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EDI].data=&reg_edi;
DynRegs[G_EDI].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_ESI].data=&reg_esi;
DynRegs[G_ESI].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_ES].data=&Segs.phys[es];
DynRegs[G_ES].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_CS].data=&Segs.phys[cs];
DynRegs[G_CS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_SS].data=&Segs.phys[ss];
DynRegs[G_SS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_DS].data=&Segs.phys[ds];
DynRegs[G_DS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_FS].data=&Segs.phys[fs];
DynRegs[G_FS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_GS].data=&Segs.phys[gs];
DynRegs[G_GS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_FLAGS].data=&reg_flags;
DynRegs[G_FLAGS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_NEWESP].data=&extra_regs.newesp;
DynRegs[G_NEWESP].flags=0;
DynRegs[G_EIP].data=&reg_eip;
DynRegs[G_EIP].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EA].data=&extra_regs.ea;
DynRegs[G_EA].flags=0;
DynRegs[G_STACK].data=&extra_regs.stack;
DynRegs[G_STACK].flags=0;
DynRegs[G_CYCLES].data=&CPU_Cycles;
DynRegs[G_CYCLES].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_TMPB].data=&extra_regs.tmpb;
DynRegs[G_TMPB].flags=DYNFLG_HAS8|DYNFLG_HAS16;
DynRegs[G_TMPW].data=&extra_regs.tmpd;
DynRegs[G_TMPW].flags=DYNFLG_HAS16;
DynRegs[G_SHIFT].data=&extra_regs.shift;
DynRegs[G_SHIFT].flags=DYNFLG_HAS8|DYNFLG_HAS16;
DynRegs[G_EXIT].data=0;
DynRegs[G_EXIT].flags=DYNFLG_HAS16;
/* Init the generator */
gen_init();
/* Init the fpu state */
dyn_dh_fpu.dh_fpu_enabled=true;
dyn_dh_fpu.state_used=false;
dyn_dh_fpu.cw=0x37f;
#if defined (_MSC_VER)
__asm {
__asm finit
__asm fsave dyn_dh_fpu.state[0]
__asm fstcw dyn_dh_fpu.host_cw
}
#else
__asm__ volatile (
"finit \n"
"fsave %0 \n"
"fstcw %1 \n"
:
: "m" (dyn_dh_fpu.state[0]), "m" (dyn_dh_fpu.host_cw)
: "memory"
);
#endif
return;
}
void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache) {
/* Initialize code cache and dynamic blocks */
cache_init(enable_cache);
}
void CPU_Core_Dyn_X86_Cache_Close(void) {
cache_close();
}
void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu) {
dyn_dh_fpu.dh_fpu_enabled=dh_fpu;
}
#endif

View File

@ -1,2 +0,0 @@
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \
dyn_fpu.h dyn_fpu_dh.h

View File

@ -1,528 +0,0 @@
class CacheBlock {
public:
void Clear(void);
void LinkTo(Bitu index,CacheBlock * toblock) {
assert(toblock);
link[index].to=toblock;
link[index].next=toblock->link[index].from;
toblock->link[index].from=this;
}
struct {
Bit16u start,end; //Where the page is the original code
CodePageHandler * handler; //Page containing this code
} page;
struct {
Bit8u * start; //Where in the cache are we
Bitu size;
CacheBlock * next;
Bit8u * wmapmask;
Bit16u maskstart;
Bit16u masklen;
} cache;
struct {
Bitu index;
CacheBlock * next;
} hash;
struct {
CacheBlock * to;
CacheBlock * next;
CacheBlock * from;
} link[2];
CacheBlock * crossblock;
};
static struct {
struct {
CacheBlock * first;
CacheBlock * active;
CacheBlock * free;
CacheBlock * running;
} block;
Bit8u * pos;
CodePageHandler * free_pages;
CodePageHandler * used_pages;
CodePageHandler * last_page;
} cache;
static CacheBlock link_blocks[2];
class CodePageHandler : public PageHandler {
public:
CodePageHandler() {
invalidation_map=NULL;
}
void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) {
phys_page=_phys_page;
old_pagehandler=_old_pagehandler;
flags=old_pagehandler->flags|PFLAG_HASCODE;
flags&=~PFLAG_WRITEABLE;
active_blocks=0;
active_count=16;
memset(&hash_map,0,sizeof(hash_map));
memset(&write_map,0,sizeof(write_map));
if (invalidation_map!=NULL) {
free(invalidation_map);
invalidation_map=NULL;
}
}
bool InvalidateRange(Bitu start,Bitu end) {
Bits index=1+(end>>DYN_HASH_SHIFT);
bool is_current_block=false;
Bit32u ip_point=SegPhys(cs)+reg_eip;
ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff);
while (index>=0) {
Bitu map=0;
for (Bitu count=start;count<=end;count++) map+=write_map[count];
if (!map) return is_current_block;
CacheBlock * block=hash_map[index];
while (block) {
CacheBlock * nextblock=block->hash.next;
if (start<=block->page.end && end>=block->page.start) {
if (ip_point<=block->page.end && ip_point>=block->page.start) is_current_block=true;
block->Clear();
}
block=nextblock;
}
index--;
}
return is_current_block;
}
void writeb(PhysPt addr,Bitu val){
addr&=4095;
if (host_readb(hostmem+addr)==(Bit8u)val) return;
host_writeb(hostmem+addr,val);
if (!*(Bit8u*)&write_map[addr]) {
if (active_blocks) return;
active_count--;
if (!active_count) Release();
return;
} else if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
invalidation_map[addr]++;
InvalidateRange(addr,addr);
}
void writew(PhysPt addr,Bitu val){
addr&=4095;
if (host_readw(hostmem+addr)==(Bit16u)val) return;
host_writew(hostmem+addr,val);
if (!*(Bit16u*)&write_map[addr]) {
if (active_blocks) return;
active_count--;
if (!active_count) Release();
return;
} else if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
(*(Bit16u*)&invalidation_map[addr])+=0x101;
InvalidateRange(addr,addr+1);
}
void writed(PhysPt addr,Bitu val){
addr&=4095;
if (host_readd(hostmem+addr)==(Bit32u)val) return;
host_writed(hostmem+addr,val);
if (!*(Bit32u*)&write_map[addr]) {
if (active_blocks) return;
active_count--;
if (!active_count) Release();
return;
} else if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
InvalidateRange(addr,addr+3);
}
bool writeb_checked(PhysPt addr,Bitu val) {
addr&=4095;
if (host_readb(hostmem+addr)==(Bit8u)val) return false;
if (!*(Bit8u*)&write_map[addr]) {
if (!active_blocks) {
active_count--;
if (!active_count) Release();
}
} else {
if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
invalidation_map[addr]++;
if (InvalidateRange(addr,addr)) {
cpu.exception.which=SMC_CURRENT_BLOCK;
return true;
}
}
host_writeb(hostmem+addr,val);
return false;
}
bool writew_checked(PhysPt addr,Bitu val) {
addr&=4095;
if (host_readw(hostmem+addr)==(Bit16u)val) return false;
if (!*(Bit16u*)&write_map[addr]) {
if (!active_blocks) {
active_count--;
if (!active_count) Release();
}
} else {
if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
(*(Bit16u*)&invalidation_map[addr])+=0x101;
if (InvalidateRange(addr,addr+1)) {
cpu.exception.which=SMC_CURRENT_BLOCK;
return true;
}
}
host_writew(hostmem+addr,val);
return false;
}
bool writed_checked(PhysPt addr,Bitu val) {
addr&=4095;
if (host_readd(hostmem+addr)==(Bit32u)val) return false;
if (!*(Bit32u*)&write_map[addr]) {
if (!active_blocks) {
active_count--;
if (!active_count) Release();
}
} else {
if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
if (InvalidateRange(addr,addr+3)) {
cpu.exception.which=SMC_CURRENT_BLOCK;
return true;
}
}
host_writed(hostmem+addr,val);
return false;
}
void AddCacheBlock(CacheBlock * block) {
Bitu index=1+(block->page.start>>DYN_HASH_SHIFT);
block->hash.next=hash_map[index];
block->hash.index=index;
hash_map[index]=block;
block->page.handler=this;
active_blocks++;
}
void AddCrossBlock(CacheBlock * block) {
block->hash.next=hash_map[0];
block->hash.index=0;
hash_map[0]=block;
block->page.handler=this;
active_blocks++;
}
void DelCacheBlock(CacheBlock * block) {
active_blocks--;
active_count=16;
CacheBlock * * where=&hash_map[block->hash.index];
while (*where!=block) {
where=&((*where)->hash.next);
//Will crash if a block isn't found, which should never happen.
}
*where=block->hash.next;
if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) {
for (Bitu i=block->page.start;i<block->cache.maskstart;i++) {
if (write_map[i]) write_map[i]--;
}
Bitu maskct=0;
for (Bitu i=block->cache.maskstart;i<=block->page.end;i++,maskct++) {
if (write_map[i]) {
if ((maskct>=block->cache.masklen) || (!block->cache.wmapmask[maskct])) write_map[i]--;
}
}
free(block->cache.wmapmask);
block->cache.wmapmask=NULL;
} else {
for (Bitu i=block->page.start;i<=block->page.end;i++) {
if (write_map[i]) write_map[i]--;
}
}
}
void Release(void) {
MEM_SetPageHandler(phys_page,1,old_pagehandler);
PAGING_ClearTLB();
if (prev) prev->next=next;
else cache.used_pages=next;
if (next) next->prev=prev;
else cache.last_page=prev;
next=cache.free_pages;
cache.free_pages=this;
prev=0;
}
void ClearRelease(void) {
for (Bitu index=0;index<(1+DYN_PAGE_HASH);index++) {
CacheBlock * block=hash_map[index];
while (block) {
CacheBlock * nextblock=block->hash.next;
block->page.handler=0; //No need, full clear
block->Clear();
block=nextblock;
}
}
Release();
}
CacheBlock * FindCacheBlock(Bitu start) {
CacheBlock * block=hash_map[1+(start>>DYN_HASH_SHIFT)];
while (block) {
if (block->page.start==start) return block;
block=block->hash.next;
}
return 0;
}
HostPt GetHostReadPt(Bitu phys_page) {
hostmem=old_pagehandler->GetHostReadPt(phys_page);
return hostmem;
}
HostPt GetHostWritePt(Bitu phys_page) {
return GetHostReadPt( phys_page );
}
public:
Bit8u write_map[4096];
Bit8u * invalidation_map;
CodePageHandler * next, * prev;
private:
PageHandler * old_pagehandler;
CacheBlock * hash_map[1+DYN_PAGE_HASH];
Bitu active_blocks;
Bitu active_count;
HostPt hostmem;
Bitu phys_page;
};
static INLINE void cache_addunsedblock(CacheBlock * block) {
block->cache.next=cache.block.free;
cache.block.free=block;
}
static CacheBlock * cache_getblock(void) {
CacheBlock * ret=cache.block.free;
if (!ret) E_Exit("Ran out of CacheBlocks" );
cache.block.free=ret->cache.next;
ret->cache.next=0;
return ret;
}
void CacheBlock::Clear(void) {
Bitu ind;
/* Check if this is not a cross page block */
if (hash.index) for (ind=0;ind<2;ind++) {
CacheBlock * fromlink=link[ind].from;
link[ind].from=0;
while (fromlink) {
CacheBlock * nextlink=fromlink->link[ind].next;
fromlink->link[ind].next=0;
fromlink->link[ind].to=&link_blocks[ind];
fromlink=nextlink;
}
if (link[ind].to!=&link_blocks[ind]) {
CacheBlock * * wherelink=&link[ind].to->link[ind].from;
while (*wherelink != this && *wherelink) {
wherelink = &(*wherelink)->link[ind].next;
}
if(*wherelink)
*wherelink = (*wherelink)->link[ind].next;
else
LOG(LOG_CPU,LOG_ERROR)("Cache anomaly. please investigate");
}
} else
cache_addunsedblock(this);
if (crossblock) {
crossblock->crossblock=0;
crossblock->Clear();
crossblock=0;
}
if (page.handler) {
page.handler->DelCacheBlock(this);
page.handler=0;
}
if (cache.wmapmask){
free(cache.wmapmask);
cache.wmapmask=NULL;
}
}
static CacheBlock * cache_openblock(void) {
CacheBlock * block=cache.block.active;
/* check for enough space in this block */
Bitu size=block->cache.size;
CacheBlock * nextblock=block->cache.next;
if (block->page.handler)
block->Clear();
while (size<CACHE_MAXSIZE) {
if (!nextblock)
goto skipresize;
size+=nextblock->cache.size;
CacheBlock * tempblock=nextblock->cache.next;
if (nextblock->page.handler)
nextblock->Clear();
cache_addunsedblock(nextblock);
nextblock=tempblock;
}
skipresize:
block->cache.size=size;
block->cache.next=nextblock;
cache.pos=block->cache.start;
return block;
}
static void cache_closeblock(void) {
CacheBlock * block=cache.block.active;
block->link[0].to=&link_blocks[0];
block->link[1].to=&link_blocks[1];
block->link[0].from=0;
block->link[1].from=0;
block->link[0].next=0;
block->link[1].next=0;
/* Close the block with correct alignments */
Bitu written=cache.pos-block->cache.start;
if (written>block->cache.size) {
if (!block->cache.next) {
if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun 1 %d",written-block->cache.size);
} else E_Exit("CacheBlock overrun 2 written %d size %d",written,block->cache.size);
} else {
Bitu new_size;
Bitu left=block->cache.size-written;
/* Smaller than cache align then don't bother to resize */
if (left>CACHE_ALIGN) {
new_size=((written-1)|(CACHE_ALIGN-1))+1;
CacheBlock * newblock=cache_getblock();
newblock->cache.start=block->cache.start+new_size;
newblock->cache.size=block->cache.size-new_size;
newblock->cache.next=block->cache.next;
block->cache.next=newblock;
block->cache.size=new_size;
}
}
/* Advance the active block pointer */
if (!block->cache.next) {
// LOG_MSG("Cache full restarting");
cache.block.active=cache.block.first;
} else {
cache.block.active=block->cache.next;
}
}
static INLINE void cache_addb(Bit8u val) {
*cache.pos++=val;
}
static INLINE void cache_addw(Bit16u val) {
*(Bit16u*)cache.pos=val;
cache.pos+=2;
}
static INLINE void cache_addd(Bit32u val) {
*(Bit32u*)cache.pos=val;
cache.pos+=4;
}
static void gen_return(BlockReturn retcode);
static Bit8u * cache_code_start_ptr=NULL;
static Bit8u * cache_code=NULL;
static Bit8u * cache_code_link_blocks=NULL;
static CacheBlock * cache_blocks=NULL;
/* Define temporary pagesize so the MPROTECT case and the regular case share as much code as possible */
#if (C_HAVE_MPROTECT)
#define PAGESIZE_TEMP PAGESIZE
#else
#define PAGESIZE_TEMP 4096
#endif
static bool cache_initialized = false;
static void cache_init(bool enable) {
Bits i;
if (enable) {
if (cache_initialized) return;
cache_initialized = true;
if (cache_blocks == NULL) {
cache_blocks=(CacheBlock*)malloc(CACHE_BLOCKS*sizeof(CacheBlock));
if(!cache_blocks) E_Exit("Allocating cache_blocks has failed");
memset(cache_blocks,0,sizeof(CacheBlock)*CACHE_BLOCKS);
cache.block.free=&cache_blocks[0];
for (i=0;i<CACHE_BLOCKS-1;i++) {
cache_blocks[i].link[0].to=(CacheBlock *)1;
cache_blocks[i].link[1].to=(CacheBlock *)1;
cache_blocks[i].cache.next=&cache_blocks[i+1];
}
}
if (cache_code_start_ptr==NULL) {
#if defined (WIN32)
cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if (!cache_code_start_ptr)
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#else
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#endif
if(!cache_code_start_ptr) E_Exit("Allocating dynamic core cache memory failed");
cache_code=(Bit8u*)(((int)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //MEM LEAK. store old pointer if you want to free it.
cache_code_link_blocks=cache_code;
cache_code+=PAGESIZE_TEMP;
#if (C_HAVE_MPROTECT)
if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
LOG_MSG("Setting excute permission on the code cache has failed!");
#endif
CacheBlock * block=cache_getblock();
cache.block.first=block;
cache.block.active=block;
block->cache.start=&cache_code[0];
block->cache.size=CACHE_TOTAL;
block->cache.next=0; //Last block in the list
}
/* Setup the default blocks for block linkage returns */
cache.pos=&cache_code_link_blocks[0];
link_blocks[0].cache.start=cache.pos;
gen_return(BR_Link1);
cache.pos=&cache_code_link_blocks[32];
link_blocks[1].cache.start=cache.pos;
gen_return(BR_Link2);
cache.free_pages=0;
cache.last_page=0;
cache.used_pages=0;
/* Setup the code pages */
for (i=0;i<CACHE_PAGES;i++) {
CodePageHandler * newpage=new CodePageHandler();
newpage->next=cache.free_pages;
cache.free_pages=newpage;
}
}
}
static void cache_close(void) {
/* for (;;) {
if (cache.used_pages) {
CodePageHandler * cpage=cache.used_pages;
CodePageHandler * npage=cache.used_pages->next;
cpage->ClearRelease();
delete cpage;
cache.used_pages=npage;
} else break;
}
if (cache_blocks != NULL) {
free(cache_blocks);
cache_blocks = NULL;
}
if (cache_code_start_ptr != NULL) {
### care: under windows VirtualFree() has to be used if
### VirtualAlloc was used for memory allocation
free(cache_code_start_ptr);
cache_code_start_ptr = NULL;
}
cache_code = NULL;
cache_code_link_blocks = NULL;
cache_initialized = false; */
}

File diff suppressed because it is too large Load Diff

View File

@ -1,665 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dyn_fpu.h,v 1.3 2007/06/14 17:47:24 c2woody Exp $ */
#include "dosbox.h"
#if C_FPU
#include <math.h>
#include <float.h>
#include "cross.h"
#include "mem.h"
#include "fpu.h"
#include "cpu.h"
static void FPU_FDECSTP(){
TOP = (TOP - 1) & 7;
}
static void FPU_FINCSTP(){
TOP = (TOP + 1) & 7;
}
static void FPU_FNSTCW(PhysPt addr){
mem_writew(addr,fpu.cw);
}
static void FPU_FFREE(Bitu st) {
fpu.tags[st]=TAG_Empty;
}
#if C_FPU_X86
#include "../../fpu/fpu_instructions_x86.h"
#else
#include "../../fpu/fpu_instructions.h"
#endif
#define dyn_fpu_top() { \
gen_protectflags(); \
gen_load_host(&TOP,DREG(EA),4); \
gen_dop_word_imm(DOP_ADD,true,DREG(EA),decode.modrm.rm); \
gen_dop_word_imm(DOP_AND,true,DREG(EA),7); \
gen_load_host(&TOP,DREG(TMPB),4); \
}
static void dyn_eatree() {
Bitu group=(decode.modrm.val >> 3) & 7;
switch (group){
case 0x00: /* FADD ST,STi */
gen_call_function((void*)&FPU_FADD_EA,"%Ddr",DREG(TMPB));
break;
case 0x01: /* FMUL ST,STi */
gen_call_function((void*)&FPU_FMUL_EA,"%Ddr",DREG(TMPB));
break;
case 0x02: /* FCOM STi */
gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB));
break;
case 0x03: /* FCOMP STi */
gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04: /* FSUB ST,STi */
gen_call_function((void*)&FPU_FSUB_EA,"%Ddr",DREG(TMPB));
break;
case 0x05: /* FSUBR ST,STi */
gen_call_function((void*)&FPU_FSUBR_EA,"%Ddr",DREG(TMPB));
break;
case 0x06: /* FDIV ST,STi */
gen_call_function((void*)&FPU_FDIV_EA,"%Ddr",DREG(TMPB));
break;
case 0x07: /* FDIVR ST,STi */
gen_call_function((void*)&FPU_FDIVR_EA,"%Ddr",DREG(TMPB));
break;
default:
break;
}
}
static void dyn_fpu_esc0(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
dyn_fpu_top();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
switch (group){
case 0x00: //FADD ST,STi /
gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x01: // FMUL ST,STi /
gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x02: // FCOM STi /
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x03: // FCOMP STi /
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04: // FSUB ST,STi /
gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x05: // FSUBR ST,STi /
gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x06: // FDIV ST,STi /
gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x07: // FDIVR ST,STi /
gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
default:
break;
}
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_F32_EA,"%Ddr",DREG(EA));
gen_load_host(&TOP,DREG(TMPB),4);
dyn_eatree();
}
}
static void dyn_fpu_esc1(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
switch (group){
case 0x00: /* FLD STi */
gen_protectflags();
gen_load_host(&TOP,DREG(EA),4);
gen_dop_word_imm(DOP_ADD,true,DREG(EA),decode.modrm.rm);
gen_dop_word_imm(DOP_AND,true,DREG(EA),7);
gen_call_function((void*)&FPU_PREP_PUSH,"");
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x01: /* FXCH STi */
dyn_fpu_top();
gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x02: /* FNOP */
gen_call_function((void*)&FPU_FNOP,"");
break;
case 0x03: /* FSTP STi */
dyn_fpu_top();
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04:
switch(sub){
case 0x00: /* FCHS */
gen_call_function((void*)&FPU_FCHS,"");
break;
case 0x01: /* FABS */
gen_call_function((void*)&FPU_FABS,"");
break;
case 0x02: /* UNKNOWN */
case 0x03: /* ILLEGAL */
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
case 0x04: /* FTST */
gen_call_function((void*)&FPU_FTST,"");
break;
case 0x05: /* FXAM */
gen_call_function((void*)&FPU_FXAM,"");
break;
case 0x06: /* FTSTP (cyrix)*/
case 0x07: /* UNKNOWN */
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
}
break;
case 0x05:
switch(sub){
case 0x00: /* FLD1 */
gen_call_function((void*)&FPU_FLD1,"");
break;
case 0x01: /* FLDL2T */
gen_call_function((void*)&FPU_FLDL2T,"");
break;
case 0x02: /* FLDL2E */
gen_call_function((void*)&FPU_FLDL2E,"");
break;
case 0x03: /* FLDPI */
gen_call_function((void*)&FPU_FLDPI,"");
break;
case 0x04: /* FLDLG2 */
gen_call_function((void*)&FPU_FLDLG2,"");
break;
case 0x05: /* FLDLN2 */
gen_call_function((void*)&FPU_FLDLN2,"");
break;
case 0x06: /* FLDZ*/
gen_call_function((void*)&FPU_FLDZ,"");
break;
case 0x07: /* ILLEGAL */
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
}
break;
case 0x06:
switch(sub){
case 0x00: /* F2XM1 */
gen_call_function((void*)&FPU_F2XM1,"");
break;
case 0x01: /* FYL2X */
gen_call_function((void*)&FPU_FYL2X,"");
break;
case 0x02: /* FPTAN */
gen_call_function((void*)&FPU_FPTAN,"");
break;
case 0x03: /* FPATAN */
gen_call_function((void*)&FPU_FPATAN,"");
break;
case 0x04: /* FXTRACT */
gen_call_function((void*)&FPU_FXTRACT,"");
break;
case 0x05: /* FPREM1 */
gen_call_function((void*)&FPU_FPREM1,"");
break;
case 0x06: /* FDECSTP */
gen_call_function((void*)&FPU_FDECSTP,"");
break;
case 0x07: /* FINCSTP */
gen_call_function((void*)&FPU_FINCSTP,"");
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
}
break;
case 0x07:
switch(sub){
case 0x00: /* FPREM */
gen_call_function((void*)&FPU_FPREM,"");
break;
case 0x01: /* FYL2XP1 */
gen_call_function((void*)&FPU_FYL2XP1,"");
break;
case 0x02: /* FSQRT */
gen_call_function((void*)&FPU_FSQRT,"");
break;
case 0x03: /* FSINCOS */
gen_call_function((void*)&FPU_FSINCOS,"");
break;
case 0x04: /* FRNDINT */
gen_call_function((void*)&FPU_FRNDINT,"");
break;
case 0x05: /* FSCALE */
gen_call_function((void*)&FPU_FSCALE,"");
break;
case 0x06: /* FSIN */
gen_call_function((void*)&FPU_FSIN,"");
break;
case 0x07: /* FCOS */
gen_call_function((void*)&FPU_FCOS,"");
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
break;
}
} else {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
dyn_fill_ea();
switch(group){
case 0x00: /* FLD float*/
gen_protectflags();
gen_call_function((void*)&FPU_PREP_PUSH,"");
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_FLD_F32,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x01: /* UNKNOWN */
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FST float*/
gen_call_function((void*)&FPU_FST_F32,"%Ddr",DREG(EA));
break;
case 0x03: /* FSTP float*/
gen_call_function((void*)&FPU_FST_F32,"%Ddr",DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04: /* FLDENV */
gen_call_function((void*)&FPU_FLDENV,"%Ddr",DREG(EA));
break;
case 0x05: /* FLDCW */
gen_call_function((void *)&FPU_FLDCW,"%Ddr",DREG(EA));
break;
case 0x06: /* FSTENV */
gen_call_function((void *)&FPU_FSTENV,"%Ddr",DREG(EA));
break;
case 0x07: /* FNSTCW*/
gen_call_function((void *)&FPU_FNSTCW,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
break;
}
}
}
static void dyn_fpu_esc2(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
switch(group){
case 0x05:
switch(sub){
case 0x01: /* FUCOMPP */
gen_protectflags();
gen_load_host(&TOP,DREG(EA),4);
gen_dop_word_imm(DOP_ADD,true,DREG(EA),1);
gen_dop_word_imm(DOP_AND,true,DREG(EA),7);
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void *)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
gen_call_function((void *)&FPU_FPOP,"");
gen_call_function((void *)&FPU_FPOP,"");
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub);
break;
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub);
break;
}
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_I32_EA,"%Ddr",DREG(EA));
gen_load_host(&TOP,DREG(TMPB),4);
dyn_eatree();
}
}
static void dyn_fpu_esc3(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
switch (group) {
case 0x04:
switch (sub) {
case 0x00: //FNENI
case 0x01: //FNDIS
LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub);
break;
case 0x02: //FNCLEX FCLEX
gen_call_function((void*)&FPU_FCLEX,"");
break;
case 0x03: //FNINIT FINIT
gen_call_function((void*)&FPU_FINIT,"");
break;
case 0x04: //FNSETPM
case 0x05: //FRSTPM
// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
break;
default:
E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub);
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub);
break;
}
} else {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
dyn_fill_ea();
switch(group){
case 0x00: /* FILD */
gen_call_function((void*)&FPU_PREP_PUSH,"");
gen_protectflags();
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_FLD_I32,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x01: /* FISTTP */
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FIST */
gen_call_function((void*)&FPU_FST_I32,"%Ddr",DREG(EA));
break;
case 0x03: /* FISTP */
gen_call_function((void*)&FPU_FST_I32,"%Ddr",DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x05: /* FLD 80 Bits Real */
gen_call_function((void*)&FPU_PREP_PUSH,"");
gen_call_function((void*)&FPU_FLD_F80,"%Ddr",DREG(EA));
break;
case 0x07: /* FSTP 80 Bits Real */
gen_call_function((void*)&FPU_FST_F80,"%Ddr",DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
}
}
}
static void dyn_fpu_esc4(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
dyn_fpu_top();
switch(group){
case 0x00: /* FADD STi,ST*/
gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x01: /* FMUL STi,ST*/
gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x02: /* FCOM*/
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x03: /* FCOMP*/
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04: /* FSUBR STi,ST*/
gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x05: /* FSUB STi,ST*/
gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x06: /* FDIVR STi,ST*/
gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x07: /* FDIV STi,ST*/
gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
default:
break;
}
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_F64_EA,"%Ddr",DREG(EA));
gen_load_host(&TOP,DREG(TMPB),4);
dyn_eatree();
}
}
static void dyn_fpu_esc5(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
dyn_fpu_top();
switch(group){
case 0x00: /* FFREE STi */
gen_call_function((void*)&FPU_FFREE,"%Ddr",DREG(EA));
break;
case 0x01: /* FXCH STi*/
gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x02: /* FST STi */
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x03: /* FSTP STi*/
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04: /* FUCOM STi */
gen_call_function((void*)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x05: /*FUCOMP STi */
gen_call_function((void*)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",group,sub);
break;
}
gen_releasereg(DREG(EA));
gen_releasereg(DREG(TMPB));
} else {
dyn_fill_ea();
switch(group){
case 0x00: /* FLD double real*/
gen_call_function((void*)&FPU_PREP_PUSH,"");
gen_protectflags();
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_FLD_F64,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x01: /* FISTTP longint*/
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FST double real*/
gen_call_function((void*)&FPU_FST_F64,"%Ddr",DREG(EA));
break;
case 0x03: /* FSTP double real*/
gen_call_function((void*)&FPU_FST_F64,"%Ddr",DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04: /* FRSTOR */
gen_call_function((void*)&FPU_FRSTOR,"%Ddr",DREG(EA));
break;
case 0x06: /* FSAVE */
gen_call_function((void*)&FPU_FSAVE,"%Ddr",DREG(EA));
break;
case 0x07: /*FNSTSW */
gen_protectflags();
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_SET_TOP,"%Dd",DREG(TMPB));
gen_load_host(&fpu.sw,DREG(TMPB),4);
gen_call_function((void*)&mem_writew,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
}
}
}
static void dyn_fpu_esc6(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
dyn_fpu_top();
switch(group){
case 0x00: /*FADDP STi,ST*/
gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x01: /* FMULP STi,ST*/
gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x02: /* FCOMP5*/
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break; /* TODO IS THIS ALLRIGHT ????????? */
case 0x03: /*FCOMPP*/
if(sub != 1) {
LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub);
return;
}
gen_load_host(&TOP,DREG(EA),4);
gen_dop_word_imm(DOP_ADD,true,DREG(EA),1);
gen_dop_word_imm(DOP_AND,true,DREG(EA),7);
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
gen_call_function((void*)&FPU_FPOP,""); /* extra pop at the bottom*/
break;
case 0x04: /* FSUBRP STi,ST*/
gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x05: /* FSUBP STi,ST*/
gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x06: /* FDIVRP STi,ST*/
gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x07: /* FDIVP STi,ST*/
gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
default:
break;
}
gen_call_function((void*)&FPU_FPOP,"");
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_I16_EA,"%Ddr",DREG(EA));
gen_load_host(&TOP,DREG(TMPB),4);
dyn_eatree();
}
}
static void dyn_fpu_esc7(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
switch (group){
case 0x01: /* FXCH STi*/
dyn_fpu_top();
gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
break;
case 0x02: /* FSTP STi*/
case 0x03: /* FSTP STi*/
dyn_fpu_top();
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04:
switch(sub){
case 0x00: /* FNSTSW AX*/
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_SET_TOP,"%Ddr",DREG(TMPB));
gen_mov_host(&fpu.sw,DREG(EAX),2);
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
break;
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
break;
}
} else {
dyn_fill_ea();
switch(group){
case 0x00: /* FILD Bit16s */
gen_call_function((void*)&FPU_PREP_PUSH,"");
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_FLD_I16,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x01:
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FIST Bit16s */
gen_call_function((void*)&FPU_FST_I16,"%Ddr",DREG(EA));
break;
case 0x03: /* FISTP Bit16s */
gen_call_function((void*)&FPU_FST_I16,"%Ddr",DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x04: /* FBLD packed BCD */
gen_call_function((void*)&FPU_PREP_PUSH,"");
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_FBLD,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x05: /* FILD Bit64s */
gen_call_function((void*)&FPU_PREP_PUSH,"");
gen_load_host(&TOP,DREG(TMPB),4);
gen_call_function((void*)&FPU_FLD_I64,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
break;
case 0x06: /* FBSTP packed BCD */
gen_call_function((void*)&FPU_FBST,"%Ddr",DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x07: /* FISTP Bit64s */
gen_call_function((void*)&FPU_FST_I64,"%Ddr",DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
break;
}
}
}
#endif

View File

@ -1,494 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dyn_fpu_dh.h,v 1.5 2007/09/29 13:23:59 c2woody Exp $ */
#include "dosbox.h"
#if C_FPU
static void FPU_FLD_16(PhysPt addr) {
dyn_dh_fpu.temp.m1 = (Bit32u)mem_readw(addr);
}
static void FPU_FST_16(PhysPt addr) {
mem_writew(addr,(Bit16u)dyn_dh_fpu.temp.m1);
}
static void FPU_FLD_32(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd(addr);
}
static void FPU_FST_32(PhysPt addr) {
mem_writed(addr,dyn_dh_fpu.temp.m1);
}
static void FPU_FLD_64(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd(addr);
dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
}
static void FPU_FST_64(PhysPt addr) {
mem_writed(addr,dyn_dh_fpu.temp.m1);
mem_writed(addr+4,dyn_dh_fpu.temp.m2);
}
static void FPU_FLD_80(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd(addr);
dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
dyn_dh_fpu.temp.m3 = mem_readw(addr+8);
}
static void FPU_FST_80(PhysPt addr) {
mem_writed(addr,dyn_dh_fpu.temp.m1);
mem_writed(addr+4,dyn_dh_fpu.temp.m2);
mem_writew(addr+8,dyn_dh_fpu.temp.m3);
}
static void FPU_FLDCW_DH(PhysPt addr){
dyn_dh_fpu.cw = mem_readw(addr);
dyn_dh_fpu.temp.m1 = (Bit32u)(dyn_dh_fpu.cw|0x3f);
}
static void FPU_FNSTCW_DH(PhysPt addr){
mem_writew(addr,(Bit16u)(dyn_dh_fpu.cw&0xffff));
}
static void FPU_FNINIT_DH(void){
dyn_dh_fpu.cw = 0x37f;
}
static void FPU_FSTENV_DH(PhysPt addr){
if(!cpu.code.big) {
mem_writew(addr+0,(Bit16u)dyn_dh_fpu.cw);
mem_writew(addr+2,(Bit16u)dyn_dh_fpu.temp.m2);
mem_writew(addr+4,dyn_dh_fpu.temp.m3);
} else {
mem_writed(addr+0,dyn_dh_fpu.temp.m1);
mem_writew(addr+0,(Bit16u)dyn_dh_fpu.cw);
mem_writed(addr+4,dyn_dh_fpu.temp.m2);
mem_writed(addr+8,dyn_dh_fpu.temp.m3);
}
}
static void FPU_FLDENV_DH(PhysPt addr){
if(!cpu.code.big) {
dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
dyn_dh_fpu.temp.m1 = dyn_dh_fpu.cw|0x3f;
dyn_dh_fpu.temp.m2 = (Bit32u)mem_readw(addr+2);
dyn_dh_fpu.temp.m3 = mem_readw(addr+4);
} else {
dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
dyn_dh_fpu.temp.m1 = mem_readd(addr)|0x3f;
dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
dyn_dh_fpu.temp.m3 = mem_readw(addr+8);
dyn_dh_fpu.temp.d1 = mem_readw(addr+10);
}
}
static void FPU_FSAVE_DH(PhysPt addr){
if (!cpu.code.big) {
mem_writew(addr,(Bit16u)dyn_dh_fpu.cw);
addr+=2;
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x04]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x05]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x08]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x09]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x0c]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x0d]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x10]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x11]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x14]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x15]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x18]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x19]);
for(Bitu i=28;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]);
} else {
mem_writew(addr,(Bit16u)dyn_dh_fpu.cw);
addr+=2;
for(Bitu i=2;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]);
}
}
static void FPU_FRSTOR_DH(PhysPt addr){
if (!cpu.code.big) {
dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
dyn_dh_fpu.temp_state[0x00] = mem_readb(addr++)|0x3f;
dyn_dh_fpu.temp_state[0x01] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x04] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x05] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x08] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x09] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x0c] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x0d] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x10] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x11] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x14] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x15] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x18] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x19] = mem_readb(addr++);
for(Bitu i=28;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++);
} else {
dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
for(Bitu i=0;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0]|=0x3f;
}
}
static void dh_fpu_esc0(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
cache_addb(0xd8);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
cache_addb(0xd8);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
}
}
static void dh_fpu_esc1(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
cache_addb(0xd9);
cache_addb(decode.modrm.val);
} else {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
dyn_fill_ea();
switch(group){
case 0x00: /* FLD float*/
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x01: /* UNKNOWN */
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FST float*/
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
break;
case 0x03: /* FSTP float*/
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
break;
case 0x04: /* FLDENV */
gen_call_function((void*)&FPU_FLDENV_DH,"%Ddr",DREG(EA));
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x05: /* FLDCW */
gen_call_function((void *)&FPU_FLDCW_DH,"%Ddr",DREG(EA));
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x06: /* FSTENV */
cache_addb(0xd9);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FSTENV_DH,"%Ddr",DREG(EA));
break;
case 0x07: /* FNSTCW*/
gen_call_function((void*)&FPU_FNSTCW_DH,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
break;
}
}
}
static void dh_fpu_esc2(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
cache_addb(0xda);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
cache_addb(0xda);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
}
}
static void dh_fpu_esc3(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
switch (group) {
case 0x04:
switch (sub) {
case 0x00: //FNENI
case 0x01: //FNDIS
LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub);
break;
case 0x02: //FNCLEX FCLEX
cache_addb(0xdb);
cache_addb(decode.modrm.val);
break;
case 0x03: //FNINIT FINIT
gen_call_function((void*)&FPU_FNINIT_DH,"");
cache_addb(0xdb);
cache_addb(decode.modrm.val);
break;
case 0x04: //FNSETPM
case 0x05: //FRSTPM
// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
break;
default:
E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub);
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub);
break;
}
} else {
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
dyn_fill_ea();
switch(group){
case 0x00: /* FILD */
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x01: /* FISTTP */
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FIST */
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
break;
case 0x03: /* FISTP */
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
break;
case 0x05: /* FLD 80 Bits Real */
gen_call_function((void*)&FPU_FLD_80,"%Ddr",DREG(EA));
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x07: /* FSTP 80 Bits Real */
cache_addb(0xdb);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_80,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
}
}
}
static void dh_fpu_esc4(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
cache_addb(0xdc);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
cache_addb(0xdc);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
}
}
static void dh_fpu_esc5(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
cache_addb(0xdd);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
switch(group){
case 0x00: /* FLD double real*/
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x01: /* FISTTP longint*/
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FST double real*/
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
break;
case 0x03: /* FSTP double real*/
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
break;
case 0x04: /* FRSTOR */
gen_call_function((void*)&FPU_FRSTOR_DH,"%Ddr",DREG(EA));
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0])));
break;
case 0x06: /* FSAVE */
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0])));
gen_call_function((void*)&FPU_FSAVE_DH,"%Ddr",DREG(EA));
cache_addb(0xdb);
cache_addb(0xe3);
break;
case 0x07: /* FNSTSW */
cache_addb(0xdd);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
}
}
}
static void dh_fpu_esc6(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
cache_addb(0xde);
cache_addb(decode.modrm.val);
} else {
dyn_fill_ea();
gen_call_function((void*)&FPU_FLD_16,"%Ddr",DREG(EA));
cache_addb(0xde);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
}
}
static void dh_fpu_esc7(){
dyn_get_modrm();
Bitu group=(decode.modrm.val >> 3) & 7;
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
switch (group){
case 0x01: /* FXCH STi*/
cache_addb(0xdf);
cache_addb(decode.modrm.val);
break;
case 0x02: /* FSTP STi*/
case 0x03: /* FSTP STi*/
cache_addb(0xdf);
cache_addb(decode.modrm.val);
break;
case 0x04:
switch(sub){
case 0x00: /* FNSTSW AX*/
cache_addb(0xdd);
cache_addb(0x05|(0x07<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_load_host(&(dyn_dh_fpu.temp.m1),DREG(TMPB),4);
gen_dop_word(DOP_MOV,false,DREG(EAX),DREG(TMPB));
gen_releasereg(DREG(TMPB));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
break;
}
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
break;
}
} else {
dyn_fill_ea();
switch(group){
case 0x00: /* FILD Bit16s */
gen_call_function((void*)&FPU_FLD_16,"%Ddr",DREG(EA));
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x01:
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
break;
case 0x02: /* FIST Bit16s */
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
break;
case 0x03: /* FISTP Bit16s */
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
break;
case 0x04: /* FBLD packed BCD */
gen_call_function((void*)&FPU_FLD_80,"%Ddr",DREG(EA));
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x05: /* FILD Bit64s */
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
break;
case 0x06: /* FBSTP packed BCD */
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_80,"%Ddr",DREG(EA));
break;
case 0x07: /* FISTP Bit64s */
cache_addb(0xdf);
cache_addb(0x05|(decode.modrm.reg<<3));
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
break;
}
}
}
#endif

View File

@ -1,69 +0,0 @@
static bool dyn_helper_divb(Bit8u val) {
if (!val) return CPU_PrepareException(0,0);
Bitu quo=reg_ax / val;
Bit8u rem=(Bit8u)(reg_ax % val);
Bit8u quo8=(Bit8u)(quo&0xff);
if (quo>0xff) return CPU_PrepareException(0,0);
reg_ah=rem;
reg_al=quo8;
return false;
}
static bool dyn_helper_idivb(Bit8s val) {
if (!val) return CPU_PrepareException(0,0);
Bits quo=(Bit16s)reg_ax / val;
Bit8s rem=(Bit8s)((Bit16s)reg_ax % val);
Bit8s quo8s=(Bit8s)(quo&0xff);
if (quo!=(Bit16s)quo8s) return CPU_PrepareException(0,0);
reg_ah=rem;
reg_al=quo8s;
return false;
}
static bool dyn_helper_divw(Bit16u val) {
if (!val) return CPU_PrepareException(0,0);
Bitu num=(reg_dx<<16)|reg_ax;
Bitu quo=num/val;
Bit16u rem=(Bit16u)(num % val);
Bit16u quo16=(Bit16u)(quo&0xffff);
if (quo!=(Bit32u)quo16) return CPU_PrepareException(0,0);
reg_dx=rem;
reg_ax=quo16;
return false;
}
static bool dyn_helper_idivw(Bit16s val) {
if (!val) return CPU_PrepareException(0,0);
Bits num=(reg_dx<<16)|reg_ax;
Bits quo=num/val;
Bit16s rem=(Bit16s)(num % val);
Bit16s quo16s=(Bit16s)quo;
if (quo!=(Bit32s)quo16s) return CPU_PrepareException(0,0);
reg_dx=rem;
reg_ax=quo16s;
return false;
}
static bool dyn_helper_divd(Bit32u val) {
if (!val) return CPU_PrepareException(0,0);
Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax;
Bit64u quo=num/val;
Bit32u rem=(Bit32u)(num % val);
Bit32u quo32=(Bit32u)(quo&0xffffffff);
if (quo!=(Bit64u)quo32) return CPU_PrepareException(0,0);
reg_edx=rem;
reg_eax=quo32;
return false;
}
static bool dyn_helper_idivd(Bit32s val) {
if (!val) return CPU_PrepareException(0,0);
Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax;
Bit64s quo=num/val;
Bit32s rem=(Bit32s)(num % val);
Bit32s quo32s=(Bit32s)(quo&0xffffffff);
if (quo!=(Bit64s)quo32s) return CPU_PrepareException(0,0);
reg_edx=rem;
reg_eax=quo32s;
return false;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,164 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
enum STRING_OP {
STR_OUTSB=0,STR_OUTSW,STR_OUTSD,
STR_INSB=4,STR_INSW,STR_INSD,
STR_MOVSB=8,STR_MOVSW,STR_MOVSD,
STR_LODSB=12,STR_LODSW,STR_LODSD,
STR_STOSB=16,STR_STOSW,STR_STOSD,
STR_SCASB=20,STR_SCASW,STR_SCASD,
STR_CMPSB=24,STR_CMPSW,STR_CMPSD
};
static void dyn_string(STRING_OP op) {
DynReg * si_base=decode.segprefix ? decode.segprefix : DREG(DS);
DynReg * di_base=DREG(ES);
DynReg * tmp_reg;bool usesi;bool usedi;
gen_protectflags();
if (decode.rep) {
gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles);
gen_releasereg(DREG(CYCLES));
decode.cycles=0;
}
/* Check what each string operation will be using */
switch (op) {
case STR_MOVSB: case STR_MOVSW: case STR_MOVSD:
case STR_CMPSB: case STR_CMPSW: case STR_CMPSD:
tmp_reg=DREG(TMPB);usesi=true;usedi=true;break;
case STR_LODSB: case STR_LODSW: case STR_LODSD:
tmp_reg=DREG(EAX);usesi=true;usedi=false;break;
case STR_OUTSB: case STR_OUTSW: case STR_OUTSD:
tmp_reg=DREG(TMPB);usesi=true;usedi=false;break;
case STR_SCASB: case STR_SCASW: case STR_SCASD:
case STR_STOSB: case STR_STOSW: case STR_STOSD:
tmp_reg=DREG(EAX);usesi=false;usedi=true;break;
case STR_INSB: case STR_INSW: case STR_INSD:
tmp_reg=DREG(TMPB);usesi=false;usedi=true;break;
default:
IllegalOption("dyn_string op");
}
gen_load_host(&cpu.direction,DREG(TMPW),4);
switch (op & 3) {
case 0:break;
case 1:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),1);break;
case 2:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),2);break;
default:
IllegalOption("dyn_string shift");
}
if (usesi) {
gen_preloadreg(DREG(ESI));
DynRegs[G_ESI].flags|=DYNFLG_CHANGED;
gen_preloadreg(si_base);
}
if (usedi) {
gen_preloadreg(DREG(EDI));
DynRegs[G_EDI].flags|=DYNFLG_CHANGED;
gen_preloadreg(di_base);
}
if (decode.rep) {
gen_preloadreg(DREG(ECX));
DynRegs[G_ECX].flags|=DYNFLG_CHANGED;
}
DynState rep_state;
dyn_savestate(&rep_state);
Bit8u * rep_start=cache.pos;
Bit8u * rep_ecx_jmp;
/* Check if ECX!=zero */
if (decode.rep) {
gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX));
rep_ecx_jmp=gen_create_branch_long(BR_Z);
}
if (usesi) {
if (!decode.big_addr) {
gen_extend_word(false,DREG(EA),DREG(ESI));
gen_lea(DREG(EA),si_base,DREG(EA),0,0);
} else {
gen_lea(DREG(EA),si_base,DREG(ESI),0,0);
}
switch (op&3) {
case 0:dyn_read_byte(DREG(EA),tmp_reg,false);break;
case 1:dyn_read_word(DREG(EA),tmp_reg,false);break;
case 2:dyn_read_word(DREG(EA),tmp_reg,true);break;
}
switch (op) {
case STR_OUTSB:
gen_call_function((void*)&IO_WriteB,"%Id%Dl",DREG(EDX),tmp_reg);break;
case STR_OUTSW:
gen_call_function((void*)&IO_WriteW,"%Id%Dw",DREG(EDX),tmp_reg);break;
case STR_OUTSD:
gen_call_function((void*)&IO_WriteD,"%Id%Dd",DREG(EDX),tmp_reg);break;
}
}
if (usedi) {
if (!decode.big_addr) {
gen_extend_word(false,DREG(EA),DREG(EDI));
gen_lea(DREG(EA),di_base,DREG(EA),0,0);
} else {
gen_lea(DREG(EA),di_base,DREG(EDI),0,0);
}
/* Maybe something special to be done to fill the value */
switch (op) {
case STR_INSB:
gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),tmp_reg);
case STR_MOVSB:
case STR_STOSB:
dyn_write_byte(DREG(EA),tmp_reg,false);
break;
case STR_INSW:
gen_call_function((void*)&IO_ReadW,"%Dw%Rw",DREG(EDX),tmp_reg);
case STR_MOVSW:
case STR_STOSW:
dyn_write_word(DREG(EA),tmp_reg,false);
break;
case STR_INSD:
gen_call_function((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),tmp_reg);
case STR_MOVSD:
case STR_STOSD:
dyn_write_word(DREG(EA),tmp_reg,true);
break;
default:
IllegalOption("dyn_string op");
}
}
gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB));
/* update registers */
if (usesi) gen_dop_word(DOP_ADD,decode.big_addr,DREG(ESI),DREG(TMPW));
if (usedi) gen_dop_word(DOP_ADD,decode.big_addr,DREG(EDI),DREG(TMPW));
if (decode.rep) {
gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX));
gen_sop_word(SOP_DEC,true,DREG(CYCLES));
gen_releasereg(DREG(CYCLES));
dyn_savestate(&save_info[used_save_info].state);
save_info[used_save_info].branch_pos=gen_create_branch_long(BR_LE);
save_info[used_save_info].eip_change=decode.op_start-decode.code_start;
save_info[used_save_info].type=normal;
used_save_info++;
/* Jump back to start of ECX check */
dyn_synchstate(&rep_state);
gen_create_jump(rep_start);
dyn_loadstate(&rep_state);
gen_fill_branch_long(rep_ecx_jmp);
}
gen_releasereg(DREG(TMPW));
}

View File

@ -1,327 +0,0 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: core_dynrec.cpp,v 1.11 2008/09/19 16:48:02 c2woody Exp $ */
#include "dosbox.h"
#if (C_DYNREC)
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#if defined (WIN32)
#include <windows.h>
#include <winbase.h>
#endif
#if (C_HAVE_MPROTECT)
#include <sys/mman.h>
#include <limits.h>
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
#endif /* C_HAVE_MPROTECT */
#include "callback.h"
#include "regs.h"
#include "mem.h"
#include "cpu.h"
#include "debug.h"
#include "paging.h"
#include "inout.h"
#include "lazyflags.h"
#define CACHE_MAXSIZE (4096*2)
#define CACHE_TOTAL (1024*1024*8)
#define CACHE_PAGES (512)
#define CACHE_BLOCKS (128*1024)
#define CACHE_ALIGN (16)
#define DYN_HASH_SHIFT (4)
#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT)
#define DYN_LINKS (16)
#if 0
#define DYN_LOG LOG_MSG
#else
#define DYN_LOG
#endif
#if C_FPU
#define CPU_FPU 1 //Enable FPU escape instructions
#endif
// the emulated x86 registers
#define DRC_REG_EAX 0
#define DRC_REG_ECX 1
#define DRC_REG_EDX 2
#define DRC_REG_EBX 3
#define DRC_REG_ESP 4
#define DRC_REG_EBP 5
#define DRC_REG_ESI 6
#define DRC_REG_EDI 7
// the emulated x86 segment registers
#define DRC_SEG_ES 0
#define DRC_SEG_CS 1
#define DRC_SEG_SS 2
#define DRC_SEG_DS 3
#define DRC_SEG_FS 4
#define DRC_SEG_GS 5
// access to a general register
#define DRCD_REG_VAL(reg) (&cpu_regs.regs[reg].dword)
// access to a segment register
#define DRCD_SEG_VAL(seg) (&Segs.val[seg])
// access to the physical value of a segment register/selector
#define DRCD_SEG_PHYS(seg) (&Segs.phys[seg])
// access to an 8bit general register
#define DRCD_REG_BYTE(reg,idx) (&cpu_regs.regs[reg].byte[idx])
// access to 16/32bit general registers
#define DRCD_REG_WORD(reg,dwrd) ((dwrd)?((void*)(&cpu_regs.regs[reg].dword)):((void*)(&cpu_regs.regs[reg].word)))
enum BlockReturn {
BR_Normal=0,
BR_Cycles,
BR_Link1,BR_Link2,
BR_Opcode,
#if (C_DEBUG)
BR_OpcodeFull,
#endif
BR_Iret,
BR_CallBack,
BR_SMCBlock
};
// identificator to signal self-modification of the currently executed block
#define SMC_CURRENT_BLOCK 0xffff
static void IllegalOptionDynrec(const char* msg) {
E_Exit("DynrecCore: illegal option in %s",msg);
}
static struct {
BlockReturn (*runcode)(Bit8u*); // points to code that can start a block
Bitu callback; // the occurred callback
Bitu readdata; // spare space used when reading from memory
Bit32u protected_regs[8]; // space to save/restore register values
} core_dynrec;
#include "core_dynrec/cache.h"
#define X86 0x01
#define X86_64 0x02
#define MIPSEL 0x03
#define ARMV4LE 0x04
#if C_TARGETCPU == X86_64
#include "core_dynrec/risc_x64.h"
#elif C_TARGETCPU == X86
#include "core_dynrec/risc_x86.h"
#elif C_TARGETCPU == MIPSEL
#include "core_dynrec/risc_mipsel32.h"
#elif C_TARGETCPU == ARMV4LE
#include "core_dynrec/risc_armv4le.h"
#endif
#include "core_dynrec/decoder.h"
CacheBlockDynRec * LinkBlocks(BlockReturn ret) {
CacheBlockDynRec * block=NULL;
// the last instruction was a control flow modifying instruction
Bitu temp_ip=SegPhys(cs)+reg_eip;
CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_readhandler(temp_ip);
if (temp_handler->flags & PFLAG_HASCODE) {
// see if the target is an already translated block
block=temp_handler->FindCacheBlock(temp_ip & 4095);
if (!block) return NULL;
// found it, link the current block to
cache.block.running->LinkTo(ret==BR_Link2,block);
return block;
}
return NULL;
}
/*
The core tries to find the block that should be executed next.
If such a block is found, it is run, otherwise the instruction
stream starting at ip_point is translated (see decoder.h) and
makes up a new code block that will be run.
When control is returned to CPU_Core_Dynrec_Run (which might
be right after the block is run, or somewhen long after that
due to the direct cacheblock linking) the returncode decides
the next action. This might be continuing the translation and
execution process, or returning from the core etc.
*/
Bits CPU_Core_Dynrec_Run(void) {
for (;;) {
// Determine the linear address of CS:EIP
PhysPt ip_point=SegPhys(cs)+reg_eip;
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
CodePageHandlerDynRec * chandler=0;
// see if the current page is present and contains code
if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) {
// page not present, throw the exception
CPU_Exception(cpu.exception.which,cpu.exception.error);
continue;
}
// page doesn't contain code or is special
if (GCC_UNLIKELY(!chandler)) return CPU_Core_Normal_Run();
// find correct Dynamic Block to run
CacheBlockDynRec * block=chandler->FindCacheBlock(ip_point&4095);
if (!block) {
// no block found, thus translate the instruction stream
// unless the instruction is known to be modified
if (!chandler->invalidation_map || (chandler->invalidation_map[ip_point&4095]<4)) {
// translate up to 32 instructions
block=CreateCacheBlock(chandler,ip_point,32);
} else {
// let the normal core handle this instruction to avoid zero-sized blocks
Bitu old_cycles=CPU_Cycles;
CPU_Cycles=1;
Bits nc_retcode=CPU_Core_Normal_Run();
if (!nc_retcode) {
CPU_Cycles=old_cycles-1;
continue;
}
CPU_CycleLeft+=old_cycles;
return nc_retcode;
}
}
run_block:
cache.block.running=0;
// now we're ready to run the dynamic code block
// BlockReturn ret=((BlockReturn (*)(void))(block->cache.start))();
BlockReturn ret=core_dynrec.runcode(block->cache.start);
switch (ret) {
case BR_Iret:
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
if (!GETFLAG(TF)) break;
// trapflag is set, switch to the trap-aware decoder
cpudecoder=CPU_Core_Dynrec_Trap_Run;
return CBRET_NONE;
case BR_Normal:
// the block was exited due to a non-predictable control flow
// modifying instruction (like ret) or some nontrivial cpu state
// changing instruction (for example switch to/from pmode),
// or the maximal number of instructions to translate was reached
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
break;
case BR_Cycles:
// cycles went negative, return from the core to handle
// external events, schedule the pic...
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
return CBRET_NONE;
case BR_CallBack:
// the callback code is executed in dosbox.conf, return the callback number
FillFlags();
return core_dynrec.callback;
case BR_SMCBlock:
// LOG_MSG("selfmodification of running block at %x:%x",SegValue(cs),reg_eip);
cpu.exception.which=0;
// fallthrough, let the normal core handle the block-modifying instruction
case BR_Opcode:
// some instruction has been encountered that could not be translated
// (thus it is not part of the code block), the normal core will
// handle this instruction
CPU_CycleLeft+=CPU_Cycles;
CPU_Cycles=1;
return CPU_Core_Normal_Run();
#if (C_DEBUG)
case BR_OpcodeFull:
CPU_CycleLeft+=CPU_Cycles;
CPU_Cycles=1;
return CPU_Core_Full_Run();
#endif
case BR_Link1:
case BR_Link2:
block=LinkBlocks(ret);
if (block) goto run_block;
break;
default:
E_Exit("Invalid return code %d", ret);
}
}
return CBRET_NONE;
}
Bits CPU_Core_Dynrec_Trap_Run(void) {
Bits oldCycles = CPU_Cycles;
CPU_Cycles = 1;
cpu.trap_skip = false;
// let the normal core execute the next (only one!) instruction
Bits ret=CPU_Core_Normal_Run();
// trap to int1 unless the last instruction deferred this
// (allows hardware interrupts to be served without interaction)
if (!cpu.trap_skip) CPU_HW_Interrupt(1);
CPU_Cycles = oldCycles-1;
// continue (either the trapflag was clear anyways, or the int1 cleared it)
cpudecoder = &CPU_Core_Dynrec_Run;
return ret;
}
void CPU_Core_Dynrec_Init(void) {
}
void CPU_Core_Dynrec_Cache_Init(bool enable_cache) {
// Initialize code cache and dynamic blocks
cache_init(enable_cache);
}
void CPU_Core_Dynrec_Cache_Close(void) {
cache_close();
}
#endif

View File

@ -1,5 +0,0 @@
noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \
dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h \
risc_armv4le.h risc_armv4le-common.h \
risc_armv4le-s3.h risc_armv4le-o3.h risc_armv4le-thumb.h \
risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h

View File

@ -1,665 +0,0 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
class CodePageHandlerDynRec; // forward
// basic cache block representation
class CacheBlockDynRec {
public:
void Clear(void);
// link this cache block to another block, index specifies the code
// path (always zero for unconditional links, 0/1 for conditional ones
void LinkTo(Bitu index,CacheBlockDynRec * toblock) {
assert(toblock);
link[index].to=toblock;
link[index].next=toblock->link[index].from; // set target block
toblock->link[index].from=this; // remember who links me
}
struct {
Bit16u start,end; // where in the page is the original code
CodePageHandlerDynRec * handler; // page containing this code
} page;
struct {
Bit8u * start; // where in the cache are we
Bitu size;
CacheBlockDynRec * next;
// writemap masking maskpointer/start/length
// to allow holes in the writemap
Bit8u * wmapmask;
Bit16u maskstart;
Bit16u masklen;
} cache;
struct {
Bitu index;
CacheBlockDynRec * next;
} hash;
struct {
CacheBlockDynRec * to; // this block can transfer control to the to-block
CacheBlockDynRec * next;
CacheBlockDynRec * from; // the from-block can transfer control to this block
} link[2]; // maximal two links (conditional jumps)
CacheBlockDynRec * crossblock;
};
static struct {
struct {
CacheBlockDynRec * first; // the first cache block in the list
CacheBlockDynRec * active; // the current cache block
CacheBlockDynRec * free; // pointer to the free list
CacheBlockDynRec * running; // the last block that was entered for execution
} block;
Bit8u * pos; // position in the cache block
CodePageHandlerDynRec * free_pages; // pointer to the free list
CodePageHandlerDynRec * used_pages; // pointer to the list of used pages
CodePageHandlerDynRec * last_page; // the last used page
} cache;
// cache memory pointers, to be malloc'd later
static Bit8u * cache_code_start_ptr=NULL;
static Bit8u * cache_code=NULL;
static Bit8u * cache_code_link_blocks=NULL;
static CacheBlockDynRec * cache_blocks=NULL;
static CacheBlockDynRec link_blocks[2]; // default linking (specially marked)
// the CodePageHandlerDynRec class provides access to the contained
// cache blocks and intercepts writes to the code for special treatment
class CodePageHandlerDynRec : public PageHandler {
public:
CodePageHandlerDynRec() {
invalidation_map=NULL;
}
void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) {
// initialize this codepage handler
phys_page=_phys_page;
// save the old pagehandler to provide direct read access to the memory,
// and to be able to restore it later on
old_pagehandler=_old_pagehandler;
// adjust flags
flags=old_pagehandler->flags|PFLAG_HASCODE;
flags&=~PFLAG_WRITEABLE;
active_blocks=0;
active_count=16;
// initialize the maps with zero (no cache blocks as well as code present)
memset(&hash_map,0,sizeof(hash_map));
memset(&write_map,0,sizeof(write_map));
if (invalidation_map!=NULL) {
free(invalidation_map);
invalidation_map=NULL;
}
}
// clear out blocks that contain code which has been modified
bool InvalidateRange(Bitu start,Bitu end) {
Bits index=1+(end>>DYN_HASH_SHIFT);
bool is_current_block=false; // if the current block is modified, it has to be exited as soon as possible
Bit32u ip_point=SegPhys(cs)+reg_eip;
ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff);
while (index>=0) {
Bitu map=0;
// see if there is still some code in the range
for (Bitu count=start;count<=end;count++) map+=write_map[count];
if (!map) return is_current_block; // no more code, finished
CacheBlockDynRec * block=hash_map[index];
while (block) {
CacheBlockDynRec * nextblock=block->hash.next;
// test if this block is in the range
if (start<=block->page.end && end>=block->page.start) {
if (ip_point<=block->page.end && ip_point>=block->page.start) is_current_block=true;
block->Clear(); // clear the block, decrements the write_map accordingly
}
block=nextblock;
}
index--;
}
return is_current_block;
}
// the following functions will clean all cache blocks that are invalid now due to the write
void writeb(PhysPt addr,Bitu val){
addr&=4095;
if (host_readb(hostmem+addr)==(Bit8u)val) return;
host_writeb(hostmem+addr,val);
// see if there's code where we are writing to
if (!host_readb(&write_map[addr])) {
if (active_blocks) return; // still some blocks in this page
active_count--;
if (!active_count) Release(); // delay page releasing until active_count is zero
return;
} else if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
invalidation_map[addr]++;
InvalidateRange(addr,addr);
}
void writew(PhysPt addr,Bitu val){
addr&=4095;
if (host_readw(hostmem+addr)==(Bit16u)val) return;
host_writew(hostmem+addr,val);
// see if there's code where we are writing to
if (!host_readw(&write_map[addr])) {
if (active_blocks) return; // still some blocks in this page
active_count--;
if (!active_count) Release(); // delay page releasing until active_count is zero
return;
} else if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
host_writew(&invalidation_map[addr],
host_readw(&invalidation_map[addr])+0x101);
#else
(*(Bit16u*)&invalidation_map[addr])+=0x101;
#endif
InvalidateRange(addr,addr+1);
}
void writed(PhysPt addr,Bitu val){
addr&=4095;
if (host_readd(hostmem+addr)==(Bit32u)val) return;
host_writed(hostmem+addr,val);
// see if there's code where we are writing to
if (!host_readd(&write_map[addr])) {
if (active_blocks) return; // still some blocks in this page
active_count--;
if (!active_count) Release(); // delay page releasing until active_count is zero
return;
} else if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
host_writed(&invalidation_map[addr],
host_readd(&invalidation_map[addr])+0x1010101);
#else
(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
#endif
InvalidateRange(addr,addr+3);
}
bool writeb_checked(PhysPt addr,Bitu val) {
addr&=4095;
if (host_readb(hostmem+addr)==(Bit8u)val) return false;
// see if there's code where we are writing to
if (!host_readb(&write_map[addr])) {
if (!active_blocks) {
// no blocks left in this page, still delay the page releasing a bit
active_count--;
if (!active_count) Release();
}
} else {
if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
invalidation_map[addr]++;
if (InvalidateRange(addr,addr)) {
cpu.exception.which=SMC_CURRENT_BLOCK;
return true;
}
}
host_writeb(hostmem+addr,val);
return false;
}
bool writew_checked(PhysPt addr,Bitu val) {
addr&=4095;
if (host_readw(hostmem+addr)==(Bit16u)val) return false;
// see if there's code where we are writing to
if (!host_readw(&write_map[addr])) {
if (!active_blocks) {
// no blocks left in this page, still delay the page releasing a bit
active_count--;
if (!active_count) Release();
}
} else {
if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
host_writew(&invalidation_map[addr],
host_readw(&invalidation_map[addr])+0x101);
#else
(*(Bit16u*)&invalidation_map[addr])+=0x101;
#endif
if (InvalidateRange(addr,addr+1)) {
cpu.exception.which=SMC_CURRENT_BLOCK;
return true;
}
}
host_writew(hostmem+addr,val);
return false;
}
bool writed_checked(PhysPt addr,Bitu val) {
addr&=4095;
if (host_readd(hostmem+addr)==(Bit32u)val) return false;
// see if there's code where we are writing to
if (!host_readd(&write_map[addr])) {
if (!active_blocks) {
// no blocks left in this page, still delay the page releasing a bit
active_count--;
if (!active_count) Release();
}
} else {
if (!invalidation_map) {
invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096);
}
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
host_writed(&invalidation_map[addr],
host_readd(&invalidation_map[addr])+0x1010101);
#else
(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
#endif
if (InvalidateRange(addr,addr+3)) {
cpu.exception.which=SMC_CURRENT_BLOCK;
return true;
}
}
host_writed(hostmem+addr,val);
return false;
}
// add a cache block to this page and note it in the hash map
void AddCacheBlock(CacheBlockDynRec * block) {
Bitu index=1+(block->page.start>>DYN_HASH_SHIFT);
block->hash.next=hash_map[index]; // link to old block at index from the new block
block->hash.index=index;
hash_map[index]=block; // put new block at hash position
block->page.handler=this;
active_blocks++;
}
// there's a block whose code started in a different page
void AddCrossBlock(CacheBlockDynRec * block) {
block->hash.next=hash_map[0];
block->hash.index=0;
hash_map[0]=block;
block->page.handler=this;
active_blocks++;
}
// remove a cache block
void DelCacheBlock(CacheBlockDynRec * block) {
active_blocks--;
active_count=16;
CacheBlockDynRec * * bwhere=&hash_map[block->hash.index];
while (*bwhere!=block) {
bwhere=&((*bwhere)->hash.next);
//Will crash if a block isn't found, which should never happen.
}
*bwhere=block->hash.next;
// remove the cleared block from the write map
if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) {
// first part is not influenced by the mask
for (Bitu i=block->page.start;i<block->cache.maskstart;i++) {
if (write_map[i]) write_map[i]--;
}
Bitu maskct=0;
// last part sticks to the writemap mask
for (Bitu i=block->cache.maskstart;i<=block->page.end;i++,maskct++) {
if (write_map[i]) {
// only adjust writemap if it isn't masked
if ((maskct>=block->cache.masklen) || (!block->cache.wmapmask[maskct])) write_map[i]--;
}
}
free(block->cache.wmapmask);
block->cache.wmapmask=NULL;
} else {
for (Bitu i=block->page.start;i<=block->page.end;i++) {
if (write_map[i]) write_map[i]--;
}
}
}
void Release(void) {
MEM_SetPageHandler(phys_page,1,old_pagehandler); // revert to old handler
PAGING_ClearTLB();
// remove page from the lists
if (prev) prev->next=next;
else cache.used_pages=next;
if (next) next->prev=prev;
else cache.last_page=prev;
next=cache.free_pages;
cache.free_pages=this;
prev=0;
}
void ClearRelease(void) {
// clear out all cache blocks in this page
for (Bitu index=0;index<(1+DYN_PAGE_HASH);index++) {
CacheBlockDynRec * block=hash_map[index];
while (block) {
CacheBlockDynRec * nextblock=block->hash.next;
block->page.handler=0; // no need, full clear
block->Clear();
block=nextblock;
}
}
Release(); // now can release this page
}
CacheBlockDynRec * FindCacheBlock(Bitu start) {
CacheBlockDynRec * block=hash_map[1+(start>>DYN_HASH_SHIFT)];
// see if there's a cache block present at the start address
while (block) {
if (block->page.start==start) return block; // found
block=block->hash.next;
}
return 0; // none found
}
HostPt GetHostReadPt(Bitu phys_page) {
hostmem=old_pagehandler->GetHostReadPt(phys_page);
return hostmem;
}
HostPt GetHostWritePt(Bitu phys_page) {
return GetHostReadPt( phys_page );
}
public:
// the write map, there are write_map[i] cache blocks that cover the byte at address i
Bit8u write_map[4096];
Bit8u * invalidation_map;
CodePageHandlerDynRec * next, * prev; // page linking
private:
PageHandler * old_pagehandler;
// hash map to quickly find the cache blocks in this page
CacheBlockDynRec * hash_map[1+DYN_PAGE_HASH];
Bitu active_blocks; // the number of cache blocks in this page
Bitu active_count; // delaying parameter to not immediately release a page
HostPt hostmem;
Bitu phys_page;
};
static INLINE void cache_addunusedblock(CacheBlockDynRec * block) {
// block has become unused, add it to the freelist
block->cache.next=cache.block.free;
cache.block.free=block;
}
static CacheBlockDynRec * cache_getblock(void) {
// get a free cache block and advance the free pointer
CacheBlockDynRec * ret=cache.block.free;
if (!ret) E_Exit("Ran out of CacheBlocks" );
cache.block.free=ret->cache.next;
ret->cache.next=0;
return ret;
}
void CacheBlockDynRec::Clear(void) {
Bitu ind;
// check if this is not a cross page block
if (hash.index) for (ind=0;ind<2;ind++) {
CacheBlockDynRec * fromlink=link[ind].from;
link[ind].from=0;
while (fromlink) {
CacheBlockDynRec * nextlink=fromlink->link[ind].next;
// clear the next-link and let the block point to the standard linkcode
fromlink->link[ind].next=0;
fromlink->link[ind].to=&link_blocks[ind];
fromlink=nextlink;
}
if (link[ind].to!=&link_blocks[ind]) {
// not linked to the standard linkcode, find the block that links to this block
CacheBlockDynRec * * wherelink=&link[ind].to->link[ind].from;
while (*wherelink != this && *wherelink) {
wherelink = &(*wherelink)->link[ind].next;
}
// now remove the link
if(*wherelink)
*wherelink = (*wherelink)->link[ind].next;
else {
LOG(LOG_CPU,LOG_ERROR)("Cache anomaly. please investigate");
}
}
} else
cache_addunusedblock(this);
if (crossblock) {
// clear out the crossblock (in the page before) as well
crossblock->crossblock=0;
crossblock->Clear();
crossblock=0;
}
if (page.handler) {
// clear out the code page handler
page.handler->DelCacheBlock(this);
page.handler=0;
}
if (cache.wmapmask){
free(cache.wmapmask);
cache.wmapmask=NULL;
}
}
static CacheBlockDynRec * cache_openblock(void) {
CacheBlockDynRec * block=cache.block.active;
// check for enough space in this block
Bitu size=block->cache.size;
CacheBlockDynRec * nextblock=block->cache.next;
if (block->page.handler)
block->Clear();
// block size must be at least CACHE_MAXSIZE
while (size<CACHE_MAXSIZE) {
if (!nextblock)
goto skipresize;
// merge blocks
size+=nextblock->cache.size;
CacheBlockDynRec * tempblock=nextblock->cache.next;
if (nextblock->page.handler)
nextblock->Clear();
// block is free now
cache_addunusedblock(nextblock);
nextblock=tempblock;
}
skipresize:
// adjust parameters and open this block
block->cache.size=size;
block->cache.next=nextblock;
cache.pos=block->cache.start;
return block;
}
static void cache_closeblock(void) {
CacheBlockDynRec * block=cache.block.active;
// links point to the default linking code
block->link[0].to=&link_blocks[0];
block->link[1].to=&link_blocks[1];
block->link[0].from=0;
block->link[1].from=0;
block->link[0].next=0;
block->link[1].next=0;
// close the block with correct alignment
Bitu written=(Bitu)(cache.pos-block->cache.start);
if (written>block->cache.size) {
if (!block->cache.next) {
if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun 1 %d",written-block->cache.size);
} else E_Exit("CacheBlock overrun 2 written %d size %d",written,block->cache.size);
} else {
Bitu new_size;
Bitu left=block->cache.size-written;
// smaller than cache align then don't bother to resize
if (left>CACHE_ALIGN) {
new_size=((written-1)|(CACHE_ALIGN-1))+1;
CacheBlockDynRec * newblock=cache_getblock();
// align block now to CACHE_ALIGN
newblock->cache.start=block->cache.start+new_size;
newblock->cache.size=block->cache.size-new_size;
newblock->cache.next=block->cache.next;
block->cache.next=newblock;
block->cache.size=new_size;
}
}
// advance the active block pointer
if (!block->cache.next || (block->cache.next->cache.start>(cache_code_start_ptr + CACHE_TOTAL - CACHE_MAXSIZE))) {
// LOG_MSG("Cache full restarting");
cache.block.active=cache.block.first;
} else {
cache.block.active=block->cache.next;
}
}
// place an 8bit value into the cache
static INLINE void cache_addb(Bit8u val) {
*cache.pos++=val;
}
// place a 16bit value into the cache
static INLINE void cache_addw(Bit16u val) {
*(Bit16u*)cache.pos=val;
cache.pos+=2;
}
// place a 32bit value into the cache
static INLINE void cache_addd(Bit32u val) {
*(Bit32u*)cache.pos=val;
cache.pos+=4;
}
// place a 64bit value into the cache
static INLINE void cache_addq(Bit64u val) {
*(Bit64u*)cache.pos=val;
cache.pos+=8;
}
static void dyn_return(BlockReturn retcode,bool ret_exception);
static void dyn_run_code(void);
/* Define temporary pagesize so the MPROTECT case and the regular case share as much code as possible */
#if (C_HAVE_MPROTECT)
#define PAGESIZE_TEMP PAGESIZE
#else
#define PAGESIZE_TEMP 4096
#endif
static bool cache_initialized = false;
static void cache_init(bool enable) {
Bits i;
if (enable) {
// see if cache is already initialized
if (cache_initialized) return;
cache_initialized = true;
if (cache_blocks == NULL) {
// allocate the cache blocks memory
cache_blocks=(CacheBlockDynRec*)malloc(CACHE_BLOCKS*sizeof(CacheBlockDynRec));
if(!cache_blocks) E_Exit("Allocating cache_blocks has failed");
memset(cache_blocks,0,sizeof(CacheBlockDynRec)*CACHE_BLOCKS);
cache.block.free=&cache_blocks[0];
// initialize the cache blocks
for (i=0;i<CACHE_BLOCKS-1;i++) {
cache_blocks[i].link[0].to=(CacheBlockDynRec *)1;
cache_blocks[i].link[1].to=(CacheBlockDynRec *)1;
cache_blocks[i].cache.next=&cache_blocks[i+1];
}
}
if (cache_code_start_ptr==NULL) {
// allocate the code cache memory
#if defined (WIN32)
cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if (!cache_code_start_ptr)
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#else
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#endif
if(!cache_code_start_ptr) E_Exit("Allocating dynamic cache failed");
// align the cache at a page boundary
cache_code=(Bit8u*)(((long)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //MEM LEAK. store old pointer if you want to free it.
cache_code_link_blocks=cache_code;
cache_code=cache_code+PAGESIZE_TEMP;
#if (C_HAVE_MPROTECT)
if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
LOG_MSG("Setting excute permission on the code cache has failed");
#endif
CacheBlockDynRec * block=cache_getblock();
cache.block.first=block;
cache.block.active=block;
block->cache.start=&cache_code[0];
block->cache.size=CACHE_TOTAL;
block->cache.next=0; // last block in the list
}
// setup the default blocks for block linkage returns
cache.pos=&cache_code_link_blocks[0];
link_blocks[0].cache.start=cache.pos;
// link code that returns with a special return code
dyn_return(BR_Link1,false);
cache.pos=&cache_code_link_blocks[32];
link_blocks[1].cache.start=cache.pos;
// link code that returns with a special return code
dyn_return(BR_Link2,false);
cache.pos=&cache_code_link_blocks[64];
core_dynrec.runcode=(BlockReturn (*)(Bit8u*))cache.pos;
// link_blocks[1].cache.start=cache.pos;
dyn_run_code();
cache.free_pages=0;
cache.last_page=0;
cache.used_pages=0;
// setup the code pages
for (i=0;i<CACHE_PAGES;i++) {
CodePageHandlerDynRec * newpage=new CodePageHandlerDynRec();
newpage->next=cache.free_pages;
cache.free_pages=newpage;
}
}
}
static void cache_close(void) {
/* for (;;) {
if (cache.used_pages) {
CodePageHandler * cpage=cache.used_pages;
CodePageHandler * npage=cache.used_pages->next;
cpage->ClearRelease();
delete cpage;
cache.used_pages=npage;
} else break;
}
if (cache_blocks != NULL) {
free(cache_blocks);
cache_blocks = NULL;
}
if (cache_code_start_ptr != NULL) {
### care: under windows VirtualFree() has to be used if
### VirtualAlloc was used for memory allocation
free(cache_code_start_ptr);
cache_code_start_ptr = NULL;
}
cache_code = NULL;
cache_code_link_blocks = NULL;
cache_initialized = false; */
}

View File

@ -1,599 +0,0 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: decoder.h,v 1.5 2008/09/19 16:48:02 c2woody Exp $ */
#include "decoder_basic.h"
#include "operators.h"
#include "decoder_opcodes.h"
#include "dyn_fpu.h"
/*
The function CreateCacheBlock translates the instruction stream
until either an unhandled instruction is found, the maximal
number of translated instructions is reached or some critical
instruction is encountered.
*/
static CacheBlockDynRec * CreateCacheBlock(CodePageHandlerDynRec * codepage,PhysPt start,Bitu max_opcodes) {
// initialize a load of variables
decode.code_start=start;
decode.code=start;
decode.page.code=codepage;
decode.page.index=start&4095;
decode.page.wmap=codepage->write_map;
decode.page.invmap=codepage->invalidation_map;
decode.page.first=start >> 12;
decode.active_block=decode.block=cache_openblock();
decode.block->page.start=(Bit16u)decode.page.index;
codepage->AddCacheBlock(decode.block);
InitFlagsOptimization();
// every codeblock that is run sets cache.block.running to itself
// so the block linking knows the last executed block
gen_mov_direct_ptr(&cache.block.running,(DRC_PTR_SIZE_IM)decode.block);
// start with the cycles check
gen_mov_word_to_reg(FC_RETOP,&CPU_Cycles,true);
save_info_dynrec[used_save_info_dynrec].branch_pos=gen_create_branch_long_leqzero(FC_RETOP);
save_info_dynrec[used_save_info_dynrec].type=cycle_check;
used_save_info_dynrec++;
decode.cycles=0;
while (max_opcodes--) {
// Init prefixes
decode.big_addr=cpu.code.big;
decode.big_op=cpu.code.big;
decode.seg_prefix=0;
decode.seg_prefix_used=false;
decode.rep=REP_NONE;
decode.cycles++;
decode.op_start=decode.code;
restart_prefix:
Bitu opcode;
if (!decode.page.invmap) opcode=decode_fetchb();
else {
// some entries in the invalidation map, see if the next
// instruction is known to be modified a lot
if (decode.page.index<4096) {
if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode;
opcode=decode_fetchb();
} else {
// switch to the next page
opcode=decode_fetchb();
if (GCC_UNLIKELY(decode.page.invmap &&
(decode.page.invmap[decode.page.index-1]>=4))) goto illegalopcode;
}
}
switch (opcode) {
// instructions 'op reg8,reg8' and 'op [],reg8'
case 0x00:dyn_dop_ebgb(DOP_ADD);break;
case 0x08:dyn_dop_ebgb(DOP_OR);break;
case 0x10:dyn_dop_ebgb(DOP_ADC);break;
case 0x18:dyn_dop_ebgb(DOP_SBB);break;
case 0x20:dyn_dop_ebgb(DOP_AND);break;
case 0x28:dyn_dop_ebgb(DOP_SUB);break;
case 0x30:dyn_dop_ebgb(DOP_XOR);break;
case 0x38:dyn_dop_ebgb(DOP_CMP);break;
// instructions 'op reg8,reg8' and 'op reg8,[]'
case 0x02:dyn_dop_gbeb(DOP_ADD);break;
case 0x0a:dyn_dop_gbeb(DOP_OR);break;
case 0x12:dyn_dop_gbeb(DOP_ADC);break;
case 0x1a:dyn_dop_gbeb(DOP_SBB);break;
case 0x22:dyn_dop_gbeb(DOP_AND);break;
case 0x2a:dyn_dop_gbeb(DOP_SUB);break;
case 0x32:dyn_dop_gbeb(DOP_XOR);break;
case 0x3a:dyn_dop_gbeb(DOP_CMP);break;
// instructions 'op reg16/32,reg16/32' and 'op [],reg16/32'
case 0x01:dyn_dop_evgv(DOP_ADD);break;
case 0x09:dyn_dop_evgv(DOP_OR);break;
case 0x11:dyn_dop_evgv(DOP_ADC);break;
case 0x19:dyn_dop_evgv(DOP_SBB);break;
case 0x21:dyn_dop_evgv(DOP_AND);break;
case 0x29:dyn_dop_evgv(DOP_SUB);break;
case 0x31:dyn_dop_evgv(DOP_XOR);break;
case 0x39:dyn_dop_evgv(DOP_CMP);break;
// instructions 'op reg16/32,reg16/32' and 'op reg16/32,[]'
case 0x03:dyn_dop_gvev(DOP_ADD);break;
case 0x0b:dyn_dop_gvev(DOP_OR);break;
case 0x13:dyn_dop_gvev(DOP_ADC);break;
case 0x1b:dyn_dop_gvev(DOP_SBB);break;
case 0x23:dyn_dop_gvev(DOP_AND);break;
case 0x2b:dyn_dop_gvev(DOP_SUB);break;
case 0x33:dyn_dop_gvev(DOP_XOR);break;
case 0x3b:dyn_dop_gvev(DOP_CMP);break;
// instructions 'op reg8,imm8'
case 0x04:dyn_dop_byte_imm(DOP_ADD,DRC_REG_EAX,0);break;
case 0x0c:dyn_dop_byte_imm(DOP_OR,DRC_REG_EAX,0);break;
case 0x14:dyn_dop_byte_imm(DOP_ADC,DRC_REG_EAX,0);break;
case 0x1c:dyn_dop_byte_imm(DOP_SBB,DRC_REG_EAX,0);break;
case 0x24:dyn_dop_byte_imm(DOP_AND,DRC_REG_EAX,0);break;
case 0x2c:dyn_dop_byte_imm(DOP_SUB,DRC_REG_EAX,0);break;
case 0x34:dyn_dop_byte_imm(DOP_XOR,DRC_REG_EAX,0);break;
case 0x3c:dyn_dop_byte_imm(DOP_CMP,DRC_REG_EAX,0);break;
// instructions 'op reg16/32,imm16/32'
case 0x05:dyn_dop_word_imm(DOP_ADD,DRC_REG_EAX);break;
case 0x0d:dyn_dop_word_imm_old(DOP_OR,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
case 0x15:dyn_dop_word_imm_old(DOP_ADC,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
case 0x1d:dyn_dop_word_imm_old(DOP_SBB,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
case 0x25:dyn_dop_word_imm(DOP_AND,DRC_REG_EAX);break;
case 0x2d:dyn_dop_word_imm_old(DOP_SUB,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
case 0x35:dyn_dop_word_imm_old(DOP_XOR,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
case 0x3d:dyn_dop_word_imm_old(DOP_CMP,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
// push segment register onto stack
case 0x06:dyn_push_seg(DRC_SEG_ES);break;
case 0x0e:dyn_push_seg(DRC_SEG_CS);break;
case 0x16:dyn_push_seg(DRC_SEG_SS);break;
case 0x1e:dyn_push_seg(DRC_SEG_DS);break;
// pop segment register from stack
case 0x07:dyn_pop_seg(DRC_SEG_ES);break;
case 0x17:dyn_pop_seg(DRC_SEG_SS);break;
case 0x1f:dyn_pop_seg(DRC_SEG_DS);break;
// segment prefixes
case 0x26:dyn_segprefix(DRC_SEG_ES);goto restart_prefix;
case 0x2e:dyn_segprefix(DRC_SEG_CS);goto restart_prefix;
case 0x36:dyn_segprefix(DRC_SEG_SS);goto restart_prefix;
case 0x3e:dyn_segprefix(DRC_SEG_DS);goto restart_prefix;
case 0x64:dyn_segprefix(DRC_SEG_FS);goto restart_prefix;
case 0x65:dyn_segprefix(DRC_SEG_GS);goto restart_prefix;
// case 0x27: DAA missing
// case 0x2f: DAS missing
// case 0x37: AAA missing
// case 0x3f: AAS missing
// dual opcodes
case 0x0f:
{
Bitu dual_code=decode_fetchb();
switch (dual_code) {
case 0x00:
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
dyn_grp6();
break;
case 0x01:
if (dyn_grp7()) goto finish_block;
break;
/* case 0x02:
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
dyn_larlsl(true);
break;
case 0x03:
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
dyn_larlsl(false);
break; */
case 0x20:dyn_mov_from_crx();break;
case 0x22:dyn_mov_to_crx();goto finish_block;
// short conditional jumps
case 0x80:case 0x81:case 0x82:case 0x83:case 0x84:case 0x85:case 0x86:case 0x87:
case 0x88:case 0x89:case 0x8a:case 0x8b:case 0x8c:case 0x8d:case 0x8e:case 0x8f:
dyn_branched_exit((BranchTypes)(dual_code&0xf),
decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw());
goto finish_block;
// conditional byte set instructions
/* case 0x90:case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97:
case 0x98:case 0x99:case 0x9a:case 0x9b:case 0x9c:case 0x9d:case 0x9e:case 0x9f:
dyn_set_byte_on_condition((BranchTypes)(dual_code&0xf));
AcquireFlags(FMASK_TEST);
break; */
// push/pop segment registers
case 0xa0:dyn_push_seg(DRC_SEG_FS);break;
case 0xa1:dyn_pop_seg(DRC_SEG_FS);break;
case 0xa8:dyn_push_seg(DRC_SEG_GS);break;
case 0xa9:dyn_pop_seg(DRC_SEG_GS);break;
// double shift instructions
case 0xa4:dyn_dshift_ev_gv(true,true);break;
case 0xa5:dyn_dshift_ev_gv(true,false);break;
case 0xac:dyn_dshift_ev_gv(false,true);break;
case 0xad:dyn_dshift_ev_gv(false,false);break;
case 0xaf:dyn_imul_gvev(0);break;
// lfs
case 0xb4:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(DRC_SEG_FS);
break;
// lgs
case 0xb5:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(DRC_SEG_GS);
break;
// zero-extending moves
case 0xb6:dyn_movx_ev_gb(false);break;
case 0xb7:dyn_movx_ev_gw(false);break;
// sign-extending moves
case 0xbe:dyn_movx_ev_gb(true);break;
case 0xbf:dyn_movx_ev_gw(true);break;
default:
// DYN_LOG("Unhandled dual opcode 0F%02X",dual_code);
goto illegalopcode;
}
break;
}
// 'inc/dec reg16/32'
case 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:
dyn_sop_word(SOP_INC,opcode&7);
break;
case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f:
dyn_sop_word(SOP_DEC,opcode&7);
break;
// 'push/pop reg16/32'
case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:
dyn_push_reg(opcode&7);
break;
case 0x58:case 0x59:case 0x5a:case 0x5b:case 0x5c:case 0x5d:case 0x5e:case 0x5f:
dyn_pop_reg(opcode&7);
break;
case 0x60:
if (decode.big_op) gen_call_function_raw((void *)&dynrec_pusha_dword);
else gen_call_function_raw((void *)&dynrec_pusha_word);
break;
case 0x61:
if (decode.big_op) gen_call_function_raw((void *)&dynrec_popa_dword);
else gen_call_function_raw((void *)&dynrec_popa_word);
break;
// case 0x62: BOUND missing
// case 0x61: ARPL missing
case 0x66:decode.big_op=!cpu.code.big;goto restart_prefix;
case 0x67:decode.big_addr=!cpu.code.big;goto restart_prefix;
// 'push imm8/16/32'
case 0x68:
dyn_push_word_imm(decode.big_op ? decode_fetchd() : decode_fetchw());
break;
case 0x6a:
dyn_push_byte_imm((Bit8s)decode_fetchb());
break;
// signed multiplication
case 0x69:dyn_imul_gvev(decode.big_op ? 4 : 2);break;
case 0x6b:dyn_imul_gvev(1);break;
// case 0x6c to 0x6f missing (ins/outs)
// short conditional jumps
case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76:case 0x77:
case 0x78:case 0x79:case 0x7a:case 0x7b:case 0x7c:case 0x7d:case 0x7e:case 0x7f:
dyn_branched_exit((BranchTypes)(opcode&0xf),(Bit8s)decode_fetchb());
goto finish_block;
// 'op []/reg8,imm8'
case 0x80:
case 0x82:dyn_grp1_eb_ib();break;
// 'op []/reg16/32,imm16/32'
case 0x81:dyn_grp1_ev_iv(false);break;
case 0x83:dyn_grp1_ev_iv(true);break;
// 'test []/reg8/16/32,reg8/16/32'
case 0x84:dyn_dop_gbeb(DOP_TEST);break;
case 0x85:dyn_dop_gvev(DOP_TEST);break;
// 'xchg reg8/16/32,[]/reg8/16/32'
case 0x86:dyn_dop_ebgb_xchg();break;
case 0x87:dyn_dop_evgv_xchg();break;
// 'mov []/reg8/16/32,reg8/16/32'
case 0x88:dyn_dop_ebgb_mov();break;
case 0x89:dyn_dop_evgv_mov();break;
// 'mov reg8/16/32,[]/reg8/16/32'
case 0x8a:dyn_dop_gbeb_mov();break;
case 0x8b:dyn_dop_gvev_mov();break;
// move segment register into memory or a 16bit register
case 0x8c:dyn_mov_ev_seg();break;
// load effective address
case 0x8d:dyn_lea();break;
// move a value from memory or a 16bit register into a segment register
case 0x8e:dyn_mov_seg_ev();break;
// 'pop []'
case 0x8f:dyn_pop_ev();break;
case 0x90: // nop
case 0x9b: // wait
case 0xf0: // lock
break;
case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97:
dyn_xchg_ax(opcode&7);
break;
// sign-extend al into ax/sign-extend ax into eax
case 0x98:dyn_cbw();break;
// sign-extend ax into dx:ax/sign-extend eax into edx:eax
case 0x99:dyn_cwd();break;
case 0x9a:dyn_call_far_imm();goto finish_block;
case 0x9c: // pushf
AcquireFlags(FMASK_TEST);
gen_call_function_I((void *)&CPU_PUSHF,decode.big_op);
dyn_check_exception(FC_RETOP);
break;
case 0x9d: // popf
gen_call_function_I((void *)&CPU_POPF,decode.big_op);
dyn_check_exception(FC_RETOP);
InvalidateFlags();
break;
case 0x9e:dyn_sahf();break;
// case 0x9f: LAHF missing
// 'mov al/ax,[]'
case 0xa0:
dyn_mov_byte_al_direct(decode.big_addr ? decode_fetchd() : decode_fetchw());
break;
case 0xa1:
dyn_mov_byte_ax_direct(decode.big_addr ? decode_fetchd() : decode_fetchw());
break;
// 'mov [],al/ax'
case 0xa2:
dyn_mov_byte_direct_al();
break;
case 0xa3:
dyn_mov_byte_direct_ax(decode.big_addr ? decode_fetchd() : decode_fetchw());
break;
// case 0xa6 to 0xaf string operations, some missing
// movsb/w/d
case 0xa4:dyn_string(STR_MOVSB);break;
case 0xa5:dyn_string(decode.big_op ? STR_MOVSD : STR_MOVSW);break;
// stosb/w/d
case 0xaa:dyn_string(STR_STOSB);break;
case 0xab:dyn_string(decode.big_op ? STR_STOSD : STR_STOSW);break;
// lodsb/w/d
case 0xac:dyn_string(STR_LODSB);break;
case 0xad:dyn_string(decode.big_op ? STR_LODSD : STR_LODSW);break;
// 'test reg8/16/32,imm8/16/32'
case 0xa8:dyn_dop_byte_imm(DOP_TEST,DRC_REG_EAX,0);break;
case 0xa9:dyn_dop_word_imm_old(DOP_TEST,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
// 'mov reg8/16/32,imm8/16/32'
case 0xb0:case 0xb1:case 0xb2:case 0xb3:case 0xb4:case 0xb5:case 0xb6:case 0xb7:
dyn_mov_byte_imm(opcode&3,(opcode>>2)&1,decode_fetchb());
break;
case 0xb8:case 0xb9:case 0xba:case 0xbb:case 0xbc:case 0xbd:case 0xbe:case 0xbf:
dyn_mov_word_imm(opcode&7);break;
break;
// 'shiftop []/reg8,imm8/1/cl'
case 0xc0:dyn_grp2_eb(grp2_imm);break;
case 0xd0:dyn_grp2_eb(grp2_1);break;
case 0xd2:dyn_grp2_eb(grp2_cl);break;
// 'shiftop []/reg16/32,imm8/1/cl'
case 0xc1:dyn_grp2_ev(grp2_imm);break;
case 0xd1:dyn_grp2_ev(grp2_1);break;
case 0xd3:dyn_grp2_ev(grp2_cl);break;
// retn [param]
case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block;
case 0xc3:dyn_ret_near(0);goto finish_block;
// les
case 0xc4:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(DRC_SEG_ES);
break;
// lds
case 0xc5:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(DRC_SEG_DS);break;
// 'mov []/reg8/16/32,imm8/16/32'
case 0xc6:dyn_dop_ebib_mov();break;
case 0xc7:dyn_dop_eviv_mov();break;
case 0xc8:dyn_enter();break;
case 0xc9:dyn_leave();break;
// retf [param]
case 0xca:dyn_ret_far(decode_fetchw());goto finish_block;
case 0xcb:dyn_ret_far(0);goto finish_block;
// int/iret
case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block;
case 0xcf:dyn_iret();goto finish_block;
// case 0xd4: AAM missing
// case 0xd5: AAD missing
// case 0xd6: SALC missing
// case 0xd7: XLAT missing
#ifdef CPU_FPU
// floating point instructions
case 0xd8:
dyn_fpu_esc0();
break;
case 0xd9:
dyn_fpu_esc1();
break;
case 0xda:
dyn_fpu_esc2();
break;
case 0xdb:
dyn_fpu_esc3();
break;
case 0xdc:
dyn_fpu_esc4();
break;
case 0xdd:
dyn_fpu_esc5();
break;
case 0xde:
dyn_fpu_esc6();
break;
case 0xdf:
dyn_fpu_esc7();
break;
#endif
// loop instructions
case 0xe0:dyn_loop(LOOP_NE);goto finish_block;
case 0xe1:dyn_loop(LOOP_E);goto finish_block;
case 0xe2:dyn_loop(LOOP_NONE);goto finish_block;
case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block;
// 'in al/ax/eax,port_imm'
case 0xe4:dyn_read_port_byte_direct(decode_fetchb());break;
case 0xe5:dyn_read_port_word_direct(decode_fetchb());break;
// 'out port_imm,al/ax/eax'
case 0xe6:dyn_write_port_byte_direct(decode_fetchb());break;
case 0xe7:dyn_write_port_word_direct(decode_fetchb());break;
// 'in al/ax/eax,port_dx'
case 0xec:dyn_read_port_byte();break;
case 0xed:dyn_read_port_word();break;
// 'out port_dx,al/ax/eax'
case 0xee:dyn_write_port_byte();break;
case 0xef:dyn_write_port_word();break;
// 'call near imm16/32'
case 0xe8:
dyn_call_near_imm();
goto finish_block;
// 'jmp near imm16/32'
case 0xe9:
dyn_exit_link(decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw());
goto finish_block;
// 'jmp far'
case 0xea:
dyn_jmp_far_imm();
goto finish_block;
// 'jmp short imm8'
case 0xeb:
dyn_exit_link((Bit8s)decode_fetchb());
goto finish_block;
// repeat prefixes
case 0xf2:
decode.rep=REP_NZ;
goto restart_prefix;
case 0xf3:
decode.rep=REP_Z;
goto restart_prefix;
case 0xf5: //CMC
gen_call_function_raw((void*)dynrec_cmc);
break;
case 0xf8: //CLC
gen_call_function_raw((void*)dynrec_clc);
break;
case 0xf9: //STC
gen_call_function_raw((void*)dynrec_stc);
break;
case 0xf6:dyn_grp3_eb();break;
case 0xf7:dyn_grp3_ev();break;
case 0xfa: //CLI
gen_call_function_raw((void *)&CPU_CLI);
dyn_check_exception(FC_RETOP);
break;
case 0xfb: //STI
gen_call_function_raw((void *)&CPU_STI);
dyn_check_exception(FC_RETOP);
if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode
break;
case 0xfc: //CLD
gen_call_function_raw((void*)dynrec_cld);
break;
case 0xfd: //STD
gen_call_function_raw((void*)dynrec_std);
break;
case 0xfe:
if (dyn_grp4_eb()) goto finish_block;
break;
case 0xff:
if (dyn_grp4_ev()) goto core_close_block;
break;
default:
// DYN_LOG("Dynrec unhandled opcode %X",opcode);
goto illegalopcode;
}
}
// normal exit because the maximal number of opcodes has been reached
dyn_set_eip_end();
core_close_block:
dyn_reduce_cycles();
dyn_return(BR_Normal);
dyn_closeblock();
goto finish_block;
illegalopcode:
// some unhandled opcode has been encountered
dyn_set_eip_last();
dyn_reduce_cycles();
dyn_return(BR_Opcode); // tell the core what happened
dyn_closeblock();
goto finish_block;
finish_block:
// setup the correct end-address
decode.page.index--;
decode.active_block->page.end=(Bit16u)decode.page.index;
// LOG_MSG("Created block size %d start %d end %d",decode.block->cache.size,decode.block->page.start,decode.block->page.end);
return decode.block;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More