Imported sources
340
SheepShaver/COPYING
Normal file
@ -0,0 +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) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 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) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
60
SheepShaver/Makefile
Normal file
@ -0,0 +1,60 @@
|
||||
# Makefile for creating SheepShaver distributions
|
||||
# Written in 1999 by Christian Bauer <Christian.Bauer@uni-mainz.de>
|
||||
|
||||
VERSION := 2
|
||||
RELEASE := 2
|
||||
VERNAME := SheepShaver-$(VERSION)
|
||||
|
||||
SRCARCHIVE := $(shell date +SheepShaver_src_%d%m%Y.tar.gz)
|
||||
|
||||
TMPDIR := $(shell date +/tmp/build%m%s)
|
||||
DOCS := HISTORY LOG TODO
|
||||
SRCS := src
|
||||
|
||||
default: help
|
||||
|
||||
help:
|
||||
@echo "This top-level Makefile is for creating SheepShaver distributions."
|
||||
@echo "The following targets are available:"
|
||||
@echo " tarball source tarball ($(SRCARCHIVE))"
|
||||
@echo " links create links to Basilisk II sources"
|
||||
|
||||
clean:
|
||||
-rm -f $(SRCARCHIVE)
|
||||
|
||||
#
|
||||
# Source tarball
|
||||
#
|
||||
tarball: $(SRCARCHIVE)
|
||||
|
||||
$(SRCARCHIVE): $(SRCS) $(DOCS)
|
||||
-rm -rf $(TMPDIR)
|
||||
mkdir $(TMPDIR)
|
||||
cd $(TMPDIR); cvs export -D "$(ISODATE)" SheepShaver
|
||||
rm $(TMPDIR)/SheepShaver/Makefile
|
||||
mv $(TMPDIR)/SheepShaver $(TMPDIR)/$(VERNAME)
|
||||
cd $(TMPDIR); tar cfz $@ $(VERNAME)
|
||||
mv $(TMPDIR)/$@ .
|
||||
rm -rf $(TMPDIR)
|
||||
|
||||
#
|
||||
# Links to Basilisk II sources
|
||||
#
|
||||
links:
|
||||
@list='adb.cpp audio.cpp cdrom.cpp disk.cpp extfs.cpp prefs.cpp \
|
||||
scsi.cpp sony.cpp xpram.cpp \
|
||||
include/adb.h include/audio.h include/audio_defs.h \
|
||||
include/cdrom.h include/clip.h include/debug.h include/disk.h \
|
||||
include/extfs.h include/extfs_defs.h include/prefs.h \
|
||||
include/scsi.h include/serial.h include/serial_defs.h \
|
||||
include/sony.h include/sys.h include/timer.h include/xpram.h \
|
||||
BeOS/audio_beos.cpp BeOS/extfs_beos.cpp BeOS/scsi_beos.cpp \
|
||||
BeOS/serial_beos.cpp BeOS/sys_beos.cpp BeOS/timer_beos.cpp \
|
||||
BeOS/xpram_beos.cpp BeOS/SheepDriver BeOS/SheepNet \
|
||||
Unix/audio_oss_esd.cpp Unix/extfs_unix.cpp Unix/serial_unix.cpp \
|
||||
Unix/sys_unix.cpp Unix/timer_unix.cpp Unix/xpram_unix.cpp \
|
||||
Unix/Linux/scsi_linux.cpp Unix/Linux/NetDriver'; \
|
||||
for i in $$list; do \
|
||||
echo $$i; \
|
||||
ln -sf `pwd`/../BasiliskII/src/$$i src/$$i; \
|
||||
done;
|
24
SheepShaver/doc/BeOS/acknowledgements.html
Normal file
@ -0,0 +1,24 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Acknowledgements</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Acknowledgements</H1>
|
||||
|
||||
The following persons/companies deserve special thanks from us as they
|
||||
made a significant contribution to the development of SheepShaver:
|
||||
|
||||
<P>
|
||||
<UL>
|
||||
<LI><A HREF="http://www.be.com/">Be Inc.</A>, and especially Dominic Giampaolo, for their support
|
||||
<LI>Tai Kahn from the <A HREF="http://www.ecafenet.com/">eCafe Network</A> for hosting the <A HREF="http://www.sheepshaver.com/">SheepShaver web site</A>
|
||||
<LI>Tinic Uro for the SheepShaver icon
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
47
SheepShaver/doc/BeOS/contact.html
Normal file
@ -0,0 +1,47 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Contact Information</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Contact Information and Copyright</H1>
|
||||
|
||||
SheepShaver was brought to you by
|
||||
<UL>
|
||||
<LI><A HREF="mailto:Christian.Bauer@uni-mainz.de">Christian Bauer</A> (kernel, disk I/O)
|
||||
<LI><A HREF="mailto:Marc.Hellwig@uni-mainz.de">Marc Hellwig</A> (graphics, sound, networking)
|
||||
</UL>
|
||||
|
||||
<H3><IMG SRC="iconsmall.gif" ALIGN=MIDDLE>SheepShaver WWW Site:</H3>
|
||||
<BLOCKQUOTE>
|
||||
<A HREF="http://www.sheepshaver.com/">www.sheepshaver.com</A><BR>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>EMail:</H3>
|
||||
<BLOCKQUOTE>
|
||||
<A HREF="mailto:Christian.Bauer@uni-mainz.de">Christian.Bauer@uni-mainz.de</A><BR>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>License</H3>
|
||||
|
||||
<P>SheepShaver is available under the terms of the GNU General Public License.
|
||||
See the file "COPYING" that is included in the distribution for details.
|
||||
|
||||
<P>© Copyright 1997-2002 Christian Bauer and Marc Hellwig
|
||||
|
||||
<P>Names of hardware and software items mentioned in this manual and
|
||||
in program texts are in most cases registered trade marks of the respective
|
||||
companies and not marked as such. So the lack of such a note may not be
|
||||
used as an indication that these names are free.
|
||||
|
||||
<P>SheepShaver is not designed, intended, or authorized for use as a component
|
||||
in systems intended for surgical implant within the body, or other applications intended
|
||||
to support or sustain life, or for any other application in which the failure of SheepShaver
|
||||
could create a situation where personal injury or death may occur (so-called "killer application").
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/BeOS/graphics.gif
Normal file
After Width: | Height: | Size: 8.6 KiB |
59
SheepShaver/doc/BeOS/history.html
Normal file
@ -0,0 +1,59 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Revision History</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>SheepShaver Revision History</H1>
|
||||
|
||||
<H2>V2.2 (04-Feb-2002)</H2>
|
||||
<UL>
|
||||
<LI>Integrated code from Basilisk II
|
||||
<LI>Source released under GPL
|
||||
</UL>
|
||||
|
||||
<H2>V2.1 (31-Mar-2001)</H2>
|
||||
<UL>
|
||||
<LI>Support for MacOS 8.5 and 8.6
|
||||
<LI>Support for G3 ROMs
|
||||
<LI>It's possible to select which video modes are to be used by MacOS
|
||||
<LI>SheepShaver will not use up all CPU time when "nothing" is running
|
||||
<LI>More stable networking
|
||||
<LI>16 and 32 bit window modes
|
||||
<LI>Small bug fixes
|
||||
</UL>
|
||||
|
||||
<H2>V2.0 (20-Jan-1999)</H2>
|
||||
<UL>
|
||||
<LI>"BeOS" icon on the Mac desktop to access files on BeOS volumes from Mac applications.
|
||||
<LI>Handling of removable media (i.e. automatic detection of disk insertion)
|
||||
<LI>More flexible parallel port selection on BeBox
|
||||
<LI>Greatly improved Time Manager (higher accuracy)
|
||||
<LI>Fixed "audio lags"
|
||||
<LI>Option to ignore illegal memory accesses
|
||||
<LI>Adapted for (and requires) BeOS R4
|
||||
<LI>MacOS 7.5.5/7.6/7.6.1 run better on some systems
|
||||
<LI>Small bug fixes
|
||||
</UL>
|
||||
|
||||
<H2>V1.1 (13-Jul-1998)</H2>
|
||||
<UL>
|
||||
<LI>Support for more machine types (esp. PowerMac 4400)
|
||||
<LI>Corrected time zone handling
|
||||
<LI>Volume list in preferences handles dropped volumes and files
|
||||
<LI>BeBox: 16/24 bit modes have correct colors with a Millennium II
|
||||
<LI>Video/SetEntries didn't set last palette entry
|
||||
<LI>Mac programs trying to use the (non-existant) SCSI Manager shouldn't crash any longer
|
||||
</UL>
|
||||
|
||||
<H2>V1.0 (18-May-1998)</H2>
|
||||
<UL>
|
||||
<LI>Initial release
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/BeOS/icon.gif
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
SheepShaver/doc/BeOS/iconsmall.gif
Normal file
After Width: | Height: | Size: 1.3 KiB |
28
SheepShaver/doc/BeOS/index.html
Normal file
@ -0,0 +1,28 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>The SheepShaver User's Guide</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1><IMG SRC="icon.gif" ALIGN=MIDDLE>SheepShaver V2.2 Installation and User's Guide (BeOS)</H1>
|
||||
|
||||
<H2>Contents</H2>
|
||||
|
||||
<UL>
|
||||
<LI><A HREF="introduction.html">Introduction</A>
|
||||
<LI><A HREF="installation.html">Installation</A>
|
||||
<LI><A HREF="quickstart.html">Quick Start</A>
|
||||
<LI><A HREF="settings.html">Setting up SheepShaver</A>
|
||||
<LI><A HREF="using.html">Using SheepShaver</A>
|
||||
<LI><A HREF="troubleshooting.html">Troubleshooting</A>
|
||||
<LI><A HREF="acknowledgements.html">Acknowledgements</A>
|
||||
<LI><A HREF="contact.html">Contact Information and Copyright</A>
|
||||
<LI><A HREF="history.html">Revision History</A>
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
25
SheepShaver/doc/BeOS/installation.html
Normal file
@ -0,0 +1,25 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Installation</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Installation</H1>
|
||||
|
||||
You need BeOS/PowerPC R4. R3 or earlier versions will not work.
|
||||
|
||||
<OL>
|
||||
<LI>Unpack the SheepShaver package (if you are reading this, you probably have already done this)
|
||||
<LI>On a BeBox, you need a copy of a PCI PowerMac ROM (4MB) in a file
|
||||
called "ROM" in the same folder SheepShaver is in (but you can select a different
|
||||
location in the settings window). SheepShaver can also use the "Mac OS ROM" file
|
||||
that comes with MacOS 8.5/8.6 (look in the System Folder on your MacOS CD). In
|
||||
order to legally use SheepShaver, you have to own the ROM the image file was taken from.
|
||||
</OL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
45
SheepShaver/doc/BeOS/introduction.html
Normal file
@ -0,0 +1,45 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Introduction</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Introduction</H1>
|
||||
|
||||
SheepShaver is a MacOS run-time environment for BeOS that allows you
|
||||
to run MacOS applications at native speed inside the BeOS multitasking
|
||||
environment on PowerPC-based BeOS systems. This means that both BeOS
|
||||
and MacOS applications can run at the same time and data can be exchanged
|
||||
between them.
|
||||
|
||||
<P>SheepShaver is neither a MacOS replacement nor an emulator. It runs an
|
||||
unmodified PowerPC MacOS under control of the BeOS at full speed without
|
||||
any kind of emulation. So it also uses the MacOS 68k emulator to run 68k
|
||||
applications. In this way, SheepShaver is comparable to the "Blue Box" of
|
||||
Apple's Rhapsody operating system.
|
||||
|
||||
<H2>Some of SheepShaver's features:</H2>
|
||||
|
||||
<UL>
|
||||
<LI>Compatibility: SheepShaver runs MacOS 7.5.2 thru 8.6 with all system
|
||||
extensions like AppleGuide, AppleScript, QuickTime, QuickTime VR,
|
||||
QuickDraw 3D, Open Transport, PPP, Language Kits, ColorSync, etc.
|
||||
<LI>Graphics: The MacOS user interface is displayed in a BeOS window or
|
||||
full-screen (with QuickDraw acceleration) in resolutions up to
|
||||
1600x1200 in 24 bit.
|
||||
<LI>Sound: CD-quality stereo sound output
|
||||
<LI>Networking: SheepShaver supports Internet and LAN networking via
|
||||
Ethernet and PPP with all Open Transport compatible MacOS applications.
|
||||
<LI>Volumes: Any HFS or HFS+ volume can be used with SheepShaver (this
|
||||
includes Zip/Jaz/SyQuest drives etc.). It also features a built-in
|
||||
CD-ROM driver and a driver for HD floppy disks.
|
||||
<LI>Data Exchange: You can access BeOS files from the MacOS via a "BeOS"
|
||||
icon on the Mac desktop and copy and paste text between BeOS and MacOS
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/BeOS/memory.gif
Normal file
After Width: | Height: | Size: 5.4 KiB |
38
SheepShaver/doc/BeOS/quickstart.html
Normal file
@ -0,0 +1,38 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Quick Start</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Quick Start</H1>
|
||||
|
||||
The following is a step-by-step guide that shows you how to get SheepShaver
|
||||
up and running in the quickest possible way. We assume that you are running
|
||||
on a PowerMac that already has MacOS installed on a partition of your hard drive
|
||||
and that you have booted into BeOS.
|
||||
|
||||
<P>
|
||||
<OL>
|
||||
<LI>Double-click the SheepShaver icon. The "SheepShaver Settings" window will appear.
|
||||
<LI>Click on "Start". SheepShaver will try to detect on which partition MacOS is installed and should then start booting MacOS.
|
||||
<LI>If this is the first time you start SheepShaver you will be asked if you want your
|
||||
network configuration to be modified to enable Ethernet networking under SheepShaver.
|
||||
If you want to use Ethernet with SheepShaver you should press "OK" (this will change the
|
||||
file <CODE>/boot/home/config/settings/network</CODE>; a backup of the the original file will
|
||||
be stored in <CODE>network.orig</CODE>).
|
||||
<LI>To quit SheepShaver, select "Shutdown" from the Finder's "Special" menu.
|
||||
</OL>
|
||||
|
||||
<H3>One word of caution:</H3>
|
||||
|
||||
Volumes which are used by SheepShaver must not also be mounted under BeOS
|
||||
while SheepShaver is running. <STRONG>You will lose data and corrupt the
|
||||
volume if you do this! Don't press the "Mount all disks now" button in the
|
||||
BeOS "Disk Mount Settings" window while SheepShaver is running!</STRONG>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/BeOS/serial.gif
Normal file
After Width: | Height: | Size: 4.7 KiB |
127
SheepShaver/doc/BeOS/settings.html
Normal file
@ -0,0 +1,127 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Setting up SheepShaver</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Setting up SheepShaver</H1>
|
||||
|
||||
In the "SheepShaver Settings" window that pops up when you double-click on
|
||||
the SheepShaver icon, you can configure certain features of SheepShaver.
|
||||
When you click on <B>"Start"</B>, the current settings are saved to disk and will be
|
||||
available next time you start SheepShaver.
|
||||
|
||||
<P>The settings are divided into four groups: Volumes, Graphics/Sound, Serial/Network and Memory/Misc.
|
||||
|
||||
<H2>Volumes</H2>
|
||||
|
||||
<IMG SRC="volumes.gif">
|
||||
|
||||
<P>The main part of the volumes pane is a <B>list</B> that contains all volumes to be mounted
|
||||
by SheepShaver. If this list is empty, SheepShaver will try to detect and mount all HFS partitions
|
||||
it can find. CD-ROM drives are always automatically detected and used.
|
||||
|
||||
<P>SheepShaver can use HFS partitions, whole HFS formatted drives, and it can also
|
||||
emulate hard disks in single BeOS files ("hardfiles").
|
||||
|
||||
<P>To add a Mac volume to the list, mount it on the BeOS side, click on <B>"Add..."</B>, go to the "Disks"
|
||||
level in the topmost popup menu of the file panel, click once on the volume you want and
|
||||
click on "Add". A line beginning with "/dev/disk/" should then appear in the volume list.
|
||||
After adding volumes to the list, you should unmount them on the BeOS side again.To remove
|
||||
a Mac volume, select it in the list and click on <B>"Remove"</B>.
|
||||
|
||||
<P>You can create a new, empty hardfile by clicking on <B>"Create..."</B>. Enter the file
|
||||
name and the size of the hardfile and click on "Create". The hardfile will be created (this may
|
||||
take some seconds) and added to the volume list. The so-created hardfile will have to be
|
||||
formatted under MacOS before you can store something in it. If you start up SheepShaver,
|
||||
the Finder will display a message about an "unreadable" volume being found and give you the
|
||||
option to format it.
|
||||
|
||||
<P>Double-clicking on an entry in the volume list will add or remove a "*" in front of the
|
||||
device name. Volumes marked with a "*" are read-only for the MacOS under SheepShaver.
|
||||
|
||||
<P>SheepShaver will show a "BeOS" disk icon on the Mac desktop that allows access to BeOS
|
||||
files from Mac applications. In <B>"BeOS Root"</B> you specify which BeOS directory will
|
||||
be at the root of this virtual "BeOS" disk. You can enter a path name here or drag and drop a
|
||||
Tracker folder onto it. The default setting of "/boot" means that the "BeOS" icon in the MacOS
|
||||
Finder will correspond to your BeOS boot volume. If you want to access files on other BeOS
|
||||
volumes, you should enter "/" here. The "BeOS" disk will then contain folders for each BeOS
|
||||
volume (among other things). The MacOS will create files and folders like "Desktop", "Trash",
|
||||
"OpenFolderListDF" etc. in the directory you specify as "BeOS Root". If they annoy you, you
|
||||
can delete them.
|
||||
|
||||
<P>To boot from CD-ROM, set the <B>"Boot From"</B> setting to <B>"CD-ROM"</B>.
|
||||
The <B>"Disable CD-ROM Driver"</B> box is used to disable SheepShaver's built-in CD-ROM driver.
|
||||
This is currently of not much use and you should leave the box unselected.
|
||||
|
||||
<H2>Graphics/Sound</H2>
|
||||
|
||||
<IMG SRC="graphics.gif">
|
||||
|
||||
<P>WIth <B>"Window Refresh Rate"</B> you can set the refresh rate of the MacOS window.
|
||||
Higher rates mean faster screen updates and less "sluggish" behaviour, but also require more CPU time.
|
||||
|
||||
<P>The <B>"QuickDraw Acceleration"</B> box should always be enabled. It allows for faster graphics in
|
||||
full-screen modes. But if your machine uses the "IXMicro" BeOS video driver, you have to disable the
|
||||
QuickDraw acceleration or full-screen modes won't work (this is because of BeOS bug #981112-032247).
|
||||
|
||||
<P>The main part of the window is occupied by a list of checkboxes that allows you to select
|
||||
which <B>graphics modes</B> are available for displaying the MacOS desktop. You can, for
|
||||
example, disable the modes that your monitor or graphics card can't display, or disable the
|
||||
window modes when you want to run some Mac programs in full-screen mode that would otherwise
|
||||
erroneously switch to a window mode. The actual mode to be used is selected in the "Monitors"
|
||||
control panel under MacOS.
|
||||
|
||||
<P>The <B>"Disable Sound Output"</B> box allows you to disable all sound output by SheepShaver.
|
||||
This is useful if the sound takes too much CPU time on your machine or to get rid of warning
|
||||
messages if SheepShaver can't use your audio hardware.
|
||||
|
||||
<H2>Serial/Network</H2>
|
||||
|
||||
<IMG SRC="serial.gif">
|
||||
|
||||
<P>You can select to which ports the MacOS <B>modem and printer ports</B> are redirected.
|
||||
This doesn't make much sense on a PowerMac, but on a BeBox you can assign the modem
|
||||
and printer ports to any of the four serial ports (or com3/com4) or even parallel ports of
|
||||
the BeBox (useful for printing if you have Mac drivers for parallel printers, like the PowerPrint
|
||||
package from <A HREF="http://www.gdt.com">www.gdt.com</A>).
|
||||
|
||||
<P>If you don't want SheepShaver's Ethernet support to be enabled for some reason, you
|
||||
can use the <B>"Disable Ethernet"</B> checkbox to disable it (this will also get rid of the annoying
|
||||
"no network hardware" messages if your Mac is not equipped with Ethernet).
|
||||
|
||||
<H2>Memory/Misc</H2>
|
||||
|
||||
<IMG SRC="memory.gif">
|
||||
|
||||
<P>With <B>"MacOS RAM Size"</B> you select how much RAM will be available to the MacOS
|
||||
(and all MacOS applications running under it). SheepShaver uses the BeOS virtual memory system,
|
||||
so you can select more RAM than you physically have in your machine. The MacOS virtual memory
|
||||
system is not available under SheepShaver (i.e. if you have 32MB of RAM in your computer and
|
||||
select 64MB to be used for MacOS in the SheepShaver settings, MacOS will behave as if it's running on
|
||||
a computer that has 64MB of RAM but no virtual memory).
|
||||
|
||||
<P>The <B>"Ignore Illegal Memory Accesses"</B> option is there to make some broken Mac
|
||||
programs work that access addresses where there is no RAM or ROM. With this option unchecked,
|
||||
SheepShaver will in this case display an error message and quit. When the option is activated,
|
||||
SheepShaver will try to continue as if the illegal access never happened (writes are ignored, reads
|
||||
return 0). This may or may not make the program work (when a program performs an illegal access,
|
||||
it is most likely that something else went wrong). When a Mac program behaves strangely or hangs,
|
||||
you can quit SheepShaver, uncheck this option and retry. If you get an "illegal access" message,
|
||||
you will know that something is broken.
|
||||
|
||||
<P>If the <B>"Don't Use CPU When Idle"</B> option is enabled, SheepShaver will try to reduce
|
||||
CPU usage to a minimum when the MacOS is doing "nothing" but waiting for user input. This doesn't
|
||||
work with all programs and it may confuse the timing of some games but in general you should
|
||||
leave it enabled.
|
||||
|
||||
<P><B>"ROM File"</B> specifies the path name of the Mac ROM file to be used. If it is left
|
||||
blank, SheepShaver expects the ROM file to be called "ROM" and be in the same directory as
|
||||
the SheepShaver application.
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
79
SheepShaver/doc/BeOS/troubleshooting.html
Normal file
@ -0,0 +1,79 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Troubleshooting</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Troubleshooting</H1>
|
||||
|
||||
<H2>SheepShaver doesn't boot</H2>
|
||||
|
||||
SheepShaver should boot all MacOS versions >=7.5.2, except MacOS X. However,
|
||||
your mileage may vary. If it doesn't boot, try again with extensions disabled
|
||||
(by pressing the shift key) and then remove some of these extensions:
|
||||
"MacOS Licensing Extension", Speed Doubler, 68k FPU extensions and MacsBug.
|
||||
|
||||
<H2>The colors are wrong in 16 or 32 bit graphics modes</H2>
|
||||
|
||||
If you're running SheepShaver on a BeBox, the only graphics modes that have
|
||||
the right colors are the 8 bit modes (this is actually a hardware problem
|
||||
and has to do with frame buffers being little-endian on the BeBox), unless
|
||||
you are using a Matrox Milennium I/II.
|
||||
<P>You should also be aware that not all graphics cards support 16 bit modes
|
||||
under BeOS (especially S3 cards don't). Check the BeOS "Screen" preferences
|
||||
application to see if your card does.
|
||||
|
||||
<H2>SheepShaver appears to be very slow</H2>
|
||||
|
||||
<UL>
|
||||
<LI>Don't use the window modes, the fullscreen modes are much faster.
|
||||
<LI>If you nevertheless want (or have) to use a window mode, you should set the
|
||||
color depth in MacOS to the same as the BeOS workspace you are running SheepShaver on
|
||||
(e.g. if you are on a 16-bit workspace, set the color depth in MacOS to "Thousands").
|
||||
Also, set the window refresh rate to a low value (high values like 30Hz will make SheepShaver
|
||||
(and BeOS) slower, not faster!).
|
||||
</UL>
|
||||
|
||||
<H2>Full-screen mode doesn't work</H2>
|
||||
|
||||
If your machine uses the "IXMicro" BeOS video driver (TwinTurbo cards), you
|
||||
will have to disable the "QuickDraw Acceleration" in the "Video" pane of the
|
||||
SheepShaver settings.
|
||||
|
||||
<H2>Ethernet doesn't work</H2>
|
||||
|
||||
<UL>
|
||||
<LI>Is the Ethernet set up under BeOS? Ethernet will not work in SheepShaver if you didn't set it up in the BeOS "Network" preferences.
|
||||
<LI>If you're using TCP/IP on the MacOS side, you have to set up different IP addresses for the BeOS and for the MacOS.
|
||||
<LI>Try disabling AppleTalk in the BeOS Network preferences (there might be conflicts between BeOS AppleTalk and SheepShaver networking).
|
||||
</UL>
|
||||
|
||||
<H2>SheepShaver crashes, but yesterday it worked</H2>
|
||||
|
||||
Try the "Zap PRAM File" item in the main menu of the SheepShaver preferences editor.
|
||||
When you are using a ROM file and switching to a different ROM version, you <B>have</B>
|
||||
to zap the PRAM file or SheepShaver might behave very weird.
|
||||
|
||||
<H2>Known incompatibilities</H2>
|
||||
|
||||
<UL>
|
||||
<LI>MacOS programs or drivers which access Mac hardware directly are not supported by SheepShaver.
|
||||
<LI>Speed Doubler, RAM Doubler, 68k FPU emulators and similar programs don't run under SheepShaver.
|
||||
<LI>MacsBug is not compatible with SheepShaver.
|
||||
<LI>If you want to run RealPC on a BeBox, you have to disable one CPU in the "Pulse" application or it will crash.
|
||||
</UL>
|
||||
|
||||
<H2>Known bugs</H2>
|
||||
|
||||
<UL>
|
||||
<LI>The QuickTime 2.5 Cinepak codec crashes the emulator.
|
||||
<LI>Programs that use InputSprockets crash the emulator when in window mode.
|
||||
<LI>The mouse cursor hotspot in window mode is not correct.
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
76
SheepShaver/doc/BeOS/using.html
Normal file
@ -0,0 +1,76 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Using SheepShaver</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Using SheepShaver</H1>
|
||||
|
||||
<H2>Changing the display mode</H2>
|
||||
|
||||
SheepShaver can display the MacOS user interface in a BeOS window or full-screen
|
||||
(much faster) in several resolutions and color depths. You select the display mode
|
||||
as usual under MacOS in the "Monitors" control panel (under System 7.x, click on "Options").
|
||||
The "75Hz" modes are full-screen modes, the "60Hz" modes are window modes
|
||||
(this doesn't mean that the video refresh rate is 75 or 60Hz in the respective modes;
|
||||
the rate displayed has no meaning; it's simply there to distinguish full screen modes
|
||||
from window modes).
|
||||
|
||||
<H2>Window mode</H2>
|
||||
|
||||
The SheepShaver window has a menu at the bottom that allows you to change the
|
||||
graphics refresh rate and to mount floppy disks (see below). The window refresh is
|
||||
disabled as long as the "Scroll Lock" key is pressed (the graphics output is then frozen).
|
||||
|
||||
<H2>Full-screen mode</H2>
|
||||
|
||||
The full-screen mode uses a whole BeOS workspace for displaying the MacOS user
|
||||
interface. You can switch workspaces with Command-F1/F2/F3/etc. Please note that
|
||||
the MacOS (and all MacOS applications) will be suspended when you switch to a different
|
||||
workspace. It will only be resumed when you go back to the SheepShaver workspace.
|
||||
|
||||
<H2>Networking</H2>
|
||||
|
||||
SheepShaver only supports Ethernet networking (and PPP via the serial
|
||||
ports). If there are multiple Ethernet cards installed, only the first
|
||||
card will be used. The Ethernet support is implemented at the data-link
|
||||
level. This implies that the "Mac" and the "Be" side must have two different
|
||||
network addresses.
|
||||
|
||||
<H2>Using floppy disks</H2>
|
||||
|
||||
Floppy disks are not automatically detected when they are inserted. They have to be
|
||||
mounted explicitly. After inserting a floppy disk, select the "Mount Floppy" item in the
|
||||
"SheepShaver" menu (when running in window mode), or press Ctrl-F1 (when running in
|
||||
full-screen mode). BeBox users should note that floppy disks also have to be unmounted
|
||||
under MacOS before ejecting them from the drive.
|
||||
|
||||
<H2>Accessing BeOS files</H2>
|
||||
|
||||
SheepShaver will display a "BeOS" disk icon on the Mac desktop that allows you
|
||||
to access any BeOS files/folders which are in the directory specified as "BeOS Root"
|
||||
in the "Volumes" pane of the SheepShaver settings. You can open and save files on the
|
||||
"BeOS" disk from Mac applications, copy, move or rename files from the Finder etc.
|
||||
Putting files/folder to the trash may however not always work. SheepShaver translates
|
||||
some BeOS file types to MacOS types and vice versa, so e.g. JPEG and PDF files will
|
||||
show up the correct icons in the Finder. To store Mac resources and other additional
|
||||
data, SheepShaver uses the following BeOS file attributes:
|
||||
|
||||
<UL>
|
||||
<LI><CODE>MACOS:RFORK</CODE> contains the complete Mac resource fork of the file
|
||||
<LI><CODE>MACOS:HFS_FLAGS</CODE> contains Finder flags
|
||||
<LI><CODE>MACOS:CREATOR</CODE> contains the MacOS creator application ID
|
||||
</UL>
|
||||
|
||||
<H2>Copying text via the clipboard</H2>
|
||||
|
||||
SheepShaver tries to keep the BeOS and MacOS clipboards synchronized. That means,
|
||||
when you copy a piece of text under BeOS, you can paste it into a MacOS application
|
||||
and vice versa.
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/BeOS/volumes.gif
Normal file
After Width: | Height: | Size: 7.3 KiB |
24
SheepShaver/doc/Linux/acknowledgements.html
Normal file
@ -0,0 +1,24 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Acknowledgements</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Acknowledgements</H1>
|
||||
|
||||
The following persons/companies deserve special thanks from us as they
|
||||
made a significant contribution to the development of SheepShaver:
|
||||
|
||||
<P>
|
||||
<UL>
|
||||
<LI><A HREF="http://www.linuxppc.com/">LinuxPPC, Inc.</A>, for supporting the development of this program
|
||||
<LI>Tai Kahn from the <A HREF="http://www.ecafenet.com/">eCafe Network</A> for hosting the <A HREF="http://www.sheepshaver.com/">SheepShaver web site</A>
|
||||
<LI>Tinic Uro for the SheepShaver icon
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
47
SheepShaver/doc/Linux/contact.html
Normal file
@ -0,0 +1,47 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Contact Information</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Contact Information and Copyright</H1>
|
||||
|
||||
SheepShaver was brought to you by
|
||||
<UL>
|
||||
<LI><A HREF="mailto:Christian.Bauer@uni-mainz.de">Christian Bauer</A> (kernel, disk I/O)
|
||||
<LI><A HREF="mailto:Marc.Hellwig@uni-mainz.de">Marc Hellwig</A> (graphics, sound, networking)
|
||||
</UL>
|
||||
|
||||
<H3><IMG SRC="iconsmall.gif" ALIGN=MIDDLE>SheepShaver WWW Site:</H3>
|
||||
<BLOCKQUOTE>
|
||||
<A HREF="http://www.sheepshaver.com/">www.sheepshaver.com</A><BR>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>EMail:</H3>
|
||||
<BLOCKQUOTE>
|
||||
<A HREF="mailto:sheep@sheepshaver.com">sheep@sheepshaver.com</A><BR>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>License</H3>
|
||||
|
||||
<P>SheepShaver is available under the terms of the GNU General Public License.
|
||||
See the file "COPYING" that is included in the distribution for details.
|
||||
|
||||
<P>© Copyright 1997-2002 Christian Bauer and Marc Hellwig
|
||||
|
||||
<P>Names of hardware and software items mentioned in this manual and
|
||||
in program texts are in most cases registered trade marks of the respective
|
||||
companies and not marked as such. So the lack of such a note may not be
|
||||
used as an indication that these names are free.
|
||||
|
||||
<P>SheepShaver is not designed, intended, or authorized for use as a component
|
||||
in systems intended for surgical implant within the body, or other applications intended
|
||||
to support or sustain life, or for any other application in which the failure of SheepShaver
|
||||
could create a situation where personal injury or death may occur (so-called "killer application").
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/Linux/graphics.gif
Normal file
After Width: | Height: | Size: 5.4 KiB |
25
SheepShaver/doc/Linux/history.html
Normal file
@ -0,0 +1,25 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Revision History</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>SheepShaver Revision History</H1>
|
||||
|
||||
<H2>V2.2 (04-Feb-2002)</H2>
|
||||
<UL>
|
||||
<LI>Integrated code from Basilisk II
|
||||
<LI>Source released under GPL
|
||||
</UL>
|
||||
|
||||
<H2>V2.1 (31-Mar-2001)</H2>
|
||||
<UL>
|
||||
<LI>Initial Linux PPC release
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/Linux/icon.gif
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
SheepShaver/doc/Linux/iconsmall.gif
Normal file
After Width: | Height: | Size: 1.3 KiB |
28
SheepShaver/doc/Linux/index.html
Normal file
@ -0,0 +1,28 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>The SheepShaver User's Guide</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1><IMG SRC="icon.gif" ALIGN=MIDDLE>SheepShaver V2.2 Installation and User's Guide (Linux)</H1>
|
||||
|
||||
<H2>Contents</H2>
|
||||
|
||||
<UL>
|
||||
<LI><A HREF="introduction.html">Introduction</A>
|
||||
<LI><A HREF="installation.html">Installation</A>
|
||||
<LI><A HREF="quickstart.html">Quick Start</A>
|
||||
<LI><A HREF="settings.html">Setting up SheepShaver</A>
|
||||
<LI><A HREF="using.html">Using SheepShaver</A>
|
||||
<LI><A HREF="troubleshooting.html">Troubleshooting</A>
|
||||
<LI><A HREF="acknowledgements.html">Acknowledgements</A>
|
||||
<LI><A HREF="contact.html">Contact Information and Copyright</A>
|
||||
<LI><A HREF="history.html">Revision History</A>
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
25
SheepShaver/doc/Linux/installation.html
Normal file
@ -0,0 +1,25 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Installation</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Installation</H1>
|
||||
|
||||
You need at least a 2.2.x kernel, glibc 2.1 and GTK+ 1.2. Earlier versions will not work.
|
||||
|
||||
<OL>
|
||||
<LI>Unpack the SheepShaver archive (if you are reading this, you probably have already done this)
|
||||
<LI>Even when running on a PowerMac, you need a copy of a PCI PowerMac ROM (4MB) in
|
||||
a file called "ROM" in the same folder SheepShaver is in (but you can select a different location
|
||||
in the settings window). SheepShaver can also use the "Mac OS ROM" file that comes with
|
||||
MacOS 8.5/8.6 (look in the System Folder on your MacOS CD). In order to legally use SheepShaver,
|
||||
you have to own the ROM the image file was taken from.
|
||||
</OL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
44
SheepShaver/doc/Linux/introduction.html
Normal file
@ -0,0 +1,44 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Introduction</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Introduction</H1>
|
||||
|
||||
SheepShaver is a MacOS run-time environment for Linux that allows you
|
||||
to run MacOS applications at native speed inside the Linux multitasking
|
||||
environment on PowerPC-based Linux systems. This means that both Linux
|
||||
and MacOS applications can run at the same time and data can be exchanged
|
||||
between them.
|
||||
|
||||
<P>SheepShaver is neither a MacOS replacement nor an emulator. It runs an
|
||||
unmodified PowerPC MacOS under control of Linux at full speed without any
|
||||
kind of emulation. So it also uses the MacOS 68k emulator to run 68k
|
||||
applications. In this way, SheepShaver is comparable to the "Blue Box" of
|
||||
Apple's Rhapsody operating system.
|
||||
|
||||
<H2>Some of SheepShaver's features:</H2>
|
||||
|
||||
<UL>
|
||||
<LI>Compatibility: SheepShaver runs MacOS 7.5.2 thru 8.6 with all system
|
||||
extensions like AppleGuide, AppleScript, QuickTime, QuickTime VR,
|
||||
QuickDraw 3D, Open Transport, PPP, Language Kits, ColorSync, etc.
|
||||
<LI>Graphics: The MacOS user interface is displayed in an X11 window or
|
||||
full-screen (requires DGA)
|
||||
<LI>Sound: CD-quality stereo sound output
|
||||
<LI>Networking: SheepShaver supports Internet and LAN networking via
|
||||
Ethernet and PPP with all Open Transport compatible MacOS applications.
|
||||
<LI>Volumes: Any HFS or HFS+ volume can be used with SheepShaver (this
|
||||
includes Zip/Jaz/SyQuest drives etc.). It also features a built-in
|
||||
CD-ROM driver and a driver for HD floppy disks.
|
||||
<LI>Data Exchange: You can access Linux files from the MacOS via a "Linux"
|
||||
icon on the Mac desktop and copy and paste text between Linux and MacOS
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/Linux/memory.gif
Normal file
After Width: | Height: | Size: 5.6 KiB |
39
SheepShaver/doc/Linux/quickstart.html
Normal file
@ -0,0 +1,39 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Quick Start</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Quick Start</H1>
|
||||
|
||||
The following is a step-by-step guide that shows you how to get SheepShaver
|
||||
up and running in the quickest possible way. We assume that you are running
|
||||
on a PowerMac that already has MacOS installed on a partition of your hard drive
|
||||
and that you have booted into Linux.
|
||||
|
||||
<P>
|
||||
<OL>
|
||||
<LI>Start the "SheepShaver" program. The "SheepShaver Settings" window will appear.
|
||||
<LI>Click on "Start". SheepShaver will try to detect on which partition MacOS is installed and should then start booting MacOS.
|
||||
<LI>To quit SheepShaver, select "Shutdown" from the Finder's "Special" menu.
|
||||
</OL>
|
||||
|
||||
When SheepShaver hangs or crashes in fullscreen mode, pressing Ctrl-Esc should
|
||||
quit it and restore the display.
|
||||
|
||||
<P>In fullscreen mode, press Ctrl-Tab to suspend SheepShaver and return to the
|
||||
normal X11 destop. Press space inside the "SheepShaver suspended" window to
|
||||
reactivate it.
|
||||
|
||||
<H3>One word of caution:</H3>
|
||||
|
||||
Volumes which are used by SheepShaver must not also be mounted under Linux
|
||||
while SheepShaver is running. <STRONG>You will lose data and corrupt the
|
||||
volume if you do this!</STRONG>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/Linux/serial.gif
Normal file
After Width: | Height: | Size: 5.2 KiB |
117
SheepShaver/doc/Linux/settings.html
Normal file
@ -0,0 +1,117 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Setting up SheepShaver</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Setting up SheepShaver</H1>
|
||||
|
||||
In the "SheepShaver Settings" window that pops up when you start SheepShaver,
|
||||
you can configure certain features of SheepShaver. When you click on <B>"Start"</B>,
|
||||
the current settings are saved to disk and will be available next time you start
|
||||
SheepShaver.
|
||||
|
||||
<P>The settings are divided into four groups: Volumes, Graphics/Sound, Serial/Network and Memory/Misc.
|
||||
|
||||
<H2>Volumes</H2>
|
||||
|
||||
<IMG SRC="volumes.gif">
|
||||
|
||||
<P>The main part of the volumes pane is a <B>list</B> that contains all volumes to be mounted
|
||||
by SheepShaver. If this list is empty, SheepShaver will try to detect and mount all
|
||||
HFS partitions it can find. A CD-ROM drive is always automatically detected and used.
|
||||
|
||||
<P>SheepShaver can use HFS partitions, whole HFS formatted drives, and it can also
|
||||
emulate hard disks in single Linux files ("hardfiles").
|
||||
|
||||
<P>To add a Mac volume to the list, click on <B>"Add..."</B>, go to the "/dev" directory
|
||||
in the file panel, click once on the partition you want and click on "OK". The selected
|
||||
partition device name should then appear in the volume list. After adding volumes to
|
||||
the list, you should unmount them on the Linux side. To remove a Mac volume, select it
|
||||
in the list and click on <B>"Remove"</B>.
|
||||
|
||||
<P>You can create a new, empty hardfile by clicking on <B>"Create..."</B>. Enter the file
|
||||
name and the size of the hardfile and click on "Create". The hardfile will be created (this may
|
||||
take some seconds) and added to the volume list. The so-created hardfile will have to be
|
||||
formatted under MacOS before you can store something in it. If you start up SheepShaver,
|
||||
the Finder will display a message about an "unreadable" volume being found and give you the
|
||||
option to format it.
|
||||
|
||||
<P>Double-clicking on an entry in the volume list will add or remove a "*" in front of the
|
||||
device name. Volumes marked with a "*" are read-only for the MacOS under SheepShaver.
|
||||
|
||||
<P>SheepShaver will show a "Linux" disk icon on the Mac desktop that allows access to Linux
|
||||
files from Mac applications. In <B>"Linux Root"</B> you specify which Linux directory will
|
||||
be at the root of this virtual "Linux" disk. The default setting of "/" means that the
|
||||
"Linux" icon in the MacOS Finder will correspond to your Linux root directory. The MacOS
|
||||
will try to create files and folders like "Desktop", "Trash", "OpenFolderListDF" etc.
|
||||
in the directory you specify as "Linux Root" (provided that you have access rights
|
||||
to that directory). If they annoy you, you can delete them.
|
||||
|
||||
<P>To boot from CD-ROM, set the <B>"Boot From"</B> setting to <B>"CD-ROM"</B>.
|
||||
The <B>"Disable CD-ROM Driver"</B> box is used to disable SheepShaver's built-in CD-ROM driver.
|
||||
This is currently of not much use and you should leave the box unselected.
|
||||
|
||||
<H2>Graphics/Sound</H2>
|
||||
|
||||
<IMG SRC="graphics.gif">
|
||||
|
||||
<P>With <B>"Window Refresh Rate"</B> you can set the refresh rate of the MacOS window.
|
||||
Higher rates mean faster screen updates and less "sluggish" behaviour, but also require more CPU time.
|
||||
|
||||
<P>The <B>"Enabled Video Modes"</B> controls allow you to select which graphics modes
|
||||
are available for displaying the MacOS desktop. You can, for example, disable the window modes
|
||||
when you want to run some Mac programs in full-screen mode that would otherwise erroneously
|
||||
switch to a window mode. If your X server doesn't support DGA you should disable the Fullscreen
|
||||
mode. The actual mode to be used is selected in the "Monitors" control panel under MacOS. The
|
||||
color depth is always that of the X11 screen and cannot be changed.
|
||||
|
||||
<P>The <B>"Disable Sound Output"</B> box allows you to disable all sound output by SheepShaver.
|
||||
This is useful if the sound takes too much CPU time on your machine or to get rid of warning
|
||||
messages if SheepShaver can't use your audio hardware.
|
||||
|
||||
<H2>Serial/Network</H2>
|
||||
|
||||
<IMG SRC="serial.gif">
|
||||
|
||||
<P>You can select to which devices the MacOS <B>modem and printer ports</B> are redirected.
|
||||
You can assign them to any serial ports you have (/dev/ttyS*), or even to parallel
|
||||
ports (/dev/lp*, useful for printing if you have Mac drivers for parallel printers,
|
||||
like the PowerPrint package from <A HREF="http://www.gdt.com">www.gdt.com</A>).
|
||||
|
||||
<P>With <B>"Ethernet Interface"</B> you select which Ethernet card is to be used for
|
||||
networking. It can either be the name of a real Ethernet card (e.g. "eth0") or of an ethertap
|
||||
interface (e.g. "tap0"). Using a real Ethernet card requires the "sheep_net" driver to be installed
|
||||
and accessible. See <A HREF="using.html">Using SheepShaver</A> for more
|
||||
information about setting up networking.
|
||||
|
||||
<H2>Memory/Misc</H2>
|
||||
|
||||
<IMG SRC="memory.gif">
|
||||
|
||||
<P>With <B>"MacOS RAM Size"</B> you select how much RAM will be available to the MacOS
|
||||
(and all MacOS applications running under it). SheepShaver uses the Linux virtual memory system,
|
||||
so you can select more RAM than you physically have in your machine. The MacOS virtual memory
|
||||
system is not available under SheepShaver (i.e. if you have 32MB of RAM in your computer and
|
||||
select 64MB to be used for MacOS in the SheepShaver settings, MacOS will behave as if it's running on
|
||||
a computer that has 64MB of RAM but no virtual memory).
|
||||
|
||||
<P><B>"ROM File"</B> specifies the path name of the Mac ROM file to be used. If it is left
|
||||
blank, SheepShaver expects the ROM file to be called "ROM" and be in the same directory as
|
||||
the SheepShaver application.
|
||||
|
||||
<P>The <B>"Ignore Illegal Memory Accesses"</B> option is there to make some broken Mac
|
||||
programs work that access addresses where there is no RAM or ROM. With this option unchecked,
|
||||
SheepShaver will in this case display an error message and quit. When the option is activated,
|
||||
SheepShaver will try to continue as if the illegal access never happened (writes are ignored, reads
|
||||
return 0). This may or may not make the program work (when a program performs an illegal access,
|
||||
it is most likely that something else went wrong). When a Mac program behaves strangely or hangs,
|
||||
you can quit SheepShaver, uncheck this option and retry. If you get an "illegal access" message,
|
||||
you will know that something is broken.
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
65
SheepShaver/doc/Linux/troubleshooting.html
Normal file
@ -0,0 +1,65 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Troubleshooting</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Troubleshooting</H1>
|
||||
|
||||
<H2>SheepShaver doesn't boot</H2>
|
||||
|
||||
SheepShaver should boot all MacOS versions >=7.5.2, except MacOS X. However,
|
||||
your mileage may vary. If it doesn't boot, try again with extensions disabled
|
||||
(by pressing the shift key) and then remove some of these extensions:
|
||||
"MacOS Licensing Extension", Speed Doubler, 68k FPU extensions and MacsBug.
|
||||
|
||||
<H2>The colors are wrong in 16 or 32 bit graphics modes</H2>
|
||||
|
||||
If you're running SheepShaver on a something other than a PowerMac, it may be
|
||||
that 16 or 32 bit graphics modes show false colors due to the frame buffer being
|
||||
little-endian. Apart from patching the X server, there's unfortunately nothing
|
||||
that you or SheepShaver can do about this.
|
||||
|
||||
<H2>Full-screen mode doesn't work</H2>
|
||||
|
||||
Some X servers on Linux PPC don't support DGA and full-screen mode cannot be used
|
||||
with these (in this case, you should disable it in the "Graphics" settings). If you
|
||||
are seeing a message like "cannot map /dev/kmem (permission denied)", you have to
|
||||
either run SheepShaver as root (not recommended) or give yourself appropriate access
|
||||
rights to /dev/kmem if you can login as root.
|
||||
|
||||
<H2>Ethernet doesn't work</H2>
|
||||
|
||||
<UL>
|
||||
<LI>You have to either install the sheep_net driver or configure the ethertap device in the Linux kernel to use Ethernet. See <A HREF="using.html">Using SheepShaver</A> for more information.
|
||||
<LI>If you're using TCP/IP on the MacOS side, you have to set up different IP addresses for Linux and for the MacOS.
|
||||
</UL>
|
||||
|
||||
<H2>SheepShaver crashes, but yesterday it worked</H2>
|
||||
|
||||
Try the "Zap PRAM File" item in the main menu of the SheepShaver preferences editor.
|
||||
When you are using a ROM file and switching to a different ROM version, you <B>have</B>
|
||||
to zap the PRAM file or SheepShaver might behave very weird.
|
||||
|
||||
<H2>Known incompatibilities</H2>
|
||||
|
||||
<UL>
|
||||
<LI>MacOS programs or drivers which access Mac hardware directly are not supported by SheepShaver.
|
||||
<LI>Speed Doubler, RAM Doubler, 68k FPU emulators and similar programs don't run under SheepShaver.
|
||||
<LI>MacsBug is not compatible with SheepShaver.
|
||||
</UL>
|
||||
|
||||
<H2>Known bugs</H2>
|
||||
|
||||
<UL>
|
||||
<LI>The QuickTime 2.5 Cinepak codec crashes the emulator.
|
||||
<LI>Programs that use InputSprockets crash the emulator when in window mode.
|
||||
<LI>The mouse cursor hotspot in window mode is not correct.
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
113
SheepShaver/doc/Linux/using.html
Normal file
@ -0,0 +1,113 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Using SheepShaver</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
|
||||
<H1>Using SheepShaver</H1>
|
||||
|
||||
<H2>Changing the display mode</H2>
|
||||
|
||||
SheepShaver can display the MacOS user interface in an X11 window or full-screen
|
||||
(much faster). You select the display mode as usual under MacOS in the "Monitors"
|
||||
control panel (under System 7.x, click on "Options"). The "75Hz" modes are full-screen
|
||||
modes, the "60Hz" modes are window modes (this doesn't mean that the video refresh
|
||||
rate is 75 or 60Hz in the respective modes; the rate displayed has no meaning; it's
|
||||
simply there to distinguish full screen modes from window modes).
|
||||
|
||||
<H2>Full-screen mode</H2>
|
||||
|
||||
The full-screen mode uses the whole X11 screen for displaying the MacOS user interface.
|
||||
You can temporarily switch back to the X11 desktop by pressing Ctrl-Tab. The MacOS (and
|
||||
all MacOS applications) will now be suspended. You can resume SheepShaver by activating
|
||||
the "SheepShaver suspended" window and pressing the space key. Using full-screen mode
|
||||
requires a DGA capable X server.
|
||||
|
||||
<H2>Networking</H2>
|
||||
|
||||
There are three approaches to networking with SheepShaver:
|
||||
|
||||
<OL>
|
||||
<LI>Direct access to an Ethernet card via the "sheep_net" driver.
|
||||
In this case, the "ethernet card description" must be the name
|
||||
of a real Ethernet card, e.g. "eth0". It also requires the "sheep_net"
|
||||
driver to be installed and accessible. This approach will allow you
|
||||
to run all networking protocols under MacOS (TCP/IP, AppleTalk, IPX
|
||||
etc.) but there is no connection between Linux networking and MacOS
|
||||
networking. MacOS will only be able to talk to other machines on
|
||||
the Ethernet, but not to other networks that your Linux box routes
|
||||
(e.g. a second Ethernet or a PPP connection to the Internet).
|
||||
|
||||
<LI>Putting SheepShaver on a virtual Ethernet via the "ethertap" device.
|
||||
In this case, the "ethernet card description" must be the name
|
||||
of an ethertap interface, e.g. "tap0". It also requires that you
|
||||
configure your kernel to enable routing and the ethertap device:
|
||||
under "Networking options", enable "Kernel/User netlink socket" and
|
||||
"Netlink device emulation", under "Network device support", activate
|
||||
"Ethertap network tap". You also have to modify <CODE>devices/net/ethertap.c</CODE>
|
||||
a bit before compiling the new kernel:
|
||||
|
||||
<UL>
|
||||
<LI>insert <CODE>#define CONFIG_ETHERTAP_MC 1</CODE> near the top (after the <CODE>#include</CODE> lines)
|
||||
<LI>comment out the line <CODE>dev->flags|=IFF_NOARP;</CODE> in <CODE>ethertap_probe()</CODE>
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
Next, see <CODE>/usr/src/linux/Documentation/networking/ethertap.txt</CODE> for
|
||||
information on how to set up <CODE>/dev/tap*</CODE> device nodes and activate the
|
||||
ethertap interface. Under MacOS, select an IP address that is on the
|
||||
virtual network and set the default gateway to the IP address of the
|
||||
ethertap interface. This approach will let you access all networks
|
||||
that your Linux box has access to (especially, if your Linux box has
|
||||
a dial-up Internet connection and is configured for IP masquerading,
|
||||
you can access the Internet from MacOS). The drawback is that you
|
||||
can only use network protocols that Linux can route, so you have to
|
||||
install and configure netatalk if you want to use AppleTalk. Here is
|
||||
an example <CODE>/etc/atalk/atalkd.conf</CODE> for a LAN:
|
||||
|
||||
<PRE>
|
||||
eth0 -seed -phase 2 -net 1 -addr 1.47 -zone "Ethernet"
|
||||
tap0 -seed -phase 2 -net 2 -addr 2.47 -zone "Sheepnet"
|
||||
</PRE>
|
||||
|
||||
(the "47" is an arbitrary node number). This will set up a zone
|
||||
"Ethernet" (net 1) for the Ethernet and a zone "Sheepnet" (net 2)
|
||||
for the internal network connection of the ethertap interface.
|
||||
MacOS should automatically recognize the nets and zones upon startup.
|
||||
If you are in an existing AppleTalk network, you should contact
|
||||
your network administrator about the nets and zones you can use
|
||||
(instead of the ones given in the example above).
|
||||
|
||||
<LI>Networking protocols for serial connections (PPP and SLIP, for example)
|
||||
can be used provided that you have the appropriate MacOS system components
|
||||
installed (e.g. Open Transport/PPP).
|
||||
</OL>
|
||||
|
||||
<H2>Using floppy disks</H2>
|
||||
|
||||
Floppy disks are not automatically detected when they are inserted. They have to be
|
||||
mounted explicitly: after inserting a floppy disk, press Ctrl-F1.
|
||||
|
||||
<H2>Accessing Linux files</H2>
|
||||
|
||||
SheepShaver will display a "Linux" disk icon on the Mac desktop that allows you
|
||||
to access any Linux files which are in the directory specified as "Linux Root"
|
||||
in the "Volumes" pane of the SheepShaver settings. You can open and save files on the
|
||||
"Linux" disk from Mac applications, copy, move or rename files from the Finder etc.
|
||||
SheepShaver translates some file name extensions to MacOS types and vice versa,
|
||||
so e.g. *.jpg and *.pdf files will show the correct icons in the Finder. MacOS
|
||||
resources and Finder attributes are stored in hidden <CODE>.rsrc</CODE> and
|
||||
<CODE>.finf</CODE> directories.
|
||||
|
||||
<H2>Copying text via the clipboard</H2>
|
||||
|
||||
SheepShaver tries to keep the Linux and MacOS clipboards synchronized. That means,
|
||||
when you copy a piece of text under Linux, you can paste it into a MacOS application
|
||||
and vice versa.
|
||||
|
||||
<HR>
|
||||
<ADDRESS>
|
||||
SheepShaver User's Guide
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
BIN
SheepShaver/doc/Linux/volumes.gif
Normal file
After Width: | Height: | Size: 7.5 KiB |
255
SheepShaver/src/BeOS/CreatePCIDrivers/Ethernet.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Ethernet.cpp - SheepShaver ethernet PCI driver stub
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "xlowmem.h"
|
||||
#include "ether_defs.h"
|
||||
|
||||
|
||||
/*
|
||||
* Driver Description structure
|
||||
*/
|
||||
|
||||
struct DriverDescription {
|
||||
uint32 driverDescSignature;
|
||||
uint32 driverDescVersion;
|
||||
char nameInfoStr[32];
|
||||
uint32 version;
|
||||
uint32 driverRuntime;
|
||||
char driverName[32];
|
||||
uint32 driverDescReserved[8];
|
||||
uint32 nServices;
|
||||
uint32 serviceCategory;
|
||||
uint32 serviceType;
|
||||
uint32 serviceVersion;
|
||||
};
|
||||
|
||||
#pragma export on
|
||||
DriverDescription TheDriverDescription = {
|
||||
'mtej',
|
||||
0,
|
||||
"\pSheepShaver Ethernet",
|
||||
0x01008000, // V1.0.0final
|
||||
4, // kDriverIsUnderExpertControl
|
||||
"\penet",
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1,
|
||||
'otan',
|
||||
0x000a0b01, // Ethernet, Framing: Ethernet/EthernetIPX/802.2, IsDLPI
|
||||
0x01000000, // V1.0.0
|
||||
};
|
||||
#pragma export off
|
||||
|
||||
|
||||
/*
|
||||
* install_info and related structures
|
||||
*/
|
||||
|
||||
static int ether_open(queue_t *rdq, void *dev, int flag, int sflag, void *creds);
|
||||
static int ether_close(queue_t *rdq, int flag, void *creds);
|
||||
static int ether_wput(queue_t *q, msgb *mp);
|
||||
static int ether_wsrv(queue_t *q);
|
||||
static int ether_rput(queue_t *q, msgb *mp);
|
||||
static int ether_rsrv(queue_t *q);
|
||||
|
||||
struct ot_module_info {
|
||||
uint16 mi_idnum;
|
||||
char *mi_idname;
|
||||
int32 mi_minpsz; // Minimum packet size
|
||||
int32 mi_maxpsz; // Maximum packet size
|
||||
uint32 mi_hiwat; // Queue hi-water mark
|
||||
uint32 mi_lowat; // Queue lo-water mark
|
||||
};
|
||||
|
||||
static ot_module_info module_information = {
|
||||
kEnetModuleID,
|
||||
"SheepShaver Ethernet",
|
||||
0,
|
||||
kEnetTSDU,
|
||||
6000,
|
||||
5000
|
||||
};
|
||||
|
||||
typedef int (*putp_t)(queue_t *, msgb *);
|
||||
typedef int (*srvp_t)(queue_t *);
|
||||
typedef int (*openp_t)(queue_t *, void *, int, int, void *);
|
||||
typedef int (*closep_t)(queue_t *, int, void *);
|
||||
|
||||
struct qinit {
|
||||
putp_t qi_putp;
|
||||
srvp_t qi_srvp;
|
||||
openp_t qi_qopen;
|
||||
closep_t qi_qclose;
|
||||
void *qi_qadmin;
|
||||
struct ot_module_info *qi_minfo;
|
||||
void *qi_mstat;
|
||||
};
|
||||
|
||||
static qinit read_side = {
|
||||
NULL,
|
||||
ether_rsrv,
|
||||
ether_open,
|
||||
ether_close,
|
||||
NULL,
|
||||
&module_information,
|
||||
NULL
|
||||
};
|
||||
|
||||
static qinit write_side = {
|
||||
ether_wput,
|
||||
NULL,
|
||||
ether_open,
|
||||
ether_close,
|
||||
NULL,
|
||||
&module_information,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct streamtab {
|
||||
struct qinit *st_rdinit;
|
||||
struct qinit *st_wrinit;
|
||||
struct qinit *st_muxrinit;
|
||||
struct qinit *st_muxwinit;
|
||||
};
|
||||
|
||||
static streamtab the_streamtab = {
|
||||
&read_side,
|
||||
&write_side,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct install_info {
|
||||
struct streamtab *install_str;
|
||||
uint32 install_flags;
|
||||
uint32 install_sqlvl;
|
||||
char *install_buddy;
|
||||
void *ref_load;
|
||||
uint32 ref_count;
|
||||
};
|
||||
|
||||
enum {
|
||||
kOTModIsDriver = 0x00000001,
|
||||
kOTModUpperIsDLPI = 0x00002000,
|
||||
SQLVL_MODULE = 3,
|
||||
};
|
||||
|
||||
static install_info the_install_info = {
|
||||
&the_streamtab,
|
||||
kOTModIsDriver /*| kOTModUpperIsDLPI */,
|
||||
SQLVL_MODULE,
|
||||
NULL,
|
||||
NULL,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
// Prototypes for exported functions
|
||||
extern "C" {
|
||||
#pragma export on
|
||||
extern uint32 ValidateHardware(void *theID);
|
||||
extern install_info* GetOTInstallInfo();
|
||||
extern uint8 InitStreamModule(void *theID);
|
||||
extern void TerminateStreamModule(void);
|
||||
#pragma export off
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Validate that our hardware is available (always available)
|
||||
*/
|
||||
|
||||
uint32 ValidateHardware(void *theID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return pointer to install_info structure
|
||||
*/
|
||||
|
||||
install_info *GetOTInstallInfo(void)
|
||||
{
|
||||
return &the_install_info;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Init module
|
||||
*/
|
||||
|
||||
asm uint8 InitStreamModule(register void *theID)
|
||||
{
|
||||
lwz r2,XLM_TOC
|
||||
lwz r0,XLM_ETHER_INIT
|
||||
mtctr r0
|
||||
bctr
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Terminate module
|
||||
*/
|
||||
|
||||
asm void TerminateStreamModule(void)
|
||||
{
|
||||
lwz r2,XLM_TOC
|
||||
lwz r0,XLM_ETHER_TERM
|
||||
mtctr r0
|
||||
bctr
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DLPI functions
|
||||
*/
|
||||
|
||||
static asm int ether_open(register queue_t *rdq, register void *dev, register int flag, register int sflag, register void *creds)
|
||||
{
|
||||
lwz r2,XLM_TOC
|
||||
lwz r0,XLM_ETHER_OPEN
|
||||
mtctr r0
|
||||
bctr
|
||||
}
|
||||
|
||||
static asm int ether_close(register queue_t *rdq, register int flag, register void *creds)
|
||||
{
|
||||
lwz r2,XLM_TOC
|
||||
lwz r0,XLM_ETHER_CLOSE
|
||||
mtctr r0
|
||||
bctr
|
||||
}
|
||||
|
||||
static asm int ether_wput(register queue_t *q, register msgb *mp)
|
||||
{
|
||||
lwz r2,XLM_TOC
|
||||
lwz r0,XLM_ETHER_WPUT
|
||||
mtctr r0
|
||||
bctr
|
||||
}
|
||||
|
||||
static asm int ether_rsrv(register queue_t *q)
|
||||
{
|
||||
lwz r2,XLM_TOC
|
||||
lwz r0,XLM_ETHER_RSRV
|
||||
mtctr r0
|
||||
bctr
|
||||
}
|
25
SheepShaver/src/BeOS/CreatePCIDrivers/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
all: ../../EthernetDriverStub.i ../../VideoDriverStub.i
|
||||
|
||||
clean:
|
||||
-rm *.o hexconv Ethernet Video
|
||||
|
||||
../../EthernetDriverStub.i: Ethernet hexconv
|
||||
hexconv $< $@
|
||||
|
||||
../../VideoDriverStub.i: Video hexconv
|
||||
hexconv $< $@
|
||||
|
||||
hexconv: hexconv.cpp
|
||||
mwcc -o hexconv hexconv.cpp
|
||||
|
||||
Ethernet.o: Ethernet.cpp
|
||||
mwcc -I.. -I../../include -o $@ -c $<
|
||||
|
||||
Video.o: Video.cpp
|
||||
mwcc -I.. -I../../include -o $@ -c $<
|
||||
|
||||
Ethernet: Ethernet.o
|
||||
mwldppc -xms -export pragma -nostdentry -nostdlib -o $@ $<
|
||||
|
||||
Video: Video.o
|
||||
mwldppc -xms -export pragma -nostdentry -nostdlib -o $@ $<
|
78
SheepShaver/src/BeOS/CreatePCIDrivers/Video.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Video.cpp - SheepShaver video PCI driver stub
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "xlowmem.h"
|
||||
|
||||
|
||||
/*
|
||||
* Driver Description structure
|
||||
*/
|
||||
|
||||
struct DriverDescription {
|
||||
uint32 driverDescSignature;
|
||||
uint32 driverDescVersion;
|
||||
char nameInfoStr[32];
|
||||
uint32 version;
|
||||
uint32 driverRuntime;
|
||||
char driverName[32];
|
||||
uint32 driverDescReserved[8];
|
||||
uint32 nServices;
|
||||
uint32 serviceCategory;
|
||||
uint32 serviceType;
|
||||
uint32 serviceVersion;
|
||||
};
|
||||
|
||||
#pragma export on
|
||||
struct DriverDescription TheDriverDescription = {
|
||||
'mtej',
|
||||
0,
|
||||
"\pvideo",
|
||||
0x01008000, // V1.0.0final
|
||||
6, // kDriverIsUnderExpertControl, kDriverIsOpenedUponLoad
|
||||
"\pDisplay_Video_Apple_Sheep",
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1,
|
||||
'ndrv',
|
||||
'vido',
|
||||
0x01000000, // V1.0.0
|
||||
};
|
||||
#pragma export off
|
||||
|
||||
|
||||
// Prototypes for exported functions
|
||||
extern "C" {
|
||||
#pragma export on
|
||||
extern int16 DoDriverIO(void *spaceID, void *commandID, void *commandContents, uint32 commandCode, uint32 commandKind);
|
||||
#pragma export off
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Do driver IO
|
||||
*/
|
||||
|
||||
asm int16 DoDriverIO(void *spaceID, void *commandID, void *commandContents, uint32 commandCode, uint32 commandKind)
|
||||
{
|
||||
lwz r2,XLM_TOC
|
||||
lwz r0,XLM_VIDEO_DOIO
|
||||
mtctr r0
|
||||
bctr
|
||||
}
|
34
SheepShaver/src/BeOS/CreatePCIDrivers/hexconv.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
printf("Usage: %s <raw file> <C source>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fin = fopen(argv[1], "rb");
|
||||
if (fin == NULL) {
|
||||
printf("Can't open '%s' for reading\n", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fout = fopen(argv[2], "w");
|
||||
if (fout == NULL) {
|
||||
printf("Can't open '%s' for writing\n", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char buf[16];
|
||||
while (!feof(fin)) {
|
||||
fprintf(fout, "\t");
|
||||
int actual = fread(buf, 1, 16, fin);
|
||||
for (int i=0; i<actual; i++)
|
||||
fprintf(fout, "0x%02x, ", buf[i]);
|
||||
fprintf(fout, "\n");
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 0;
|
||||
}
|
117
SheepShaver/src/BeOS/Makefile
Normal file
@ -0,0 +1,117 @@
|
||||
## BeOS Generic Makefile v2.1 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
## makefile-engine will do all of the hard work for you. This handles both
|
||||
## Intel and PowerPC builds of the BeOS.
|
||||
|
||||
## Application Specific Settings ---------------------------------------------
|
||||
|
||||
# specify the name of the binary
|
||||
NAME= SheepShaver
|
||||
|
||||
# specify the type of binary
|
||||
# APP: Application
|
||||
# SHARED: Shared library or add-on
|
||||
# STATIC: Static library archive
|
||||
# DRIVER: Kernel Driver
|
||||
TYPE= APP
|
||||
|
||||
# add support for new Pe and Eddie features
|
||||
# to fill in generic makefile
|
||||
|
||||
#%{
|
||||
# @src->@
|
||||
|
||||
# specify the source files to use
|
||||
# full paths or paths relative to the makefile can be included
|
||||
# all files, regardless of directory, will have their object
|
||||
# files created in the common object directory.
|
||||
# Note that this means this makefile will not work correctly
|
||||
# if two source files with the same name (source.c or source.cpp)
|
||||
# are included from different directories. Also note that spaces
|
||||
# in folder names do not work well with this makefile.
|
||||
SRCS= main_beos.cpp ../prefs.cpp ../prefs_items.cpp prefs_beos.cpp \
|
||||
prefs_editor_beos.cpp sys_beos.cpp ../rom_patches.cpp ../rsrc_patches.cpp \
|
||||
../emul_op.cpp ../name_registry.cpp ../macos_util.cpp ../timer.cpp \
|
||||
timer_beos.cpp ../xpram.cpp xpram_beos.cpp ../adb.cpp clip_beos.cpp \
|
||||
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp scsi_beos.cpp \
|
||||
../video.cpp video_beos.cpp ../audio.cpp audio_beos.cpp ../ether.cpp \
|
||||
ether_beos.cpp ../serial.cpp serial_beos.cpp ../extfs.cpp extfs_beos.cpp \
|
||||
about_window_beos.cpp ../user_strings.cpp user_strings_beos.cpp
|
||||
|
||||
# specify the resource files to use
|
||||
# full path or a relative path to the resource file can be used.
|
||||
RSRCS= SheepShaver.rsrc
|
||||
|
||||
# @<-src@
|
||||
#%}
|
||||
|
||||
# end support for Pe and Eddie
|
||||
|
||||
# specify additional libraries to link against
|
||||
# there are two acceptable forms of library specifications
|
||||
# - if your library follows the naming pattern of:
|
||||
# libXXX.so or libXXX.a you can simply specify XXX
|
||||
# library: libbe.so entry: be
|
||||
#
|
||||
# - if your library does not follow the standard library
|
||||
# naming scheme you need to specify the path to the library
|
||||
# and it's name
|
||||
# library: my_lib.a entry: my_lib.a or path/my_lib.a
|
||||
LIBS= be tracker game media translation textencoding device GL
|
||||
|
||||
# specify additional paths to directories following the standard
|
||||
# libXXX.so or libXXX.a naming scheme. You can specify full paths
|
||||
# or paths relative to the makefile. The paths included may not
|
||||
# be recursive, so include all of the paths where libraries can
|
||||
# be found. Directories where source files are found are
|
||||
# automatically included.
|
||||
LIBPATHS=
|
||||
|
||||
# additional paths to look for system headers
|
||||
# thes use the form: #include <header>
|
||||
# source file directories are NOT auto-included here
|
||||
SYSTEM_INCLUDE_PATHS =
|
||||
|
||||
# additional paths to look for local headers
|
||||
# thes use the form: #include "header"
|
||||
# source file directories are automatically included
|
||||
LOCAL_INCLUDE_PATHS = ../include SheepDriver SheepNet
|
||||
|
||||
# specify the level of optimization that you desire
|
||||
# NONE, SOME, FULL
|
||||
OPTIMIZE= FULL
|
||||
|
||||
# specify any preprocessor symbols to be defined. The symbols will not
|
||||
# have their values set automatically; you must supply the value (if any)
|
||||
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
|
||||
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
|
||||
# would pass "-DDEBUG" on the compiler's command line.
|
||||
DEFINES=
|
||||
|
||||
# specify special warning levels
|
||||
# if unspecified default warnings will be used
|
||||
# NONE = supress all warnings
|
||||
# ALL = enable all warnings
|
||||
WARNINGS =
|
||||
|
||||
# specify whether image symbols will be created
|
||||
# so that stack crawls in the debugger are meaningful
|
||||
# if TRUE symbols will be created
|
||||
SYMBOLS =
|
||||
|
||||
# specify debug settings
|
||||
# if TRUE will allow application to be run from a source-level
|
||||
# debugger. Note that this will disable all optimzation.
|
||||
DEBUGGER =
|
||||
|
||||
# specify additional compiler flags for all files
|
||||
COMPILER_FLAGS = -prefix BeHeaders
|
||||
|
||||
# specify additional linker flags
|
||||
LINKER_FLAGS =
|
||||
|
||||
|
||||
## include the makefile-engine
|
||||
include /boot/develop/etc/makefile-engine
|
||||
|
110
SheepShaver/src/BeOS/NetPeek/Makefile
Normal file
@ -0,0 +1,110 @@
|
||||
## BeOS Generic Makefile v2.1 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
## makefile-engine will do all of the hard work for you. This handles both
|
||||
## Intel and PowerPC builds of the BeOS.
|
||||
|
||||
## Application Specific Settings ---------------------------------------------
|
||||
|
||||
# specify the name of the binary
|
||||
NAME= NetPeek
|
||||
|
||||
# specify the type of binary
|
||||
# APP: Application
|
||||
# SHARED: Shared library or add-on
|
||||
# STATIC: Static library archive
|
||||
# DRIVER: Kernel Driver
|
||||
TYPE= APP
|
||||
|
||||
# add support for new Pe and Eddie features
|
||||
# to fill in generic makefile
|
||||
|
||||
#%{
|
||||
# @src->@
|
||||
|
||||
# specify the source files to use
|
||||
# full paths or paths relative to the makefile can be included
|
||||
# all files, regardless of directory, will have their object
|
||||
# files created in the common object directory.
|
||||
# Note that this means this makefile will not work correctly
|
||||
# if two source files with the same name (source.c or source.cpp)
|
||||
# are included from different directories. Also note that spaces
|
||||
# in folder names do not work well with this makefile.
|
||||
SRCS= NetPeek.cpp
|
||||
|
||||
# specify the resource files to use
|
||||
# full path or a relative path to the resource file can be used.
|
||||
RSRCS=
|
||||
|
||||
# @<-src@
|
||||
#%}
|
||||
|
||||
# end support for Pe and Eddie
|
||||
|
||||
# specify additional libraries to link against
|
||||
# there are two acceptable forms of library specifications
|
||||
# - if your library follows the naming pattern of:
|
||||
# libXXX.so or libXXX.a you can simply specify XXX
|
||||
# library: libbe.so entry: be
|
||||
#
|
||||
# - if your library does not follow the standard library
|
||||
# naming scheme you need to specify the path to the library
|
||||
# and it's name
|
||||
# library: my_lib.a entry: my_lib.a or path/my_lib.a
|
||||
LIBS=
|
||||
|
||||
# specify additional paths to directories following the standard
|
||||
# libXXX.so or libXXX.a naming scheme. You can specify full paths
|
||||
# or paths relative to the makefile. The paths included may not
|
||||
# be recursive, so include all of the paths where libraries can
|
||||
# be found. Directories where source files are found are
|
||||
# automatically included.
|
||||
LIBPATHS=
|
||||
|
||||
# additional paths to look for system headers
|
||||
# thes use the form: #include <header>
|
||||
# source file directories are NOT auto-included here
|
||||
SYSTEM_INCLUDE_PATHS =
|
||||
|
||||
# additional paths to look for local headers
|
||||
# thes use the form: #include "header"
|
||||
# source file directories are automatically included
|
||||
LOCAL_INCLUDE_PATHS = ../ ../../include ../NetAddOn
|
||||
|
||||
# specify the level of optimization that you desire
|
||||
# NONE, SOME, FULL
|
||||
OPTIMIZE= FULL
|
||||
|
||||
# specify any preprocessor symbols to be defined. The symbols will not
|
||||
# have their values set automatically; you must supply the value (if any)
|
||||
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
|
||||
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
|
||||
# would pass "-DDEBUG" on the compiler's command line.
|
||||
DEFINES=
|
||||
|
||||
# specify special warning levels
|
||||
# if unspecified default warnings will be used
|
||||
# NONE = supress all warnings
|
||||
# ALL = enable all warnings
|
||||
WARNINGS =
|
||||
|
||||
# specify whether image symbols will be created
|
||||
# so that stack crawls in the debugger are meaningful
|
||||
# if TRUE symbols will be created
|
||||
SYMBOLS =
|
||||
|
||||
# specify debug settings
|
||||
# if TRUE will allow application to be run from a source-level
|
||||
# debugger. Note that this will disable all optimzation.
|
||||
DEBUGGER =
|
||||
|
||||
# specify additional compiler flags for all files
|
||||
COMPILER_FLAGS =
|
||||
|
||||
# specify additional linker flags
|
||||
LINKER_FLAGS =
|
||||
|
||||
|
||||
## include the makefile-engine
|
||||
include /boot/develop/etc/makefile-engine
|
||||
|
49
SheepShaver/src/BeOS/NetPeek/NetPeek.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* NetPeek.cpp - Utility program for monitoring SheepNet add-on
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "sheep_net.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static area_id buffer_area; // Packet buffer area
|
||||
static net_buffer *net_buffer_ptr; // Pointer to packet buffer
|
||||
|
||||
int main(void)
|
||||
{
|
||||
area_id handler_buffer;
|
||||
if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) {
|
||||
printf("Can't find packet buffer\n");
|
||||
return 10;
|
||||
}
|
||||
if ((buffer_area = clone_area("local packet buffer", &net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) {
|
||||
printf("Can't clone packet buffer\n");
|
||||
return 10;
|
||||
}
|
||||
|
||||
uint8 *p = net_buffer_ptr->ether_addr;
|
||||
printf("Ethernet address : %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
printf("read_sem : %d\n", net_buffer_ptr->read_sem);
|
||||
printf("read_ofs : %d\n", net_buffer_ptr->read_ofs);
|
||||
printf("read_packet_size : %d\n", net_buffer_ptr->read_packet_size);
|
||||
printf("read_packet_count : %d\n", net_buffer_ptr->read_packet_count);
|
||||
printf("write_sem : %d\n", net_buffer_ptr->write_sem);
|
||||
printf("write_ofs : %d\n", net_buffer_ptr->write_ofs);
|
||||
printf("write_packet_size : %d\n", net_buffer_ptr->write_packet_size);
|
||||
printf("write_packet_count: %d\n", net_buffer_ptr->write_packet_count);
|
||||
|
||||
printf("\nRead packets:\n");
|
||||
for (int i=0; i<READ_PACKET_COUNT; i++) {
|
||||
net_packet *p = &net_buffer_ptr->read[i];
|
||||
printf("cmd : %08lx\n", p->cmd);
|
||||
printf("length: %d\n", p->length);
|
||||
}
|
||||
printf("\nWrite packets:\n");
|
||||
for (int i=0; i<WRITE_PACKET_COUNT; i++) {
|
||||
net_packet *p = &net_buffer_ptr->write[i];
|
||||
printf("cmd : %08lx\n", p->cmd);
|
||||
printf("length: %d\n", p->length);
|
||||
}
|
||||
return 0;
|
||||
}
|
110
SheepShaver/src/BeOS/SaveROM/Makefile
Normal file
@ -0,0 +1,110 @@
|
||||
## BeOS Generic Makefile v2.1 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
## makefile-engine will do all of the hard work for you. This handles both
|
||||
## Intel and PowerPC builds of the BeOS.
|
||||
|
||||
## Application Specific Settings ---------------------------------------------
|
||||
|
||||
# specify the name of the binary
|
||||
NAME= SaveROM
|
||||
|
||||
# specify the type of binary
|
||||
# APP: Application
|
||||
# SHARED: Shared library or add-on
|
||||
# STATIC: Static library archive
|
||||
# DRIVER: Kernel Driver
|
||||
TYPE= APP
|
||||
|
||||
# add support for new Pe and Eddie features
|
||||
# to fill in generic makefile
|
||||
|
||||
#%{
|
||||
# @src->@
|
||||
|
||||
# specify the source files to use
|
||||
# full paths or paths relative to the makefile can be included
|
||||
# all files, regardless of directory, will have their object
|
||||
# files created in the common object directory.
|
||||
# Note that this means this makefile will not work correctly
|
||||
# if two source files with the same name (source.c or source.cpp)
|
||||
# are included from different directories. Also note that spaces
|
||||
# in folder names do not work well with this makefile.
|
||||
SRCS= SaveROM.cpp
|
||||
|
||||
# specify the resource files to use
|
||||
# full path or a relative path to the resource file can be used.
|
||||
RSRCS= SaveROM.rsrc
|
||||
|
||||
# @<-src@
|
||||
#%}
|
||||
|
||||
# end support for Pe and Eddie
|
||||
|
||||
# specify additional libraries to link against
|
||||
# there are two acceptable forms of library specifications
|
||||
# - if your library follows the naming pattern of:
|
||||
# libXXX.so or libXXX.a you can simply specify XXX
|
||||
# library: libbe.so entry: be
|
||||
#
|
||||
# - if your library does not follow the standard library
|
||||
# naming scheme you need to specify the path to the library
|
||||
# and it's name
|
||||
# library: my_lib.a entry: my_lib.a or path/my_lib.a
|
||||
LIBS= be
|
||||
|
||||
# specify additional paths to directories following the standard
|
||||
# libXXX.so or libXXX.a naming scheme. You can specify full paths
|
||||
# or paths relative to the makefile. The paths included may not
|
||||
# be recursive, so include all of the paths where libraries can
|
||||
# be found. Directories where source files are found are
|
||||
# automatically included.
|
||||
LIBPATHS=
|
||||
|
||||
# additional paths to look for system headers
|
||||
# thes use the form: #include <header>
|
||||
# source file directories are NOT auto-included here
|
||||
SYSTEM_INCLUDE_PATHS =
|
||||
|
||||
# additional paths to look for local headers
|
||||
# thes use the form: #include "header"
|
||||
# source file directories are automatically included
|
||||
LOCAL_INCLUDE_PATHS = ../ ../../include ../NetAddOn
|
||||
|
||||
# specify the level of optimization that you desire
|
||||
# NONE, SOME, FULL
|
||||
OPTIMIZE= FULL
|
||||
|
||||
# specify any preprocessor symbols to be defined. The symbols will not
|
||||
# have their values set automatically; you must supply the value (if any)
|
||||
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
|
||||
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
|
||||
# would pass "-DDEBUG" on the compiler's command line.
|
||||
DEFINES=
|
||||
|
||||
# specify special warning levels
|
||||
# if unspecified default warnings will be used
|
||||
# NONE = supress all warnings
|
||||
# ALL = enable all warnings
|
||||
WARNINGS =
|
||||
|
||||
# specify whether image symbols will be created
|
||||
# so that stack crawls in the debugger are meaningful
|
||||
# if TRUE symbols will be created
|
||||
SYMBOLS =
|
||||
|
||||
# specify debug settings
|
||||
# if TRUE will allow application to be run from a source-level
|
||||
# debugger. Note that this will disable all optimzation.
|
||||
DEBUGGER =
|
||||
|
||||
# specify additional compiler flags for all files
|
||||
COMPILER_FLAGS =
|
||||
|
||||
# specify additional linker flags
|
||||
LINKER_FLAGS =
|
||||
|
||||
|
||||
## include the makefile-engine
|
||||
include /boot/develop/etc/makefile-engine
|
||||
|
8
SheepShaver/src/BeOS/SaveROM/README
Normal file
@ -0,0 +1,8 @@
|
||||
"SaveROM" is a program that allows you to save the ROM of
|
||||
a PowerMac running under BeOS to a file.
|
||||
|
||||
1. Copy "sheep_driver" to ~/config/add-ons/kernel/drivers.
|
||||
2. Double-click the "SaveROM" icon.
|
||||
|
||||
This will create a file called "ROM" which should be 4MB
|
||||
in size.
|
128
SheepShaver/src/BeOS/SaveROM/SaveROM.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* SaveROM - Save Mac ROM to file
|
||||
*
|
||||
* Copyright (C) 1998-2002 Christian Bauer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <AppKit.h>
|
||||
#include <InterfaceKit.h>
|
||||
#include <StorageKit.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
// Constants
|
||||
const char APP_SIGNATURE[] = "application/x-vnd.cebix-SaveROM";
|
||||
const char ROM_FILE_NAME[] = "ROM";
|
||||
|
||||
// Global variables
|
||||
static uint8 buf[0x400000];
|
||||
|
||||
// Application object
|
||||
class SaveROM : public BApplication {
|
||||
public:
|
||||
SaveROM() : BApplication(APP_SIGNATURE)
|
||||
{
|
||||
// Find application directory and cwd to it
|
||||
app_info the_info;
|
||||
GetAppInfo(&the_info);
|
||||
BEntry the_file(&the_info.ref);
|
||||
BEntry the_dir;
|
||||
the_file.GetParent(&the_dir);
|
||||
BPath the_path;
|
||||
the_dir.GetPath(&the_path);
|
||||
chdir(the_path.Path());
|
||||
}
|
||||
virtual void ReadyToRun(void);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Create application object and start it
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SaveROM *the_app = new SaveROM();
|
||||
the_app->Run();
|
||||
delete the_app;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display error alert
|
||||
*/
|
||||
|
||||
static void ErrorAlert(const char *text)
|
||||
{
|
||||
BAlert *alert = new BAlert("SaveROM Error", text, "Quit", NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
|
||||
alert->Go();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display OK alert
|
||||
*/
|
||||
|
||||
static void InfoAlert(const char *text)
|
||||
{
|
||||
BAlert *alert = new BAlert("SaveROM Message", text, "Quit", NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT);
|
||||
alert->Go();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main program
|
||||
*/
|
||||
|
||||
void SaveROM::ReadyToRun(void)
|
||||
{
|
||||
int fd = open("/dev/sheep", 0);
|
||||
if (fd < 0) {
|
||||
ErrorAlert("Cannot open '/dev/sheep'.");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (read(fd, buf, 0x400000) != 0x400000) {
|
||||
ErrorAlert("Cannot read ROM.");
|
||||
close(fd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
FILE *f = fopen(ROM_FILE_NAME, "wb");
|
||||
if (f == NULL) {
|
||||
ErrorAlert("Cannot open ROM file.");
|
||||
close(fd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (fwrite(buf, 1, 0x400000, f) != 0x400000) {
|
||||
ErrorAlert("Cannot write ROM.");
|
||||
fclose(f);
|
||||
close(fd);
|
||||
goto done;
|
||||
}
|
||||
|
||||
InfoAlert("ROM saved.");
|
||||
|
||||
fclose(f);
|
||||
close(fd);
|
||||
done:
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
BIN
SheepShaver/src/BeOS/SaveROM/SaveROM.rsrc
Normal file
BIN
SheepShaver/src/BeOS/SheepShaver.rsrc
Normal file
289
SheepShaver/src/BeOS/about_window_beos.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* about_window_beos.cpp - "About" window, BeOS implementation
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <GLView.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "about_window.h"
|
||||
#include "video.h"
|
||||
#include "version.h"
|
||||
#include "user_strings.h"
|
||||
|
||||
|
||||
// About window dimensions
|
||||
static const BRect about_frame = BRect(0, 0, 383, 99);
|
||||
|
||||
// Special colors
|
||||
const rgb_color fill_color = {216, 216, 216, 0};
|
||||
|
||||
// SheepShaver icon
|
||||
static const uint8 sheep_icon[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xda, 0x15, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xff, 0x00, 0x00, 0x00, 0x16, 0xda, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16,
|
||||
0x00, 0x1d, 0xda, 0x1e, 0x1e, 0x1e, 0xda, 0x16, 0x00, 0x00, 0x16, 0xda, 0x16, 0xda, 0x08, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x00, 0x0b, 0xff, 0xff, 0x11, 0x00, 0xda,
|
||||
0x1d, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0x16, 0x00, 0x00, 0x0c, 0xff, 0xff, 0xff,
|
||||
0xff, 0x0b, 0x00, 0x00, 0x16, 0x16, 0x00, 0x12, 0xfd, 0x1d, 0x0b, 0x00, 0x00, 0x1d, 0xfd, 0x1d,
|
||||
0xfd, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x3f, 0xda, 0x3f, 0xda, 0x15, 0x00, 0xff, 0xff, 0xff,
|
||||
0x16, 0x00, 0x17, 0x16, 0x00, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x16, 0x0f, 0x0b, 0x1d,
|
||||
0x1e, 0xfd, 0x1e, 0xda, 0x1e, 0xda, 0x3f, 0xda, 0x3f, 0xda, 0x1d, 0x5a, 0x15, 0xff, 0xff, 0xff,
|
||||
0x05, 0x17, 0x16, 0x00, 0x12, 0x1d, 0x00, 0x1d, 0xfd, 0x00, 0xfd, 0x00, 0x00, 0x16, 0x0b, 0x00,
|
||||
0x00, 0x0e, 0x1d, 0x3f, 0xda, 0x3f, 0xda, 0x1d, 0xda, 0x1b, 0x5a, 0x1b, 0x0f, 0x1d, 0xff, 0xff,
|
||||
0xff, 0x05, 0x00, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x00, 0x0f, 0x14, 0x14,
|
||||
0x16, 0x00, 0x15, 0xfd, 0x1d, 0xda, 0x1b, 0xda, 0x1b, 0x5a, 0x1b, 0x5a, 0x0f, 0x14, 0xff, 0xff,
|
||||
0xff, 0xff, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x12, 0x00, 0x16, 0x00, 0x0f,
|
||||
0x00, 0x1b, 0xfd, 0x1e, 0xfd, 0x1b, 0xda, 0x1b, 0x5a, 0x1b, 0x5a, 0x1b, 0x5a, 0x14, 0xff, 0xff,
|
||||
0xff, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x12, 0x00, 0x16, 0x1b, 0x16, 0x0e,
|
||||
0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0x5a, 0x18, 0x00, 0x00, 0x5a, 0x1b, 0x00, 0xff, 0xff,
|
||||
0xff, 0x00, 0xfd, 0x14, 0xfd, 0x14, 0xfd, 0x1d, 0xfd, 0x12, 0x00, 0x16, 0xfd, 0x1b, 0xfd, 0x1b,
|
||||
0xfd, 0x1b, 0xfd, 0x1e, 0xfd, 0x1b, 0x5a, 0x18, 0x5a, 0x00, 0x00, 0x1b, 0x9b, 0x00, 0xff, 0xff,
|
||||
0xff, 0x00, 0x0f, 0xfd, 0x1d, 0xfd, 0x0f, 0xfd, 0x12, 0x00, 0x16, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd,
|
||||
0x1b, 0xfd, 0x18, 0xfd, 0x1b, 0xf9, 0x18, 0x5a, 0x00, 0x12, 0x00, 0x9b, 0x1b, 0x00, 0xff, 0xff,
|
||||
0xff, 0x00, 0xfd, 0x0a, 0x0a, 0x0a, 0xfd, 0x10, 0x00, 0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd, 0x18,
|
||||
0xfd, 0x15, 0xfa, 0x15, 0xf9, 0x18, 0x15, 0x00, 0x12, 0x9b, 0x00, 0x1b, 0x9b, 0x00, 0x15, 0x15,
|
||||
0xff, 0xff, 0x00, 0xfd, 0x1d, 0xfd, 0x1d, 0x00, 0x16, 0x00, 0x1b, 0xfd, 0x1b, 0xfd, 0x15, 0xfd,
|
||||
0x15, 0xfa, 0x15, 0xf9, 0x15, 0x16, 0x00, 0x0f, 0x9b, 0x12, 0x00, 0x9b, 0x1b, 0x00, 0x15, 0x15,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x1d, 0x00, 0xfa, 0x1e, 0x00, 0x1e, 0xfa, 0x15,
|
||||
0xfa, 0x15, 0x16, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x12, 0x15, 0x15,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1d, 0xf9, 0x00, 0x3f, 0xfa, 0x00, 0xfa, 0x1b, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x12, 0x15, 0x15, 0x15, 0x15,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf9, 0x1d, 0x00, 0xf9, 0x1b, 0x00, 0x1b, 0xf9, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1d, 0xf9, 0x00, 0x3f, 0xf9, 0x00, 0xf9, 0x1b, 0x00,
|
||||
0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x16, 0x1d, 0x00, 0xf9, 0x1b, 0x00, 0x1b, 0xf9, 0x00,
|
||||
0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x00, 0x16, 0xf9, 0x00, 0x1b, 0x16, 0x00,
|
||||
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00, 0x12, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
|
||||
0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x15, 0x00, 0x0a, 0x19, 0x0a, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x12, 0x00, 0x00, 0x00, 0x16, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x19, 0x1c, 0x18, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
|
||||
0x0f, 0xff, 0xff, 0xff, 0x00, 0x18, 0x11, 0x00, 0x15, 0x00, 0x1c, 0x18, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0x00, 0x00, 0x0b, 0x0b,
|
||||
0x00, 0x00, 0x0f, 0xff, 0x12, 0x00, 0x18, 0x19, 0x00, 0x15, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0x00, 0x14, 0x1e, 0xfd, 0x01, 0xfd, 0x14,
|
||||
0xfa, 0xf9, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x19, 0x1c, 0x00, 0x18, 0x1c, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0xfd, 0x1e, 0xf9, 0x1e, 0xfa, 0x1e, 0xf9,
|
||||
0x14, 0xfa, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x18, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0x1e, 0xf9, 0x14, 0xfa, 0x1e, 0xf9, 0x1e,
|
||||
0xfd, 0x1e, 0x00, 0x15, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x00, 0x00, 0x18, 0x00, 0x1c, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0xfd, 0x1e, 0xfd, 0x14, 0xfd, 0x1e, 0xfd,
|
||||
0x1e, 0x01, 0x00, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x1c, 0x00, 0x15,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0xfa, 0x01, 0xf9, 0x1e, 0xf9, 0x14,
|
||||
0x14, 0x00, 0x0f, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x15, 0x15,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0f, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
|
||||
0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
|
||||
// View class
|
||||
class AboutViewT : public BView {
|
||||
public:
|
||||
AboutViewT(BRect r) : BView(r, "", B_FOLLOW_NONE, B_WILL_DRAW) {}
|
||||
|
||||
virtual void Draw(BRect update)
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
|
||||
|
||||
SetFont(be_bold_font);
|
||||
SetDrawingMode(B_OP_OVER);
|
||||
MovePenTo(20, 20);
|
||||
DrawString(str);
|
||||
SetFont(be_plain_font);
|
||||
MovePenTo(20, 40);
|
||||
DrawString(GetString(STR_ABOUT_TEXT2));
|
||||
MovePenTo(20, 60);
|
||||
DrawString(B_UTF8_COPYRIGHT "1997-2002 Christian Bauer and Marc Hellwig");
|
||||
}
|
||||
|
||||
virtual void MouseDown(BPoint point)
|
||||
{
|
||||
Window()->PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 3D view class
|
||||
class AboutView3D : public BGLView {
|
||||
public:
|
||||
AboutView3D(BRect r) : BGLView(r, "", B_FOLLOW_NONE, 0, BGL_RGB | BGL_DOUBLE)
|
||||
{
|
||||
rot_x = rot_y = 0;
|
||||
|
||||
if (!VideoSnapshot(64, 64, texture)) {
|
||||
uint8 *p = texture;
|
||||
const uint8 *q = sheep_icon;
|
||||
const color_map *cm = system_colors();
|
||||
for (int i=0; i<32*32; i++) {
|
||||
uint8 red = cm->color_list[*q].red;
|
||||
uint8 green = cm->color_list[*q].green;
|
||||
uint8 blue = cm->color_list[*q++].blue;
|
||||
p[0] = p[3] = p[64*3] = p[65*3] = red;
|
||||
p[1] = p[4] = p[64*3+1] = p[65*3+1] = green;
|
||||
p[2] = p[5] = p[64*3+2] = p[65*3+2] = blue;
|
||||
p += 6;
|
||||
if ((i & 31) == 31)
|
||||
p += 64*3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void AttachedToWindow(void)
|
||||
{
|
||||
BGLView::AttachedToWindow();
|
||||
LockGL();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(30, 1, 0.5, 20);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
GLfloat light_color[4] = {1, 1, 1, 1};
|
||||
GLfloat light_dir[4] = {1, 2, 1.5, 1};
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, light_dir);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
UnlockGL();
|
||||
|
||||
tick_thread_active = true;
|
||||
tick_thread = spawn_thread(tick_func, "OpenGL Animation", B_NORMAL_PRIORITY, this);
|
||||
resume_thread(tick_thread);
|
||||
}
|
||||
|
||||
virtual void DetachedFromWindow(void)
|
||||
{
|
||||
status_t l;
|
||||
tick_thread_active = false;
|
||||
wait_for_thread(tick_thread, &l);
|
||||
|
||||
BGLView::DetachedFromWindow();
|
||||
}
|
||||
|
||||
virtual void Draw(BRect update)
|
||||
{
|
||||
LockGL();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glBegin(GL_QUADS);
|
||||
glNormal3d(0, 0, 1);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3d(-1, 1, 0);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3d(1, 1, 0);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3d(1, -1, 0);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3d(-1, -1, 0);
|
||||
glEnd();
|
||||
SwapBuffers();
|
||||
UnlockGL();
|
||||
}
|
||||
|
||||
static status_t tick_func(void *arg)
|
||||
{
|
||||
AboutView3D *obj = (AboutView3D *)arg;
|
||||
while (obj->tick_thread_active) {
|
||||
obj->rot_x += 2;
|
||||
obj->rot_y += 2;
|
||||
obj->LockGL();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0, 0, -5);
|
||||
glRotatef(obj->rot_x, 1, 0, 0);
|
||||
glRotatef(obj->rot_y, 0, 1, 0);
|
||||
obj->UnlockGL();
|
||||
if (obj->LockLooperWithTimeout(20000) == B_OK) {
|
||||
obj->Draw(obj->Bounds());
|
||||
obj->UnlockLooper();
|
||||
}
|
||||
snooze(16667);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
thread_id tick_thread;
|
||||
bool tick_thread_active;
|
||||
|
||||
float rot_x, rot_y;
|
||||
uint8 texture[64*64*3];
|
||||
};
|
||||
|
||||
|
||||
// Window class
|
||||
class AboutWindowT : public BWindow {
|
||||
public:
|
||||
AboutWindowT() : BWindow(about_frame, NULL, B_MODAL_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK)
|
||||
{
|
||||
Lock();
|
||||
MoveTo(100, 100);
|
||||
BRect r = Bounds();
|
||||
r.right = 100;
|
||||
AboutView3D *view_3d = new AboutView3D(r);
|
||||
AddChild(view_3d);
|
||||
r = Bounds();
|
||||
r.left = 100;
|
||||
AboutViewT *view = new AboutViewT(r);
|
||||
AddChild(view);
|
||||
view->SetHighColor(0, 0, 0);
|
||||
view->SetViewColor(fill_color);
|
||||
view->MakeFocus();
|
||||
Unlock();
|
||||
Show();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Open "About" window
|
||||
*/
|
||||
|
||||
void OpenAboutWindow(void)
|
||||
{
|
||||
new AboutWindowT;
|
||||
}
|
366
SheepShaver/src/BeOS/clip_beos.cpp
Normal file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
* clip_beos.cpp - Clipboard handling, BeOS implementation
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <support/UTF8.h>
|
||||
|
||||
#include "clip.h"
|
||||
#include "main.h"
|
||||
#include "cpu_emulation.h"
|
||||
#include "emul_op.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
// Global variables
|
||||
static bool we_put_this_data = false; // Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the Be side
|
||||
static BTranslatorRoster *roster;
|
||||
static float input_cap = 0;
|
||||
static translator_info input_info;
|
||||
static float output_cap = 0;
|
||||
static translator_id output_trans = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Clipboard manager thread (for calling clipboard functions; this is not safe
|
||||
* under R4 when running on the MacOS stack in kernel space)
|
||||
*/
|
||||
|
||||
// Message constants
|
||||
const uint32 MSG_QUIT_CLIP_MANAGER = 'quit';
|
||||
const uint32 MSG_PUT_TEXT = 'ptxt';
|
||||
|
||||
static thread_id cm_thread = -1;
|
||||
static sem_id cm_done_sem = -1;
|
||||
|
||||
// Argument passing
|
||||
static void *cm_scrap;
|
||||
static int32 cm_length;
|
||||
|
||||
static status_t clip_manager(void *arg)
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
// Receive message
|
||||
thread_id sender;
|
||||
uint32 code = receive_data(&sender, NULL, 0);
|
||||
D(bug("Clipboard manager received %08lx\n", code));
|
||||
switch (code) {
|
||||
case MSG_QUIT_CLIP_MANAGER:
|
||||
return 0;
|
||||
|
||||
case MSG_PUT_TEXT:
|
||||
if (be_clipboard->Lock()) {
|
||||
be_clipboard->Clear();
|
||||
BMessage *clipper = be_clipboard->Data();
|
||||
|
||||
// Convert text from Mac charset to UTF-8
|
||||
int32 dest_length = cm_length * 3;
|
||||
int32 state = 0;
|
||||
char *inbuf = new char[cm_length];
|
||||
memcpy(inbuf, cm_scrap, cm_length); // Copy to user space
|
||||
char *outbuf = new char[dest_length];
|
||||
if (convert_to_utf8(B_MAC_ROMAN_CONVERSION, inbuf, &cm_length, outbuf, &dest_length, &state) == B_OK) {
|
||||
for (int i=0; i<dest_length; i++)
|
||||
if (outbuf[i] == 13)
|
||||
outbuf[i] = 10;
|
||||
|
||||
// Add text to Be clipboard
|
||||
clipper->AddData("text/plain", B_MIME_TYPE, outbuf, dest_length);
|
||||
be_clipboard->Commit();
|
||||
} else {
|
||||
D(bug(" text conversion failed\n"));
|
||||
}
|
||||
delete[] outbuf;
|
||||
delete[] inbuf;
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Acknowledge
|
||||
release_sem(cm_done_sem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize clipboard
|
||||
*/
|
||||
|
||||
void ClipInit(void)
|
||||
{
|
||||
// check if there is a translator that can handle the pict datatype
|
||||
roster = BTranslatorRoster::Default();
|
||||
int32 num_translators, i,j;
|
||||
translator_id *translators;
|
||||
const char *translator_name, *trans_info;
|
||||
int32 translator_version;
|
||||
const translation_format *t_formats;
|
||||
long t_num;
|
||||
|
||||
roster->GetAllTranslators(&translators, &num_translators);
|
||||
for (i=0;i<num_translators;i++) {
|
||||
roster->GetTranslatorInfo(translators[i], &translator_name,
|
||||
&trans_info, &translator_version);
|
||||
D(bug("found translator %s: %s (%.2f)\n", translator_name, trans_info,
|
||||
translator_version/100.));
|
||||
// does this translator support the pict datatype ?
|
||||
roster->GetInputFormats(translators[i], &t_formats,&t_num);
|
||||
//printf(" supports %d input formats \n",t_num);
|
||||
for (j=0;j<t_num;j++) {
|
||||
if (!strcmp (t_formats[j].MIME,"image/pict")) {
|
||||
// matching translator found
|
||||
if (t_formats[j].capability>input_cap) {
|
||||
input_info.type = t_formats[j].type;
|
||||
input_info.group = t_formats[j].group;
|
||||
input_info.quality = t_formats[j].quality;
|
||||
input_info.capability = t_formats[j].capability;
|
||||
strcpy(input_info.MIME,t_formats[j].MIME);
|
||||
strcpy(input_info.name,t_formats[j].name);
|
||||
input_info.translator=translators[i];
|
||||
input_cap = t_formats[j].capability;
|
||||
}
|
||||
D(bug("matching input translator found:type:%c%c%c%c group:%c%c%c%c quality:%f capability:%f MIME:%s name:%s\n",
|
||||
t_formats[j].type>>24,t_formats[j].type>>16,t_formats[j].type>>8,t_formats[j].type,
|
||||
t_formats[j].group>>24,t_formats[j].group>>16,t_formats[j].group>>8,t_formats[j].group,
|
||||
t_formats[j].quality,
|
||||
t_formats[j].capability,t_formats[j].MIME,
|
||||
t_formats[j].name));
|
||||
}
|
||||
|
||||
}
|
||||
roster->GetOutputFormats(translators[i], &t_formats,&t_num);
|
||||
//printf("and %d output formats \n",t_num);
|
||||
for (j=0;j<t_num;j++) {
|
||||
if (!strcmp (t_formats[j].MIME,"image/pict")) {
|
||||
if (t_formats[j].capability>output_cap) {
|
||||
output_trans = translators[i];
|
||||
output_cap = t_formats[j].capability;
|
||||
}
|
||||
D(bug("matching output translator found:type:%c%c%c%c group:%c%c%c%c quality:%f capability:%f MIME:%s name:%s\n",
|
||||
t_formats[j].type>>24,t_formats[j].type>>16,t_formats[j].type>>8,t_formats[j].type,
|
||||
t_formats[j].group>>24,t_formats[j].group>>16,t_formats[j].group>>8,t_formats[j].group,
|
||||
t_formats[j].quality,
|
||||
t_formats[j].capability,t_formats[j].MIME,
|
||||
t_formats[j].name));
|
||||
}
|
||||
}
|
||||
}
|
||||
delete [] translators; // clean up our droppings
|
||||
|
||||
// Start clipboard manager thread
|
||||
cm_done_sem = create_sem(0, "Clipboard Manager Done");
|
||||
cm_thread = spawn_thread(clip_manager, "Clipboard Manager", B_NORMAL_PRIORITY, NULL);
|
||||
resume_thread(cm_thread);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deinitialize clipboard
|
||||
*/
|
||||
|
||||
void ClipExit(void)
|
||||
{
|
||||
// Stop clipboard manager
|
||||
if (cm_thread > 0) {
|
||||
status_t l;
|
||||
send_data(cm_thread, MSG_QUIT_CLIP_MANAGER, NULL, 0);
|
||||
while (wait_for_thread(cm_thread, &l) == B_INTERRUPTED) ;
|
||||
}
|
||||
|
||||
// Delete semaphores
|
||||
delete_sem(cm_done_sem);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mac application wrote to clipboard
|
||||
*/
|
||||
|
||||
void PutScrap(uint32 type, void *scrap, int32 length)
|
||||
{
|
||||
D(bug("PutScrap type %08lx, data %p, length %ld\n", type, scrap, length));
|
||||
if (we_put_this_data) {
|
||||
we_put_this_data = false;
|
||||
return;
|
||||
}
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case 'TEXT':
|
||||
D(bug(" clipping TEXT\n"));
|
||||
cm_scrap = scrap;
|
||||
cm_length = length;
|
||||
while (send_data(cm_thread, MSG_PUT_TEXT, NULL, 0) == B_INTERRUPTED) ;
|
||||
while (acquire_sem(cm_done_sem) == B_INTERRUPTED) ;
|
||||
break;
|
||||
|
||||
case 'PICT':
|
||||
D(bug(" clipping PICT\n"));
|
||||
//!! this has to be converted to use the Clipboard Manager
|
||||
#if 0
|
||||
if (be_clipboard->Lock()) {
|
||||
be_clipboard->Clear();
|
||||
BMessage *clipper = be_clipboard->Data();
|
||||
// Waaaah! This crashes!
|
||||
if (input_cap > 0) { // if there is an converter for PICT datatype convert data to bitmap.
|
||||
BMemoryIO *in_buffer = new BMemoryIO(scrap, length);
|
||||
BMallocIO *out_buffer = new BMallocIO();
|
||||
status_t result=roster->Translate(in_buffer,&input_info,NULL,out_buffer,B_TRANSLATOR_BITMAP);
|
||||
clipper->AddData("image/x-be-bitmap", B_MIME_TYPE, out_buffer->Buffer(), out_buffer->BufferLength());
|
||||
D(bug("conversion result:%08x buffer_size:%d\n",result,out_buffer->BufferLength()));
|
||||
delete in_buffer;
|
||||
delete out_buffer;
|
||||
}
|
||||
clipper->AddData("image/pict", B_MIME_TYPE, scrap, length);
|
||||
be_clipboard->Commit();
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
*/
|
||||
|
||||
void GetScrap(void **handle, uint32 type, int32 offset)
|
||||
{
|
||||
M68kRegisters r;
|
||||
D(bug("GetScrap handle %p, type %08lx, offset %ld\n", handle, type, offset));
|
||||
return; //!! GetScrap is currently broken (should use Clipboard Manager)
|
||||
//!! replace with clipboard notification in BeOS R4.1
|
||||
|
||||
switch (type) {
|
||||
case 'TEXT':
|
||||
D(bug(" clipping TEXT\n"));
|
||||
if (be_clipboard->Lock()) {
|
||||
BMessage *clipper = be_clipboard->Data();
|
||||
char *clip;
|
||||
ssize_t length;
|
||||
|
||||
// Check if we already copied this data
|
||||
if (clipper->HasData("application/x-SheepShaver-cookie", B_MIME_TYPE))
|
||||
return;
|
||||
bigtime_t cookie = system_time();
|
||||
clipper->AddData("application/x-SheepShaver-cookie", B_MIME_TYPE, &cookie, sizeof(bigtime_t));
|
||||
|
||||
// No, is there text in it?
|
||||
if (clipper->FindData("text/plain", B_MIME_TYPE, &clip, &length) == B_OK) {
|
||||
D(bug(" text/plain found\n"));
|
||||
|
||||
// Convert text from UTF-8 to Mac charset
|
||||
int32 src_length = length;
|
||||
int32 dest_length = length;
|
||||
int32 state = 0;
|
||||
char *outbuf = new char[dest_length];
|
||||
if (convert_from_utf8(B_MAC_ROMAN_CONVERSION, clip, &src_length, outbuf, &dest_length, &state) == B_OK) {
|
||||
for (int i=0; i<dest_length; i++)
|
||||
if (outbuf[i] == 10)
|
||||
outbuf[i] = 13;
|
||||
|
||||
// Add text to Mac clipboard
|
||||
static uint16 proc[] = {
|
||||
0x598f, // subq.l #4,sp
|
||||
0xa9fc, // ZeroScrap()
|
||||
0x2f3c, 0, 0, // move.l #length,-(sp)
|
||||
0x2f3c, 'TE', 'XT', // move.l #'TEXT',-(sp)
|
||||
0x2f3c, 0, 0, // move.l #outbuf,-(sp)
|
||||
0xa9fe, // PutScrap()
|
||||
0x588f, // addq.l #4,sp
|
||||
M68K_RTS
|
||||
};
|
||||
*(int32 *)(proc + 3) = dest_length;
|
||||
*(char **)(proc + 9) = outbuf;
|
||||
we_put_this_data = true;
|
||||
Execute68k((uint32)proc, &r);
|
||||
} else {
|
||||
D(bug(" text conversion failed\n"));
|
||||
}
|
||||
delete[] outbuf;
|
||||
}
|
||||
be_clipboard->Commit();
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'PICT':
|
||||
D(bug(" clipping PICT\n"));
|
||||
if (be_clipboard->Lock()) {
|
||||
BMessage *clipper = be_clipboard->Data();
|
||||
char *clip;
|
||||
ssize_t length;
|
||||
|
||||
// Check if we already copied this data
|
||||
if (clipper->HasData("application/x-SheepShaver-cookie", B_MIME_TYPE))
|
||||
return;
|
||||
bigtime_t cookie = system_time();
|
||||
clipper->AddData("application/x-SheepShaver-cookie", B_MIME_TYPE, &cookie, sizeof(bigtime_t));
|
||||
|
||||
static uint16 proc2[] = {
|
||||
0x598f, // subq.l #4,sp
|
||||
0xa9fc, // ZeroScrap()
|
||||
0x2f3c, 0, 0, // move.l #length,-(sp)
|
||||
0x2f3c, 'PI', 'CT', // move.l #'PICT',-(sp)
|
||||
0x2f3c, 0, 0, // move.l #buf,-(sp)
|
||||
0xa9fe, // PutScrap()
|
||||
0x588f, // addq.l #4,sp
|
||||
M68K_RTS
|
||||
};
|
||||
|
||||
// No, is there a pict ?
|
||||
if (clipper->FindData("image/pict", B_MIME_TYPE, &clip, &length) == B_OK ) {
|
||||
D(bug(" image/pict found\n"));
|
||||
|
||||
// Add pict to Mac clipboard
|
||||
*(int32 *)(proc2 + 3) = length;
|
||||
*(char **)(proc2 + 9) = clip;
|
||||
we_put_this_data = true;
|
||||
Execute68k((uint32)proc2, &r);
|
||||
#if 0
|
||||
// No, is there a bitmap ?
|
||||
} else if (clipper->FindData("image/x-be-bitmap", B_MIME_TYPE, &clip, &length) == B_OK || output_cap > 0) {
|
||||
D(bug(" image/x-be-bitmap found\nstarting conversion to PICT\n"));
|
||||
|
||||
BMemoryIO *in_buffer = new BMemoryIO(clip, length);
|
||||
BMallocIO *out_buffer = new BMallocIO();
|
||||
status_t result=roster->Translate(output_trans,in_buffer,NULL,out_buffer,'PICT');
|
||||
D(bug("result of conversion:%08x buffer_size:%d\n",result,out_buffer->BufferLength()));
|
||||
|
||||
// Add pict to Mac clipboard
|
||||
*(int32 *)(proc2 + 3) = out_buffer->BufferLength();
|
||||
*(char **)(proc2 + 9) = (char *)out_buffer->Buffer();
|
||||
we_put_this_data = true;
|
||||
Execute68k(proc2, &r);
|
||||
|
||||
delete in_buffer;
|
||||
delete out_buffer;
|
||||
#endif
|
||||
}
|
||||
be_clipboard->Commit();
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
398
SheepShaver/src/BeOS/ether_beos.cpp
Normal file
@ -0,0 +1,398 @@
|
||||
/*
|
||||
* ether_beos.cpp - SheepShaver Ethernet Device Driver (DLPI), BeOS specific stuff
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "ether.h"
|
||||
#include "ether_defs.h"
|
||||
#include "prefs.h"
|
||||
#include "xlowmem.h"
|
||||
#include "main.h"
|
||||
#include "user_strings.h"
|
||||
#include "sheep_net.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define STATISTICS 0
|
||||
#define MONITOR 0
|
||||
|
||||
|
||||
// Global variables
|
||||
static thread_id read_thread; // Packet receiver thread
|
||||
static bool ether_thread_active = true; // Flag for quitting the receiver thread
|
||||
|
||||
static area_id buffer_area; // Packet buffer area
|
||||
static net_buffer *net_buffer_ptr; // Pointer to packet buffer
|
||||
static sem_id read_sem, write_sem; // Semaphores to trigger packet reading/writing
|
||||
static uint32 rd_pos; // Current read position in packet buffer
|
||||
static uint32 wr_pos; // Current write position in packet buffer
|
||||
|
||||
static bool net_open = false; // Flag: initialization succeeded, network device open
|
||||
|
||||
|
||||
// Prototypes
|
||||
static status_t AO_receive_thread(void *data);
|
||||
|
||||
|
||||
/*
|
||||
* Initialize ethernet
|
||||
*/
|
||||
|
||||
void EtherInit(void)
|
||||
{
|
||||
// Do nothing if the user disabled the network
|
||||
if (PrefsFindBool("nonet"))
|
||||
return;
|
||||
|
||||
// find net-server team
|
||||
i_wanna_try_that_again:
|
||||
bool found_add_on = false;
|
||||
team_info t_info;
|
||||
int32 t_cookie = 0;
|
||||
image_info i_info;
|
||||
int32 i_cookie = 0;
|
||||
while (get_next_team_info(&t_cookie, &t_info) == B_NO_ERROR) {
|
||||
if (strstr(t_info.args,"net_server")!=NULL) {
|
||||
// check if sheep_net add-on is loaded
|
||||
while (get_next_image_info(t_info.team,&i_cookie,&i_info) == B_NO_ERROR) {
|
||||
if (strstr(i_info.name,"sheep_net")!=NULL) {
|
||||
found_add_on = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_add_on) break;
|
||||
}
|
||||
if (!found_add_on) {
|
||||
|
||||
// Search for sheep_net in network config file
|
||||
char str[1024];
|
||||
bool sheep_net_found = false;
|
||||
FILE *fin = fopen("/boot/home/config/settings/network", "r");
|
||||
while (!feof(fin)) {
|
||||
fgets(str, 1024, fin);
|
||||
if (strstr(str, "PROTOCOLS"))
|
||||
if (strstr(str, "sheep_net"))
|
||||
sheep_net_found = true;
|
||||
}
|
||||
fclose(fin);
|
||||
|
||||
// It was found, so something else must be wrong
|
||||
if (sheep_net_found) {
|
||||
WarningAlert(GetString(STR_NO_NET_ADDON_WARN));
|
||||
return;
|
||||
}
|
||||
|
||||
// Not found, inform the user
|
||||
if (!ChoiceAlert(GetString(STR_NET_CONFIG_MODIFY_WARN), GetString(STR_OK_BUTTON), GetString(STR_CANCEL_BUTTON)))
|
||||
return;
|
||||
|
||||
// Change the network config file and restart the network
|
||||
fin = fopen("/boot/home/config/settings/network", "r");
|
||||
FILE *fout = fopen("/boot/home/config/settings/network.2", "w");
|
||||
bool global_found = false;
|
||||
bool modified = false;
|
||||
while (!feof(fin)) {
|
||||
str[0] = 0;
|
||||
fgets(str, 1024, fin);
|
||||
if (!global_found && strstr(str, "GLOBAL:")) {
|
||||
global_found = true;
|
||||
} else if (global_found && !modified && strstr(str, "PROTOCOLS")) {
|
||||
str[strlen(str)-1] = 0;
|
||||
strcat(str, " sheep_net\n");
|
||||
modified = true;
|
||||
} else if (global_found && !modified && strlen(str) > 2 && str[strlen(str) - 2] == ':') {
|
||||
fputs("\tPROTOCOLS = sheep_net\n", fout);
|
||||
modified = true;
|
||||
}
|
||||
fputs(str, fout);
|
||||
}
|
||||
if (!modified)
|
||||
fputs("\tPROTOCOLS = sheep_net\n", fout);
|
||||
fclose(fout);
|
||||
fclose(fin);
|
||||
remove("/boot/home/config/settings/network.orig");
|
||||
rename("/boot/home/config/settings/network", "/boot/home/config/settings/network.orig");
|
||||
rename("/boot/home/config/settings/network.2", "/boot/home/config/settings/network");
|
||||
|
||||
app_info ai;
|
||||
if (be_roster->GetAppInfo("application/x-vnd.Be-NETS", &ai) == B_OK) {
|
||||
BMessenger msg(NULL, ai.team);
|
||||
if (msg.IsValid()) {
|
||||
while (be_roster->IsRunning("application/x-vnd.Be-NETS")) {
|
||||
msg.SendMessage(B_QUIT_REQUESTED);
|
||||
snooze(500000);
|
||||
}
|
||||
}
|
||||
}
|
||||
BPath path;
|
||||
find_directory(B_BEOS_BOOT_DIRECTORY, &path);
|
||||
path.Append("Netscript");
|
||||
char *argv[3] = {"/bin/sh", (char *)path.Path(), NULL};
|
||||
thread_id net_server = load_image(2, argv, environ);
|
||||
resume_thread(net_server);
|
||||
status_t l;
|
||||
wait_for_thread(net_server, &l);
|
||||
goto i_wanna_try_that_again;
|
||||
}
|
||||
|
||||
// Set up communications with add-on
|
||||
area_id handler_buffer;
|
||||
if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) {
|
||||
WarningAlert(GetString(STR_NET_ADDON_INIT_FAILED));
|
||||
return;
|
||||
}
|
||||
if ((buffer_area = clone_area("local packet buffer", &net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) {
|
||||
D(bug("EtherInit: couldn't clone packet area\n"));
|
||||
WarningAlert(GetString(STR_NET_ADDON_CLONE_FAILED));
|
||||
return;
|
||||
}
|
||||
if ((read_sem = create_sem(0, "ether read")) < B_NO_ERROR) {
|
||||
printf("FATAL: can't create Ethernet semaphore\n");
|
||||
return;
|
||||
}
|
||||
net_buffer_ptr->read_sem = read_sem;
|
||||
write_sem = net_buffer_ptr->write_sem;
|
||||
read_thread = spawn_thread(AO_receive_thread, "ether read", B_URGENT_DISPLAY_PRIORITY, NULL);
|
||||
resume_thread(read_thread);
|
||||
for (int i=0; i<WRITE_PACKET_COUNT; i++)
|
||||
net_buffer_ptr->write[i].cmd = IN_USE | (ACTIVATE_SHEEP_NET << 8);
|
||||
rd_pos = wr_pos = 0;
|
||||
release_sem(write_sem);
|
||||
|
||||
// Everything OK
|
||||
net_open = true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Exit ethernet
|
||||
*/
|
||||
|
||||
void EtherExit(void)
|
||||
{
|
||||
if (net_open) {
|
||||
|
||||
// Close communications with add-on
|
||||
for (int i=0; i<WRITE_PACKET_COUNT; i++)
|
||||
net_buffer_ptr->write[i].cmd = IN_USE | (DEACTIVATE_SHEEP_NET << 8);
|
||||
release_sem(write_sem);
|
||||
|
||||
// Quit receiver thread
|
||||
ether_thread_active = false;
|
||||
status_t result;
|
||||
release_sem(read_sem);
|
||||
while (wait_for_thread(read_thread, &result) == B_INTERRUPTED) ;
|
||||
|
||||
delete_sem(read_sem);
|
||||
delete_area(buffer_area);
|
||||
}
|
||||
|
||||
#if STATISTICS
|
||||
// Show statistics
|
||||
printf("%ld messages put on write queue\n", num_wput);
|
||||
printf("%ld error acks\n", num_error_acks);
|
||||
printf("%ld packets transmitted (%ld raw, %ld normal)\n", num_tx_packets, num_tx_raw_packets, num_tx_normal_packets);
|
||||
printf("%ld tx packets dropped because buffer full\n", num_tx_buffer_full);
|
||||
printf("%ld packets received\n", num_rx_packets);
|
||||
printf("%ld packets passed upstream (%ld Fast Path, %ld normal)\n", num_rx_fastpath + num_unitdata_ind, num_rx_fastpath, num_unitdata_ind);
|
||||
printf("EtherIRQ called %ld times\n", num_ether_irq);
|
||||
printf("%ld rx packets dropped due to low memory\n", num_rx_no_mem);
|
||||
printf("%ld rx packets dropped because no stream found\n", num_rx_dropped);
|
||||
printf("%ld rx packets dropped because stream not ready\n", num_rx_stream_not_ready);
|
||||
printf("%ld rx packets dropped because no memory for unitdata_ind\n", num_rx_no_unitdata_mem);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ask add-on for ethernet hardware address
|
||||
*/
|
||||
|
||||
void AO_get_ethernet_address(uint8 *addr)
|
||||
{
|
||||
if (net_open) {
|
||||
OTCopy48BitAddress(net_buffer_ptr->ether_addr, addr);
|
||||
} else {
|
||||
addr[0] = 0x12;
|
||||
addr[1] = 0x34;
|
||||
addr[2] = 0x56;
|
||||
addr[3] = 0x78;
|
||||
addr[4] = 0x9a;
|
||||
addr[5] = 0xbc;
|
||||
}
|
||||
D(bug("AO_get_ethernet_address: got address %02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tell add-on to enable multicast address
|
||||
*/
|
||||
|
||||
void AO_enable_multicast(uint8 *addr)
|
||||
{
|
||||
D(bug("AO_enable_multicast\n"));
|
||||
if (net_open) {
|
||||
net_packet *p = &net_buffer_ptr->write[wr_pos];
|
||||
if (p->cmd & IN_USE) {
|
||||
D(bug("WARNING: couldn't enable multicast address\n"));
|
||||
} else {
|
||||
memcpy(p->data, addr, 6);
|
||||
p->length = 6;
|
||||
p->cmd = IN_USE | (ADD_MULTICAST << 8);
|
||||
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
|
||||
release_sem(write_sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tell add-on to disable multicast address
|
||||
*/
|
||||
|
||||
void AO_disable_multicast(uint8 *addr)
|
||||
{
|
||||
D(bug("AO_disable_multicast\n"));
|
||||
if (net_open) {
|
||||
net_packet *p = &net_buffer_ptr->write[wr_pos];
|
||||
if (p->cmd & IN_USE) {
|
||||
D(bug("WARNING: couldn't enable multicast address\n"));
|
||||
} else {
|
||||
memcpy(p->data, addr, 6);
|
||||
p->length = 6;
|
||||
p->cmd = IN_USE | (REMOVE_MULTICAST << 8);
|
||||
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
|
||||
release_sem(write_sem);
|
||||
}
|
||||
D(bug("WARNING: couldn't disable multicast address\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tell add-on to transmit one packet
|
||||
*/
|
||||
|
||||
void AO_transmit_packet(mblk_t *mp)
|
||||
{
|
||||
D(bug("AO_transmit_packet\n"));
|
||||
if (net_open) {
|
||||
net_packet *p = &net_buffer_ptr->write[wr_pos];
|
||||
if (p->cmd & IN_USE) {
|
||||
D(bug("WARNING: couldn't transmit packet (buffer full)\n"));
|
||||
num_tx_buffer_full++;
|
||||
} else {
|
||||
D(bug(" write packet pos %d\n", i));
|
||||
num_tx_packets++;
|
||||
|
||||
// Copy packet to buffer
|
||||
uint8 *start;
|
||||
uint8 *bp = start = p->data;
|
||||
while (mp) {
|
||||
uint32 size = mp->b_wptr - mp->b_rptr;
|
||||
memcpy(bp, mp->b_rptr, size);
|
||||
bp += size;
|
||||
mp = mp->b_cont;
|
||||
}
|
||||
|
||||
#if MONITOR
|
||||
bug("Sending Ethernet packet:\n");
|
||||
for (int i=0; i<(uint32)(bp - start); i++) {
|
||||
bug("%02lx ", start[i]);
|
||||
}
|
||||
bug("\n");
|
||||
#endif
|
||||
|
||||
// Notify add-on
|
||||
p->length = (uint32)(bp - start);
|
||||
p->cmd = IN_USE | (SHEEP_PACKET << 8);
|
||||
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
|
||||
release_sem(write_sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Packet reception thread
|
||||
*/
|
||||
|
||||
static status_t AO_receive_thread(void *data)
|
||||
{
|
||||
while (ether_thread_active) {
|
||||
if (net_buffer_ptr->read[rd_pos].cmd & IN_USE) {
|
||||
if (ether_driver_opened) {
|
||||
D(bug(" packet received, triggering Ethernet interrupt\n"));
|
||||
SetInterruptFlag(INTFLAG_ETHER);
|
||||
TriggerInterrupt();
|
||||
}
|
||||
}
|
||||
acquire_sem_etc(read_sem, 1, B_TIMEOUT, 25000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ethernet interrupt
|
||||
*/
|
||||
|
||||
void EtherIRQ(void)
|
||||
{
|
||||
D(bug("EtherIRQ\n"));
|
||||
num_ether_irq++;
|
||||
OTEnterInterrupt();
|
||||
|
||||
// Send received packets to OpenTransport
|
||||
net_packet *p = &net_buffer_ptr->read[rd_pos];
|
||||
while (p->cmd & IN_USE) {
|
||||
if ((p->cmd >> 8) == SHEEP_PACKET) {
|
||||
num_rx_packets++;
|
||||
D(bug(" read packet pos %d\n", i));
|
||||
uint32 size = p->length;
|
||||
|
||||
#if MONITOR
|
||||
bug("Receiving Ethernet packet:\n");
|
||||
for (int i=0; i<size; i++) {
|
||||
bug("%02lx ", p->data[i]);
|
||||
}
|
||||
bug("\n");
|
||||
#endif
|
||||
|
||||
// Wrap packet in message block
|
||||
//!! maybe use esballoc()
|
||||
mblk_t *mp;
|
||||
if ((mp = allocb(size, 0)) != NULL) {
|
||||
D(bug(" packet data at %p\n", mp->b_rptr));
|
||||
memcpy(mp->b_rptr, p->data, size);
|
||||
mp->b_wptr += size;
|
||||
ether_packet_received(mp);
|
||||
} else {
|
||||
D(bug("WARNING: Cannot allocate mblk for received packet\n"));
|
||||
num_rx_no_mem++;
|
||||
}
|
||||
}
|
||||
p->cmd = 0; // Free packet
|
||||
rd_pos = (rd_pos + 1) % READ_PACKET_COUNT;
|
||||
p = &net_buffer_ptr->read[rd_pos];
|
||||
}
|
||||
OTLeaveInterrupt();
|
||||
}
|
2185
SheepShaver/src/BeOS/main_beos.cpp
Normal file
112
SheepShaver/src/BeOS/prefs_beos.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* prefs_beos.cpp - Preferences handling, BeOS specific things
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <StorageKit.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "prefs.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
// Platform-specific preferences items
|
||||
prefs_desc platform_prefs_items[] = {
|
||||
{"bitbang", TYPE_BOOLEAN, false, "draw Mac desktop directly on screen in window mode"},
|
||||
{"idlewait", TYPE_BOOLEAN, false, "sleep when idle"},
|
||||
{NULL, TYPE_END, false, NULL} // End of list
|
||||
};
|
||||
|
||||
|
||||
// Preferences file name and path
|
||||
const char PREFS_FILE_NAME[] = "SheepShaver_prefs";
|
||||
static BPath prefs_path;
|
||||
|
||||
// Modification date of prefs file
|
||||
time_t PrefsFileDate = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Load preferences from settings file
|
||||
*/
|
||||
|
||||
void LoadPrefs(void)
|
||||
{
|
||||
// Construct prefs path
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, &prefs_path, true);
|
||||
prefs_path.Append(PREFS_FILE_NAME);
|
||||
|
||||
// Read preferences from settings file
|
||||
FILE *f = fopen(prefs_path.Path(), "r");
|
||||
if (f == NULL) // Not found in settings directory, look in app directory
|
||||
f = fopen(PREFS_FILE_NAME, "r");
|
||||
if (f != NULL) {
|
||||
LoadPrefsFromStream(f);
|
||||
|
||||
struct stat s;
|
||||
fstat(fileno(f), &s);
|
||||
PrefsFileDate = s.st_ctime;
|
||||
fclose(f);
|
||||
|
||||
} else {
|
||||
|
||||
// No prefs file, save defaults
|
||||
SavePrefs();
|
||||
PrefsFileDate = real_time_clock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save preferences to settings file
|
||||
*/
|
||||
|
||||
void SavePrefs(void)
|
||||
{
|
||||
FILE *f;
|
||||
if ((f = fopen(prefs_path.Path(), "w")) != NULL) {
|
||||
SavePrefsToStream(f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add defaults of platform-specific prefs items
|
||||
* You may also override the defaults set in PrefsInit()
|
||||
*/
|
||||
|
||||
void AddPlatformPrefsDefaults(void)
|
||||
{
|
||||
PrefsReplaceString("extfs", "/boot");
|
||||
PrefsAddInt32("windowmodes",
|
||||
B_8_BIT_640x480 | B_15_BIT_640x480 | B_32_BIT_640x480 |
|
||||
B_8_BIT_800x600 | B_15_BIT_800x600 | B_32_BIT_800x600
|
||||
);
|
||||
PrefsAddInt32("screenmodes",
|
||||
B_8_BIT_640x480 | B_15_BIT_640x480 | B_32_BIT_640x480 |
|
||||
B_8_BIT_800x600 | B_15_BIT_800x600 | B_32_BIT_800x600 |
|
||||
B_8_BIT_1024x768 | B_15_BIT_1024x768
|
||||
);
|
||||
PrefsAddBool("bitbang", false);
|
||||
PrefsAddBool("idlewait", true);
|
||||
}
|
877
SheepShaver/src/BeOS/prefs_editor_beos.cpp
Normal file
@ -0,0 +1,877 @@
|
||||
/*
|
||||
* prefs_editor_beos.cpp - Preferences editor, BeOS implementation
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <SerialPort.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fs_info.h>
|
||||
|
||||
#include "prefs_editor.h"
|
||||
#include "prefs.h"
|
||||
#include "main.h"
|
||||
#include "cdrom.h"
|
||||
#include "xpram.h"
|
||||
#include "about_window.h"
|
||||
#include "user_strings.h"
|
||||
|
||||
|
||||
// Special colors
|
||||
const rgb_color fill_color = {216, 216, 216, 0};
|
||||
const rgb_color slider_fill_color = {102, 152, 255, 0};
|
||||
|
||||
|
||||
// Window messages
|
||||
const uint32 MSG_OK = 'okok'; // "Start" clicked
|
||||
const uint32 MSG_CANCEL = 'cncl'; // "Quit" clicked
|
||||
const uint32 MSG_ZAP_PRAM = 'zprm';
|
||||
|
||||
const int NUM_PANES = 4;
|
||||
|
||||
const uint32 MSG_VOLUME_SELECTED = 'volu'; // "Volumes" pane
|
||||
const uint32 MSG_VOLUME_INVOKED = 'voli';
|
||||
const uint32 MSG_ADD_VOLUME = 'addv';
|
||||
const uint32 MSG_CREATE_VOLUME = 'crev';
|
||||
const uint32 MSG_REMOVE_VOLUME = 'remv';
|
||||
const uint32 MSG_ADD_VOLUME_PANEL = 'advp';
|
||||
const uint32 MSG_CREATE_VOLUME_PANEL = 'crvp';
|
||||
const uint32 MSG_DEVICE_NAME = 'devn';
|
||||
const uint32 MSG_BOOT_ANY = 'bany';
|
||||
const uint32 MSG_BOOT_CDROM = 'bcdr';
|
||||
const uint32 MSG_NOCDROM = 'nocd';
|
||||
|
||||
const uint32 MSG_REF_5HZ = ' 5Hz'; // "Graphics" pane
|
||||
const uint32 MSG_REF_7_5HZ = ' 7Hz';
|
||||
const uint32 MSG_REF_10HZ = '10Hz';
|
||||
const uint32 MSG_REF_15HZ = '15Hz';
|
||||
const uint32 MSG_REF_30HZ = '30Hz';
|
||||
const uint32 MSG_GFXACCEL = 'gfac';
|
||||
const uint32 MSG_WINDOW_MODE = 'wmod';
|
||||
const uint32 MSG_SCREEN_MODE = 'smod';
|
||||
const uint32 MSG_NOSOUND = 'nosn';
|
||||
|
||||
const uint32 MSG_SER_A = 'sera'; // "Serial"/"Network" pane
|
||||
const uint32 MSG_SER_B = 'serb';
|
||||
const uint32 MSG_NONET = 'noet';
|
||||
|
||||
const uint32 MSG_RAMSIZE = 'rmsz'; // "Memory" pane
|
||||
const uint32 MSG_IGNORESEGV = 'isgv';
|
||||
const uint32 MSG_IDLEWAIT = 'idlw';
|
||||
|
||||
|
||||
// RAM size slider class
|
||||
class RAMSlider : public BSlider {
|
||||
public:
|
||||
RAMSlider(BRect frame, const char *name, const char *label, BMessage *message,
|
||||
int32 minValue, int32 maxValue, thumb_style thumbType = B_BLOCK_THUMB,
|
||||
uint32 resizingMode = B_FOLLOW_LEFT |
|
||||
B_FOLLOW_TOP,
|
||||
uint32 flags = B_NAVIGABLE | B_WILL_DRAW |
|
||||
B_FRAME_EVENTS) : BSlider(frame, name, label, message, minValue, maxValue, thumbType, resizingMode, flags)
|
||||
{
|
||||
update_text = (char *)malloc(256);
|
||||
}
|
||||
|
||||
virtual ~RAMSlider()
|
||||
{
|
||||
if (update_text)
|
||||
free(update_text);
|
||||
}
|
||||
|
||||
virtual char *UpdateText(void) const
|
||||
{
|
||||
if (update_text) {
|
||||
sprintf(update_text, GetString(STR_RAMSIZE_FMT), Value());
|
||||
}
|
||||
return update_text;
|
||||
}
|
||||
|
||||
private:
|
||||
char *update_text;
|
||||
};
|
||||
|
||||
|
||||
// Volumes list view class
|
||||
class VolumeListView : public BListView {
|
||||
public:
|
||||
VolumeListView(BRect frame, const char *name, list_view_type type = B_SINGLE_SELECTION_LIST, uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE)
|
||||
: BListView(frame, name, type, resizeMask, flags)
|
||||
{}
|
||||
|
||||
// Handle dropped files and volumes
|
||||
virtual void MessageReceived(BMessage *msg)
|
||||
{
|
||||
if (msg->what == B_SIMPLE_DATA) {
|
||||
BMessage msg2(MSG_ADD_VOLUME_PANEL);
|
||||
entry_ref ref;
|
||||
for (int i=0; msg->FindRef("refs", i, &ref) == B_NO_ERROR; i++)
|
||||
msg2.AddRef("refs", &ref);
|
||||
Window()->PostMessage(&msg2);
|
||||
} else
|
||||
BListView::MessageReceived(msg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Number-entry BTextControl
|
||||
class NumberControl : public BTextControl {
|
||||
public:
|
||||
NumberControl(BRect frame, float divider, const char *name, const char *label, long value, BMessage *message)
|
||||
: BTextControl(frame, name, label, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE)
|
||||
{
|
||||
SetDivider(divider);
|
||||
for (int c=0; c<256; c++)
|
||||
if (!isdigit(c) && c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
|
||||
((BTextView *)ChildAt(0))->DisallowChar(c);
|
||||
SetValue(value);
|
||||
}
|
||||
|
||||
// Set integer value
|
||||
void SetValue(long value)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "%ld", value);
|
||||
SetText(str);
|
||||
}
|
||||
|
||||
// Get integer value
|
||||
long Value(void)
|
||||
{
|
||||
return atol(Text());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Path-entry BTextControl
|
||||
class PathControl : public BTextControl {
|
||||
public:
|
||||
PathControl(bool dir_ctrl_, BRect frame, const char *name, const char *label, const char *text, BMessage *message) : BTextControl(frame, name, label, text, message), dir_ctrl(dir_ctrl_)
|
||||
{
|
||||
for (int c=0; c<' '; c++)
|
||||
if (c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW)
|
||||
((BTextView *)ChildAt(0))->DisallowChar(c);
|
||||
}
|
||||
|
||||
virtual void MessageReceived(BMessage *msg)
|
||||
{
|
||||
if (msg->what == B_SIMPLE_DATA) {
|
||||
entry_ref the_ref;
|
||||
BEntry the_entry;
|
||||
|
||||
// Look for dropped refs
|
||||
if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) {
|
||||
if (the_entry.SetTo(&the_ref) == B_NO_ERROR && (dir_ctrl&& the_entry.IsDirectory() || !dir_ctrl && the_entry.IsFile())) {
|
||||
BPath the_path;
|
||||
the_entry.GetPath(&the_path);
|
||||
SetText(the_path.Path());
|
||||
}
|
||||
} else
|
||||
BTextControl::MessageReceived(msg);
|
||||
|
||||
MakeFocus();
|
||||
} else
|
||||
BTextControl::MessageReceived(msg);
|
||||
}
|
||||
|
||||
private:
|
||||
bool dir_ctrl;
|
||||
};
|
||||
|
||||
|
||||
// Preferences window class
|
||||
class PrefsWindow : public BWindow {
|
||||
public:
|
||||
PrefsWindow(uint32 msg);
|
||||
virtual ~PrefsWindow();
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
|
||||
private:
|
||||
BView *create_volumes_pane(void);
|
||||
BView *create_graphics_pane(void);
|
||||
BView *create_serial_pane(void);
|
||||
BView *create_memory_pane(void);
|
||||
|
||||
uint32 ok_message;
|
||||
bool send_quit_on_close;
|
||||
|
||||
BMessenger this_messenger;
|
||||
BView *top;
|
||||
BRect top_frame;
|
||||
BTabView *pane_tabs;
|
||||
BView *panes[NUM_PANES];
|
||||
int current_pane;
|
||||
|
||||
VolumeListView *volume_list;
|
||||
BCheckBox *nocdrom_checkbox;
|
||||
BCheckBox *gfxaccel_checkbox;
|
||||
BCheckBox *nosound_checkbox;
|
||||
BCheckBox *nonet_checkbox;
|
||||
BCheckBox *ignoresegv_checkbox;
|
||||
BCheckBox *idlewait_checkbox;
|
||||
RAMSlider *ramsize_slider;
|
||||
PathControl *extfs_control;
|
||||
PathControl *rom_control;
|
||||
|
||||
BFilePanel *add_volume_panel;
|
||||
BFilePanel *create_volume_panel;
|
||||
|
||||
uint32 max_ramsize; // In MB
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Show preferences editor
|
||||
* When the user clicks on "OK", the message given as parameter is sent
|
||||
* to the application; if he clicks on "Quit", B_QUIT_REQUESTED is sent
|
||||
*/
|
||||
|
||||
void PrefsEditor(uint32 msg)
|
||||
{
|
||||
new PrefsWindow(msg);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Preferences window constructor
|
||||
*/
|
||||
|
||||
PrefsWindow::PrefsWindow(uint32 msg) : BWindow(BRect(0, 0, 400, 289), GetString(STR_PREFS_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), this_messenger(this)
|
||||
{
|
||||
int i;
|
||||
ok_message = msg;
|
||||
send_quit_on_close = true;
|
||||
|
||||
// Move window to right position
|
||||
Lock();
|
||||
MoveTo(80, 80);
|
||||
|
||||
// Set up menus
|
||||
BMenuBar *bar = new BMenuBar(Bounds(), "menu");
|
||||
BMenu *menu = new BMenu(GetString(STR_PREFS_MENU));
|
||||
menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ABOUT), new BMessage(B_ABOUT_REQUESTED)));
|
||||
menu->AddItem(new BSeparatorItem);
|
||||
menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_START), new BMessage(MSG_OK)));
|
||||
menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ZAP_PRAM), new BMessage(MSG_ZAP_PRAM)));
|
||||
menu->AddItem(new BSeparatorItem);
|
||||
menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_QUIT), new BMessage(MSG_CANCEL), 'Q'));
|
||||
bar->AddItem(menu);
|
||||
AddChild(bar);
|
||||
SetKeyMenuBar(bar);
|
||||
int mbar_height = bar->Bounds().bottom + 1;
|
||||
|
||||
// Resize window to fit menu bar
|
||||
ResizeBy(0, mbar_height);
|
||||
|
||||
// Light gray background
|
||||
BRect b = Bounds();
|
||||
top = new BView(BRect(0, mbar_height, b.right, b.bottom), "top", B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
AddChild(top);
|
||||
top->SetViewColor(fill_color);
|
||||
top_frame = top->Bounds();
|
||||
|
||||
// Create panes
|
||||
panes[0] = create_volumes_pane();
|
||||
panes[1] = create_graphics_pane();
|
||||
panes[2] = create_serial_pane();
|
||||
panes[3] = create_memory_pane();
|
||||
|
||||
// Prefs item tab view
|
||||
pane_tabs = new BTabView(BRect(10, 10, top_frame.right-10, top_frame.bottom-50), "items", B_WIDTH_FROM_LABEL);
|
||||
for (i=0; i<NUM_PANES; i++)
|
||||
pane_tabs->AddTab(panes[i]);
|
||||
top->AddChild(pane_tabs);
|
||||
|
||||
volume_list->Select(0);
|
||||
|
||||
// Create volume file panels
|
||||
add_volume_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_ADD_VOLUME_PANEL));
|
||||
add_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_ADD_VOLUME_PANEL_BUTTON));
|
||||
add_volume_panel->Window()->SetTitle(GetString(STR_ADD_VOLUME_TITLE));
|
||||
create_volume_panel = new BFilePanel(B_SAVE_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_CREATE_VOLUME_PANEL));
|
||||
create_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_CREATE_VOLUME_PANEL_BUTTON));
|
||||
create_volume_panel->Window()->SetTitle(GetString(STR_CREATE_VOLUME_TITLE));
|
||||
|
||||
create_volume_panel->Window()->Lock();
|
||||
BView *background = create_volume_panel->Window()->ChildAt(0);
|
||||
background->FindView("PoseView")->ResizeBy(0, -30);
|
||||
background->FindView("VScrollBar")->ResizeBy(0, -30);
|
||||
background->FindView("CountVw")->MoveBy(0, -30);
|
||||
BView *v = background->FindView("HScrollBar");
|
||||
if (v)
|
||||
v->MoveBy(0, -30);
|
||||
else {
|
||||
i = 0;
|
||||
while ((v = background->ChildAt(i++)) != NULL) {
|
||||
if (v->Name() == NULL || v->Name()[0] == 0) {
|
||||
v->MoveBy(0, -30); // unnamed horizontal scroll bar
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
BView *filename = background->FindView("text view");
|
||||
BRect fnr(filename->Frame());
|
||||
fnr.OffsetBy(0, -30);
|
||||
NumberControl *nc = new NumberControl(fnr, 80, "hardfile_size", GetString(STR_HARDFILE_SIZE_CTRL), 40, NULL);
|
||||
background->AddChild(nc);
|
||||
create_volume_panel->Window()->Unlock();
|
||||
|
||||
// "Start" button
|
||||
BButton *button = new BButton(BRect(20, top_frame.bottom-35, 90, top_frame.bottom-10), "start", GetString(STR_START_BUTTON), new BMessage(MSG_OK));
|
||||
top->AddChild(button);
|
||||
SetDefaultButton(button);
|
||||
|
||||
// "Quit" button
|
||||
top->AddChild(new BButton(BRect(top_frame.right-90, top_frame.bottom-35, top_frame.right-20, top_frame.bottom-10), "cancel", GetString(STR_QUIT_BUTTON), new BMessage(MSG_CANCEL)));
|
||||
|
||||
Unlock();
|
||||
Show();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Preferences window destructor
|
||||
*/
|
||||
|
||||
PrefsWindow::~PrefsWindow()
|
||||
{
|
||||
delete add_volume_panel;
|
||||
if (send_quit_on_close)
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create "Volumes" pane
|
||||
*/
|
||||
|
||||
BView *PrefsWindow::create_volumes_pane(void)
|
||||
{
|
||||
BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_VOLUMES_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
pane->SetViewColor(fill_color);
|
||||
float right = pane->Bounds().right-10;
|
||||
|
||||
const char *str;
|
||||
int32 index = 0;
|
||||
volume_list = new VolumeListView(BRect(15, 10, pane->Bounds().right-30, 108), "volumes");
|
||||
while ((str = PrefsFindString("disk", index++)) != NULL)
|
||||
volume_list->AddItem(new BStringItem(str));
|
||||
volume_list->SetSelectionMessage(new BMessage(MSG_VOLUME_SELECTED));
|
||||
volume_list->SetInvocationMessage(new BMessage(MSG_VOLUME_INVOKED));
|
||||
pane->AddChild(new BScrollView("volumes_border", volume_list, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true));
|
||||
|
||||
pane->AddChild(new BButton(BRect(10, 113, pane->Bounds().right/3, 133), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME)));
|
||||
pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 113, pane->Bounds().right*2/3, 133), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME)));
|
||||
pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 113, pane->Bounds().right-11, 133), "remove_volume", GetString(STR_REMOVE_VOLUME_BUTTON), new BMessage(MSG_REMOVE_VOLUME)));
|
||||
|
||||
extfs_control = new PathControl(true, BRect(10, 145, right, 160), "extfs", GetString(STR_EXTFS_CTRL), PrefsFindString("extfs"), NULL);
|
||||
extfs_control->SetDivider(90);
|
||||
pane->AddChild(extfs_control);
|
||||
|
||||
BMenuField *menu_field;
|
||||
BPopUpMenu *menu = new BPopUpMenu("");
|
||||
menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu);
|
||||
menu_field->SetDivider(90);
|
||||
menu->AddItem(new BMenuItem(GetString(STR_BOOT_ANY_LAB), new BMessage(MSG_BOOT_ANY)));
|
||||
menu->AddItem(new BMenuItem(GetString(STR_BOOT_CDROM_LAB), new BMessage(MSG_BOOT_CDROM)));
|
||||
pane->AddChild(menu_field);
|
||||
int16 i16 = PrefsFindInt32("bootdriver");
|
||||
BMenuItem *item;
|
||||
if (i16 == 0) {
|
||||
if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (i16 == CDROMRefNum) {
|
||||
if ((item = menu->FindItem(GetString(STR_BOOT_CDROM_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
|
||||
nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM));
|
||||
pane->AddChild(nocdrom_checkbox);
|
||||
nocdrom_checkbox->SetValue(PrefsFindBool("nocdrom") ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create "Graphics/Sound" pane
|
||||
*/
|
||||
|
||||
struct video_mode_box {
|
||||
uint32 mode;
|
||||
int mode_string_id, bit_string_id;
|
||||
float left, top;
|
||||
BCheckBox *box;
|
||||
};
|
||||
|
||||
const int NUM_WINDOW_MODES = 6;
|
||||
const int NUM_SCREEN_MODES = 18;
|
||||
|
||||
static video_mode_box window_mode_boxes[NUM_SCREEN_MODES] = {
|
||||
{B_8_BIT_640x480, STR_W_640x480_CTRL, STR_8_BIT_CTRL, 140, 48, NULL},
|
||||
{B_15_BIT_640x480, STR_W_640x480_CTRL, STR_16_BIT_CTRL, 220, 48, NULL},
|
||||
{B_32_BIT_640x480, STR_W_640x480_CTRL, STR_32_BIT_CTRL, 300, 48, NULL},
|
||||
{B_8_BIT_800x600, STR_W_800x600_CTRL, STR_8_BIT_CTRL, 140, 65, NULL},
|
||||
{B_15_BIT_800x600, STR_W_800x600_CTRL, STR_16_BIT_CTRL, 220, 65, NULL},
|
||||
{B_32_BIT_800x600, STR_W_800x600_CTRL, STR_32_BIT_CTRL, 300, 65, NULL},
|
||||
};
|
||||
|
||||
static video_mode_box screen_mode_boxes[NUM_SCREEN_MODES] = {
|
||||
{B_8_BIT_640x480, STR_640x480_CTRL, STR_8_BIT_CTRL, 140, 82, NULL},
|
||||
{B_15_BIT_640x480, STR_640x480_CTRL, STR_16_BIT_CTRL, 220, 82, NULL},
|
||||
{B_32_BIT_640x480, STR_640x480_CTRL, STR_32_BIT_CTRL, 300, 82, NULL},
|
||||
{B_8_BIT_800x600, STR_800x600_CTRL, STR_8_BIT_CTRL, 140, 99, NULL},
|
||||
{B_15_BIT_800x600, STR_800x600_CTRL, STR_16_BIT_CTRL, 220, 99, NULL},
|
||||
{B_32_BIT_800x600, STR_800x600_CTRL, STR_32_BIT_CTRL, 300, 99, NULL},
|
||||
{B_8_BIT_1024x768, STR_1024x768_CTRL, STR_8_BIT_CTRL, 140, 116, NULL},
|
||||
{B_15_BIT_1024x768, STR_1024x768_CTRL, STR_16_BIT_CTRL, 220, 116, NULL},
|
||||
{B_32_BIT_1024x768, STR_1024x768_CTRL, STR_32_BIT_CTRL, 300, 116, NULL},
|
||||
{B_8_BIT_1152x900, STR_1152x900_CTRL, STR_8_BIT_CTRL, 140, 133, NULL},
|
||||
{B_15_BIT_1152x900, STR_1152x900_CTRL, STR_16_BIT_CTRL, 220, 133, NULL},
|
||||
{B_32_BIT_1152x900, STR_1152x900_CTRL, STR_32_BIT_CTRL, 300, 133, NULL},
|
||||
{B_8_BIT_1280x1024, STR_1280x1024_CTRL, STR_8_BIT_CTRL, 140, 150, NULL},
|
||||
{B_15_BIT_1280x1024, STR_1280x1024_CTRL, STR_16_BIT_CTRL, 220, 150, NULL},
|
||||
{B_32_BIT_1280x1024, STR_1280x1024_CTRL, STR_32_BIT_CTRL, 300, 150, NULL},
|
||||
{B_8_BIT_1600x1200, STR_1600x1200_CTRL, STR_8_BIT_CTRL, 140, 167, NULL},
|
||||
{B_15_BIT_1600x1200, STR_1600x1200_CTRL, STR_16_BIT_CTRL, 220, 167, NULL},
|
||||
{B_32_BIT_1600x1200, STR_1600x1200_CTRL, STR_32_BIT_CTRL, 300, 167, NULL}
|
||||
};
|
||||
|
||||
BView *PrefsWindow::create_graphics_pane(void)
|
||||
{
|
||||
BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_GRAPHICS_SOUND_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
pane->SetViewColor(fill_color);
|
||||
float right = pane->Bounds().right-10;
|
||||
|
||||
BMenuField *menu_field;
|
||||
BPopUpMenu *menu = new BPopUpMenu("");
|
||||
menu_field = new BMenuField(BRect(10, 5, right, 20), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu);
|
||||
menu_field->SetDivider(120);
|
||||
menu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ)));
|
||||
menu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ)));
|
||||
menu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ)));
|
||||
menu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ)));
|
||||
menu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ)));
|
||||
pane->AddChild(menu_field);
|
||||
int32 i32 = PrefsFindInt32("frameskip");
|
||||
BMenuItem *item;
|
||||
if (i32 == 12) {
|
||||
if ((item = menu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (i32 == 8) {
|
||||
if ((item = menu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (i32 == 6) {
|
||||
if ((item = menu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (i32 == 4) {
|
||||
if ((item = menu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (i32 == 2) {
|
||||
if ((item = menu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
|
||||
gfxaccel_checkbox = new BCheckBox(BRect(10, 25, right, 40), "gfxaccel", GetString(STR_GFXACCEL_CTRL), new BMessage(MSG_GFXACCEL));
|
||||
pane->AddChild(gfxaccel_checkbox);
|
||||
gfxaccel_checkbox->SetValue(PrefsFindBool("gfxaccel") ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
|
||||
uint32 window_modes = PrefsFindInt32("windowmodes");
|
||||
for (int i=0; i<NUM_WINDOW_MODES; i++) {
|
||||
video_mode_box *p = window_mode_boxes + i;
|
||||
if (p->bit_string_id == STR_8_BIT_CTRL) {
|
||||
BStringView *text = new BStringView(BRect(10, p->top, 120, p->top + 15), "", GetString(p->mode_string_id));
|
||||
pane->AddChild(text);
|
||||
}
|
||||
p->box = new BCheckBox(BRect(p->left, p->top, p->left + 80, p->top + 15), "", GetString(p->bit_string_id), new BMessage(MSG_WINDOW_MODE));
|
||||
pane->AddChild(p->box);
|
||||
p->box->SetValue(window_modes & p->mode ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
}
|
||||
uint32 screen_modes = PrefsFindInt32("screenmodes");
|
||||
for (int i=0; i<NUM_SCREEN_MODES; i++) {
|
||||
video_mode_box *p = screen_mode_boxes + i;
|
||||
if (p->bit_string_id == STR_8_BIT_CTRL) {
|
||||
BStringView *text = new BStringView(BRect(10, p->top, 120, p->top + 15), "", GetString(p->mode_string_id));
|
||||
pane->AddChild(text);
|
||||
}
|
||||
p->box = new BCheckBox(BRect(p->left, p->top, p->left + 80, p->top + 15), "", GetString(p->bit_string_id), new BMessage(MSG_SCREEN_MODE));
|
||||
pane->AddChild(p->box);
|
||||
p->box->SetValue(screen_modes & p->mode ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
}
|
||||
|
||||
nosound_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND));
|
||||
pane->AddChild(nosound_checkbox);
|
||||
nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create "Serial/Network" pane
|
||||
*/
|
||||
|
||||
static void add_serial_names(BPopUpMenu *menu, uint32 msg)
|
||||
{
|
||||
BSerialPort *port = new BSerialPort;
|
||||
char name[B_PATH_NAME_LENGTH];
|
||||
for (int i=0; i<port->CountDevices(); i++) {
|
||||
port->GetDeviceName(i, name);
|
||||
menu->AddItem(new BMenuItem(name, new BMessage(msg)));
|
||||
}
|
||||
if (SysInfo.platform_type == B_BEBOX_PLATFORM) {
|
||||
BDirectory dir;
|
||||
BEntry entry;
|
||||
dir.SetTo("/dev/parallel");
|
||||
if (dir.InitCheck() == B_NO_ERROR) {
|
||||
dir.Rewind();
|
||||
while (dir.GetNextEntry(&entry) >= 0) {
|
||||
if (!entry.IsDirectory()) {
|
||||
entry.GetName(name);
|
||||
menu->AddItem(new BMenuItem(name, new BMessage(msg)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete port;
|
||||
}
|
||||
|
||||
static void set_serial_label(BPopUpMenu *menu, const char *prefs_name)
|
||||
{
|
||||
const char *str;
|
||||
BMenuItem *item;
|
||||
if ((str = PrefsFindString(prefs_name)) != NULL)
|
||||
if ((item = menu->FindItem(str)) != NULL)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
|
||||
BView *PrefsWindow::create_serial_pane(void)
|
||||
{
|
||||
BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_SERIAL_NETWORK_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
pane->SetViewColor(fill_color);
|
||||
float right = pane->Bounds().right-10;
|
||||
|
||||
BMenuField *menu_field;
|
||||
BPopUpMenu *menu_a = new BPopUpMenu("");
|
||||
add_serial_names(menu_a, MSG_SER_A);
|
||||
menu_field = new BMenuField(BRect(10, 5, right, 20), "seriala", GetString(STR_SERPORTA_CTRL), menu_a);
|
||||
menu_field->SetDivider(90);
|
||||
pane->AddChild(menu_field);
|
||||
set_serial_label(menu_a, "seriala");
|
||||
|
||||
BPopUpMenu *menu_b = new BPopUpMenu("");
|
||||
add_serial_names(menu_b, MSG_SER_B);
|
||||
menu_field = new BMenuField(BRect(10, 26, right, 41), "serialb", GetString(STR_SERPORTB_CTRL), menu_b);
|
||||
menu_field->SetDivider(90);
|
||||
pane->AddChild(menu_field);
|
||||
set_serial_label(menu_b, "serialb");
|
||||
|
||||
nonet_checkbox = new BCheckBox(BRect(10, 47, right, 62), "nonet", GetString(STR_NONET_CTRL), new BMessage(MSG_NONET));
|
||||
pane->AddChild(nonet_checkbox);
|
||||
nonet_checkbox->SetValue(PrefsFindBool("nonet") ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create "Memory/Misc" pane
|
||||
*/
|
||||
|
||||
BView *PrefsWindow::create_memory_pane(void)
|
||||
{
|
||||
char str[256], str2[256];
|
||||
BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_MEMORY_MISC_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
pane->SetViewColor(fill_color);
|
||||
float right = pane->Bounds().right-10;
|
||||
|
||||
BEntry entry("/boot/var/swap");
|
||||
off_t swap_space;
|
||||
if (entry.GetSize(&swap_space) == B_NO_ERROR)
|
||||
max_ramsize = swap_space / (1024 * 1024) - 8;
|
||||
else
|
||||
max_ramsize = SysInfo.max_pages * B_PAGE_SIZE / (1024 * 1024) - 8;
|
||||
|
||||
int32 value = PrefsFindInt32("ramsize") / (1024 * 1024);
|
||||
|
||||
ramsize_slider = new RAMSlider(BRect(10, 5, right, 55), "ramsize", GetString(STR_RAMSIZE_SLIDER), new BMessage(MSG_RAMSIZE), 8, max_ramsize, B_TRIANGLE_THUMB);
|
||||
ramsize_slider->SetValue(value);
|
||||
ramsize_slider->UseFillColor(true, &slider_fill_color);
|
||||
sprintf(str, GetString(STR_RAMSIZE_FMT), 8);
|
||||
sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize);
|
||||
ramsize_slider->SetLimitLabels(str, str2);
|
||||
pane->AddChild(ramsize_slider);
|
||||
|
||||
ignoresegv_checkbox = new BCheckBox(BRect(10, 60, right, 75), "ignoresegv", GetString(STR_IGNORESEGV_CTRL), new BMessage(MSG_IGNORESEGV));
|
||||
pane->AddChild(ignoresegv_checkbox);
|
||||
ignoresegv_checkbox->SetValue(PrefsFindBool("ignoresegv") ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
|
||||
idlewait_checkbox = new BCheckBox(BRect(10, 80, right, 95), "idlewait", GetString(STR_IDLEWAIT_CTRL), new BMessage(MSG_IDLEWAIT));
|
||||
pane->AddChild(idlewait_checkbox);
|
||||
idlewait_checkbox->SetValue(PrefsFindBool("idlewait") ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
|
||||
rom_control = new PathControl(false, BRect(10, 100, right, 115), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL);
|
||||
rom_control->SetDivider(117);
|
||||
pane->AddChild(rom_control);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Message from controls/menus received
|
||||
*/
|
||||
|
||||
void PrefsWindow::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case MSG_OK: // "Start" button clicked
|
||||
PrefsReplaceString("extfs", extfs_control->Text());
|
||||
const char *str = rom_control->Text();
|
||||
if (strlen(str))
|
||||
PrefsReplaceString("rom", str);
|
||||
else
|
||||
PrefsRemoveItem("rom");
|
||||
SavePrefs();
|
||||
send_quit_on_close = false;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
be_app->PostMessage(ok_message);
|
||||
break;
|
||||
|
||||
case MSG_CANCEL: // "Quit" button clicked
|
||||
send_quit_on_close = false;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
|
||||
case B_ABOUT_REQUESTED: // "About" menu item selected
|
||||
OpenAboutWindow();
|
||||
break;
|
||||
|
||||
case MSG_ZAP_PRAM: // "Zap PRAM File" menu item selected
|
||||
ZapPRAM();
|
||||
break;
|
||||
|
||||
case MSG_VOLUME_INVOKED: { // Double-clicked on volume name, toggle read-only flag
|
||||
int selected = volume_list->CurrentSelection();
|
||||
if (selected >= 0) {
|
||||
const char *str = PrefsFindString("disk", selected);
|
||||
BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected);
|
||||
delete item;
|
||||
char newstr[256];
|
||||
if (str[0] == '*')
|
||||
strcpy(newstr, str+1);
|
||||
else {
|
||||
strcpy(newstr, "*");
|
||||
strcat(newstr, str);
|
||||
}
|
||||
PrefsReplaceString("disk", newstr, selected);
|
||||
volume_list->AddItem(new BStringItem(newstr), selected);
|
||||
volume_list->Select(selected);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_ADD_VOLUME:
|
||||
add_volume_panel->Show();
|
||||
break;
|
||||
|
||||
case MSG_CREATE_VOLUME:
|
||||
create_volume_panel->Show();
|
||||
break;
|
||||
|
||||
case MSG_ADD_VOLUME_PANEL: {
|
||||
entry_ref ref;
|
||||
if (msg->FindRef("refs", &ref) == B_NO_ERROR) {
|
||||
BEntry entry(&ref, true);
|
||||
BPath path;
|
||||
entry.GetPath(&path);
|
||||
if (entry.IsFile()) {
|
||||
PrefsAddString("disk", path.Path());
|
||||
volume_list->AddItem(new BStringItem(path.Path()));
|
||||
} else if (entry.IsDirectory()) {
|
||||
BVolume volume;
|
||||
if (path.Path()[0] == '/' && strchr(path.Path()+1, '/') == NULL && entry.GetVolume(&volume) == B_NO_ERROR) {
|
||||
int32 i = 0;
|
||||
dev_t d;
|
||||
fs_info info;
|
||||
while ((d = next_dev(&i)) >= 0) {
|
||||
fs_stat_dev(d, &info);
|
||||
if (volume.Device() == info.dev) {
|
||||
PrefsAddString("disk", info.device_name);
|
||||
volume_list->AddItem(new BStringItem(info.device_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_CREATE_VOLUME_PANEL: {
|
||||
entry_ref dir;
|
||||
if (msg->FindRef("directory", &dir) == B_NO_ERROR) {
|
||||
BEntry entry(&dir, true);
|
||||
BPath path;
|
||||
entry.GetPath(&path);
|
||||
path.Append(msg->FindString("name"));
|
||||
|
||||
create_volume_panel->Window()->Lock();
|
||||
BView *background = create_volume_panel->Window()->ChildAt(0);
|
||||
NumberControl *v = (NumberControl *)background->FindView("hardfile_size");
|
||||
int size = v->Value();
|
||||
|
||||
char cmd[1024];
|
||||
sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", path.Path(), size);
|
||||
int ret = system(cmd);
|
||||
if (ret == 0) {
|
||||
PrefsAddString("disk", path.Path());
|
||||
volume_list->AddItem(new BStringItem(path.Path()));
|
||||
} else {
|
||||
sprintf(cmd, GetString(STR_CREATE_VOLUME_WARN), strerror(ret));
|
||||
WarningAlert(cmd);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_REMOVE_VOLUME: {
|
||||
int selected = volume_list->CurrentSelection();
|
||||
if (selected >= 0) {
|
||||
PrefsRemoveItem("disk", selected);
|
||||
BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected);
|
||||
delete item;
|
||||
volume_list->Select(selected);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_BOOT_ANY:
|
||||
PrefsReplaceInt32("bootdriver", 0);
|
||||
break;
|
||||
|
||||
case MSG_BOOT_CDROM:
|
||||
PrefsReplaceInt32("bootdriver", CDROMRefNum);
|
||||
break;
|
||||
|
||||
case MSG_NOCDROM:
|
||||
PrefsReplaceBool("nocdrom", nocdrom_checkbox->Value() == B_CONTROL_ON);
|
||||
break;
|
||||
|
||||
case MSG_GFXACCEL:
|
||||
PrefsReplaceBool("gfxaccel", gfxaccel_checkbox->Value() == B_CONTROL_ON);
|
||||
break;
|
||||
|
||||
case MSG_NOSOUND:
|
||||
PrefsReplaceBool("nosound", nosound_checkbox->Value() == B_CONTROL_ON);
|
||||
break;
|
||||
|
||||
case MSG_WINDOW_MODE: {
|
||||
BCheckBox *source = NULL;
|
||||
msg->FindPointer("source", &source);
|
||||
if (source == NULL)
|
||||
break;
|
||||
for (int i=0; i<NUM_WINDOW_MODES; i++) {
|
||||
video_mode_box *p = window_mode_boxes + i;
|
||||
if (p->box == source) {
|
||||
if (p->box->Value() == B_CONTROL_ON)
|
||||
PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") | p->mode);
|
||||
else
|
||||
PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") & ~(p->mode));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_SCREEN_MODE: {
|
||||
BCheckBox *source = NULL;
|
||||
msg->FindPointer("source", &source);
|
||||
if (source == NULL)
|
||||
break;
|
||||
for (int i=0; i<NUM_SCREEN_MODES; i++) {
|
||||
video_mode_box *p = screen_mode_boxes + i;
|
||||
if (p->box == source) {
|
||||
if (p->box->Value() == B_CONTROL_ON)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | p->mode);
|
||||
else
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~(p->mode));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_REF_5HZ:
|
||||
PrefsReplaceInt32("frameskip", 12);
|
||||
break;
|
||||
|
||||
case MSG_REF_7_5HZ:
|
||||
PrefsReplaceInt32("frameskip", 8);
|
||||
break;
|
||||
|
||||
case MSG_REF_10HZ:
|
||||
PrefsReplaceInt32("frameskip", 6);
|
||||
break;
|
||||
|
||||
case MSG_REF_15HZ:
|
||||
PrefsReplaceInt32("frameskip", 4);
|
||||
break;
|
||||
|
||||
case MSG_REF_30HZ:
|
||||
PrefsReplaceInt32("frameskip", 2);
|
||||
break;
|
||||
|
||||
case MSG_SER_A: {
|
||||
BMenuItem *source = NULL;
|
||||
msg->FindPointer("source", &source);
|
||||
if (source)
|
||||
PrefsReplaceString("seriala", source->Label());
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_SER_B: {
|
||||
BMenuItem *source = NULL;
|
||||
msg->FindPointer("source", &source);
|
||||
if (source)
|
||||
PrefsReplaceString("serialb", source->Label());
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_NONET:
|
||||
PrefsReplaceBool("nonet", nonet_checkbox->Value() == B_CONTROL_ON);
|
||||
break;
|
||||
|
||||
case MSG_IGNORESEGV:
|
||||
PrefsReplaceBool("ignoresegv", ignoresegv_checkbox->Value() == B_CONTROL_ON);
|
||||
break;
|
||||
|
||||
case MSG_IDLEWAIT:
|
||||
PrefsReplaceBool("idlewait", idlewait_checkbox->Value() == B_CONTROL_ON);
|
||||
break;
|
||||
|
||||
case MSG_RAMSIZE:
|
||||
PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
55
SheepShaver/src/BeOS/sysdeps.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* sysdeps.h - System dependent definitions for BeOS
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 SYSDEPS_H
|
||||
#define SYSDEPS_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <KernelKit.h>
|
||||
|
||||
#include "user_strings_beos.h"
|
||||
|
||||
// Are we using a PPC emulator or the real thing?
|
||||
#ifdef __POWERPC__
|
||||
#define EMULATED_PPC 0
|
||||
#else
|
||||
#define EMULATED_PPC 1
|
||||
#endif
|
||||
|
||||
#define POWERPC_ROM 1
|
||||
|
||||
// Time data type for Time Manager emulation
|
||||
typedef bigtime_t tm_time_t;
|
||||
|
||||
// 64 bit file offsets
|
||||
typedef off_t loff_t;
|
||||
|
||||
// Macro for calling MacOS routines
|
||||
#define CallMacOS(type, proc) (*(type)proc)()
|
||||
#define CallMacOS1(type, proc, arg1) (*(type)proc)(arg1)
|
||||
#define CallMacOS2(type, proc, arg1, arg2) (*(type)proc)(arg1, arg2)
|
||||
#define CallMacOS3(type, proc, arg1, arg2, arg3) (*(type)proc)(arg1, arg2, arg3)
|
||||
#define CallMacOS4(type, proc, arg1, arg2, arg3, arg4) (*(type)proc)(arg1, arg2, arg3, arg4)
|
||||
#define CallMacOS5(type, proc, arg1, arg2, arg3, arg4, arg5) (*(type)proc)(arg1, arg2, arg3, arg4, arg5)
|
||||
#define CallMacOS6(type, proc, arg1, arg2, arg3, arg4, arg5, arg6) (*(type)proc)(arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
#define CallMacOS7(type, proc, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (*(type)proc)(arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
|
||||
#endif
|
69
SheepShaver/src/BeOS/user_strings_beos.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* user_strings_beos.cpp - Localizable strings, BeOS specific strings
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "user_strings.h"
|
||||
|
||||
|
||||
// Platform-specific string definitions
|
||||
user_string_def platform_strings[] = {
|
||||
// Common strings that have a platform-specific variant
|
||||
{STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under BeOS. Basilisk II will try to unmount it."},
|
||||
{STR_EXTFS_CTRL, "BeOS Root"},
|
||||
{STR_EXTFS_NAME, "BeOS Directory Tree"},
|
||||
{STR_EXTFS_VOLUME_NAME, "BeOS"},
|
||||
|
||||
// Purely platform-specific strings
|
||||
{STR_NO_SHEEP_DRIVER_ERR, "Cannot open /dev/sheep: %s (%08x). SheepShaver is not properly installed."},
|
||||
{STR_NO_RAM_AREA_ERR, "Not enough memory to create RAM area: %s (%08x)."},
|
||||
{STR_NO_ROM_AREA_ERR, "Not enough memory to create ROM area."},
|
||||
{STR_SHEEP_UP_ERR, "Cannot allocate Low Memory Globals: %s (%08x)."},
|
||||
{STR_NO_NET_ADDON_WARN, "The SheepShaver net server add-on cannot be found. Ethernet will not be available."},
|
||||
{STR_NET_CONFIG_MODIFY_WARN, "To enable Ethernet networking for SheepShaver, your network configuration has to be modified and the network restarted. Do you want this to be done now (selecting \"Cancel\" will disable Ethernet under SheepShaver)?."},
|
||||
{STR_NET_ADDON_INIT_FAILED, "SheepShaver net server add-on found\nbut there seems to be no network hardware.\nPlease check your network preferences."},
|
||||
{STR_NET_ADDON_CLONE_FAILED, "Cloning of the network transfer area failed."},
|
||||
|
||||
{-1, NULL} // End marker
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Fetch pointer to string, given the string number
|
||||
*/
|
||||
|
||||
const char *GetString(int num)
|
||||
{
|
||||
// First search for platform-specific string
|
||||
int i = 0;
|
||||
while (platform_strings[i].num >= 0) {
|
||||
if (platform_strings[i].num == num)
|
||||
return platform_strings[i].str;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Not found, search for common string
|
||||
i = 0;
|
||||
while (common_strings[i].num >= 0) {
|
||||
if (common_strings[i].num == num)
|
||||
return common_strings[i].str;
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
34
SheepShaver/src/BeOS/user_strings_beos.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* user_strings_beos.h - BeOS-specific localizable strings
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 USER_STRINGS_BEOS_H
|
||||
#define USER_STRINGS_BEOS_H
|
||||
|
||||
enum {
|
||||
STR_NO_SHEEP_DRIVER_ERR = 10000,
|
||||
STR_NO_ROM_AREA_ERR,
|
||||
STR_SHEEP_UP_ERR,
|
||||
STR_NO_NET_ADDON_WARN,
|
||||
STR_NET_CONFIG_MODIFY_WARN,
|
||||
STR_NET_ADDON_INIT_FAILED,
|
||||
STR_NET_ADDON_CLONE_FAILED
|
||||
};
|
||||
|
||||
#endif
|
768
SheepShaver/src/BeOS/video_beos.cpp
Normal file
@ -0,0 +1,768 @@
|
||||
/*
|
||||
* video_beos.cpp - Video/graphics emulation, BeOS specific things
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "video_defs.h"
|
||||
#include "main.h"
|
||||
#include "adb.h"
|
||||
#include "prefs.h"
|
||||
#include "user_strings.h"
|
||||
#include "about_window.h"
|
||||
#include "version.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
// Global variables
|
||||
static sem_id video_lock = -1; // Protection during mode changes
|
||||
static sem_id mac_os_lock = -1; // This is used to stop the MacOS thread when the SheepShaver workspace is switched out
|
||||
|
||||
// Prototypes
|
||||
static filter_result filter_func(BMessage *msg, BHandler **target, BMessageFilter *filter);
|
||||
|
||||
// From sys_beos.cpp
|
||||
extern void SysCreateVolumeMenu(BMenu *menu, uint32 msg);
|
||||
extern void SysMountVolume(const char *name);
|
||||
|
||||
|
||||
#include "video_window.h"
|
||||
#include "video_screen.h"
|
||||
|
||||
|
||||
/*
|
||||
* Display manager thread (for opening and closing windows and screens;
|
||||
* this is not safe under R4 when running on the MacOS stack in kernel
|
||||
* space)
|
||||
*/
|
||||
|
||||
// Message constants
|
||||
const uint32 MSG_OPEN_WINDOW = 'owin';
|
||||
const uint32 MSG_CLOSE_WINDOW = 'cwin';
|
||||
const uint32 MSG_OPEN_SCREEN = 'oscr';
|
||||
const uint32 MSG_CLOSE_SCREEN = 'cscr';
|
||||
const uint32 MSG_QUIT_DISPLAY_MANAGER = 'quit';
|
||||
|
||||
static thread_id dm_thread = -1;
|
||||
static sem_id dm_done_sem = -1;
|
||||
|
||||
static status_t display_manager(void *arg)
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
// Receive message
|
||||
thread_id sender;
|
||||
uint32 code = receive_data(&sender, NULL, 0);
|
||||
D(bug("Display manager received %08lx\n", code));
|
||||
switch (code) {
|
||||
case MSG_QUIT_DISPLAY_MANAGER:
|
||||
return 0;
|
||||
|
||||
case MSG_OPEN_WINDOW:
|
||||
D(bug("Opening window\n"));
|
||||
the_window = new MacWindow(BRect(0, 0, VModes[cur_mode].viXsize-1, VModes[cur_mode].viYsize-1));
|
||||
D(bug("Opened\n"));
|
||||
break;
|
||||
|
||||
case MSG_CLOSE_WINDOW:
|
||||
if (the_window != NULL) {
|
||||
D(bug("Posting quit to window\n"));
|
||||
the_window->PostMessage(B_QUIT_REQUESTED);
|
||||
D(bug("Posted, waiting\n"));
|
||||
while (the_window)
|
||||
snooze(200000);
|
||||
D(bug("Window closed\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_OPEN_SCREEN: {
|
||||
D(bug("Opening screen\n"));
|
||||
long scr_mode = 0;
|
||||
switch (VModes[cur_mode].viAppleMode) {
|
||||
case APPLE_8_BIT:
|
||||
switch (VModes[cur_mode].viAppleID) {
|
||||
case APPLE_640x480:
|
||||
scr_mode = B_8_BIT_640x480;
|
||||
break;
|
||||
case APPLE_800x600:
|
||||
scr_mode = B_8_BIT_800x600;
|
||||
break;
|
||||
case APPLE_1024x768:
|
||||
scr_mode = B_8_BIT_1024x768;
|
||||
break;
|
||||
case APPLE_1152x900:
|
||||
scr_mode = B_8_BIT_1152x900;
|
||||
break;
|
||||
case APPLE_1280x1024:
|
||||
scr_mode = B_8_BIT_1280x1024;
|
||||
break;
|
||||
case APPLE_1600x1200:
|
||||
scr_mode = B_8_BIT_1600x1200;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case APPLE_16_BIT:
|
||||
switch (VModes[cur_mode].viAppleID) {
|
||||
case APPLE_640x480:
|
||||
scr_mode = B_15_BIT_640x480;
|
||||
break;
|
||||
case APPLE_800x600:
|
||||
scr_mode = B_15_BIT_800x600;
|
||||
break;
|
||||
case APPLE_1024x768:
|
||||
scr_mode = B_15_BIT_1024x768;
|
||||
break;
|
||||
case APPLE_1152x900:
|
||||
scr_mode = B_15_BIT_1152x900;
|
||||
break;
|
||||
case APPLE_1280x1024:
|
||||
scr_mode = B_15_BIT_1280x1024;
|
||||
break;
|
||||
case APPLE_1600x1200:
|
||||
scr_mode = B_15_BIT_1600x1200;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case APPLE_32_BIT:
|
||||
switch (VModes[cur_mode].viAppleID) {
|
||||
case APPLE_640x480:
|
||||
scr_mode = B_32_BIT_640x480;
|
||||
break;
|
||||
case APPLE_800x600:
|
||||
scr_mode = B_32_BIT_800x600;
|
||||
break;
|
||||
case APPLE_1024x768:
|
||||
scr_mode = B_32_BIT_1024x768;
|
||||
break;
|
||||
case APPLE_1152x900:
|
||||
scr_mode = B_32_BIT_1152x900;
|
||||
break;
|
||||
case APPLE_1280x1024:
|
||||
scr_mode = B_32_BIT_1280x1024;
|
||||
break;
|
||||
case APPLE_1600x1200:
|
||||
scr_mode = B_32_BIT_1600x1200;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
the_screen = new MacScreen(GetString(STR_WINDOW_TITLE), scr_mode);
|
||||
D(bug("Opened, error %08lx\n", screen_error));
|
||||
if (screen_error != B_NO_ERROR) {
|
||||
D(bug("Error, posting quit to screen\n"));
|
||||
the_screen->PostMessage(B_QUIT_REQUESTED);
|
||||
D(bug("Posted, waiting\n"));
|
||||
while (the_screen)
|
||||
snooze(200000);
|
||||
D(bug("Screen closed\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for video mem access
|
||||
D(bug("Showing screen\n"));
|
||||
the_screen->Show();
|
||||
D(bug("Shown, waiting for frame buffer access\n"));
|
||||
while (!drawing_enable)
|
||||
snooze(200000);
|
||||
D(bug("Access granted\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_CLOSE_SCREEN:
|
||||
if (the_screen != NULL) {
|
||||
D(bug("Posting quit to screen\n"));
|
||||
the_screen->PostMessage(B_QUIT_REQUESTED);
|
||||
D(bug("Posted, waiting\n"));
|
||||
while (the_screen)
|
||||
snooze(200000);
|
||||
D(bug("Screen closed\n"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Acknowledge
|
||||
release_sem(dm_done_sem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Open display (window or screen)
|
||||
*/
|
||||
|
||||
static void open_display(void)
|
||||
{
|
||||
D(bug("entering open_display()\n"));
|
||||
display_type = VModes[cur_mode].viType;
|
||||
if (display_type == DIS_SCREEN) {
|
||||
while (send_data(dm_thread, MSG_OPEN_SCREEN, NULL, 0) == B_INTERRUPTED) ;
|
||||
while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ;
|
||||
} else if (display_type == DIS_WINDOW) {
|
||||
while (send_data(dm_thread, MSG_OPEN_WINDOW, NULL, 0) == B_INTERRUPTED) ;
|
||||
while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ;
|
||||
}
|
||||
D(bug("exiting open_display()\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Close display
|
||||
*/
|
||||
|
||||
static void close_display(void)
|
||||
{
|
||||
D(bug("entering close_display()\n"));
|
||||
if (display_type == DIS_SCREEN) {
|
||||
while (send_data(dm_thread, MSG_CLOSE_SCREEN, NULL, 0) == B_INTERRUPTED) ;
|
||||
while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ;
|
||||
} else if (display_type == DIS_WINDOW) {
|
||||
while (send_data(dm_thread, MSG_CLOSE_WINDOW, NULL, 0) == B_INTERRUPTED) ;
|
||||
while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ;
|
||||
}
|
||||
D(bug("exiting close_display()\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, long apple_mode, long apple_id, int type)
|
||||
{
|
||||
if (allow & test) {
|
||||
p->viType = type;
|
||||
switch (apple_id) {
|
||||
case APPLE_W_640x480:
|
||||
case APPLE_640x480:
|
||||
p->viXsize = 640;
|
||||
p->viYsize = 480;
|
||||
break;
|
||||
case APPLE_W_800x600:
|
||||
case APPLE_800x600:
|
||||
p->viXsize = 800;
|
||||
p->viYsize = 600;
|
||||
break;
|
||||
case APPLE_1024x768:
|
||||
p->viXsize = 1024;
|
||||
p->viYsize = 768;
|
||||
break;
|
||||
case APPLE_1152x900:
|
||||
p->viXsize = 1152;
|
||||
p->viYsize = 900;
|
||||
break;
|
||||
case APPLE_1280x1024:
|
||||
p->viXsize = 1280;
|
||||
p->viYsize = 1024;
|
||||
break;
|
||||
case APPLE_1600x1200:
|
||||
p->viXsize = 1600;
|
||||
p->viYsize = 1200;
|
||||
break;
|
||||
}
|
||||
switch (apple_mode) {
|
||||
case APPLE_8_BIT:
|
||||
p->viRowBytes = p->viXsize;
|
||||
break;
|
||||
case APPLE_16_BIT:
|
||||
p->viRowBytes = p->viXsize * 2;
|
||||
break;
|
||||
case APPLE_32_BIT:
|
||||
p->viRowBytes = p->viXsize * 4;
|
||||
break;
|
||||
}
|
||||
p->viAppleMode = apple_mode;
|
||||
p->viAppleID = apple_id;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
bool VideoInit(void)
|
||||
{
|
||||
// Init variables, create semaphores
|
||||
private_data = NULL;
|
||||
cur_mode = 0; // Window 640x480
|
||||
video_lock = create_sem(1, "Video Lock");
|
||||
mac_os_lock = create_sem(0, "MacOS Frame Buffer Lock");
|
||||
dm_done_sem = create_sem(0, "Display Manager Done");
|
||||
|
||||
// Construct video mode table
|
||||
VideoInfo *p = VModes;
|
||||
uint32 window_modes = PrefsFindInt32("windowmodes");
|
||||
uint32 screen_modes = PrefsFindInt32("screenmodes");
|
||||
if (window_modes == 0 && screen_modes == 0)
|
||||
window_modes |= B_8_BIT_640x480 | B_8_BIT_800x600; // Allow at least 640x480 and 800x600 window modes
|
||||
add_mode(p, window_modes, B_8_BIT_640x480, APPLE_8_BIT, APPLE_W_640x480, DIS_WINDOW);
|
||||
add_mode(p, window_modes, B_8_BIT_800x600, APPLE_8_BIT, APPLE_W_800x600, DIS_WINDOW);
|
||||
add_mode(p, window_modes, B_15_BIT_640x480, APPLE_16_BIT, APPLE_W_640x480, DIS_WINDOW);
|
||||
add_mode(p, window_modes, B_15_BIT_800x600, APPLE_16_BIT, APPLE_W_800x600, DIS_WINDOW);
|
||||
add_mode(p, window_modes, B_32_BIT_640x480, APPLE_32_BIT, APPLE_W_640x480, DIS_WINDOW);
|
||||
add_mode(p, window_modes, B_32_BIT_800x600, APPLE_32_BIT, APPLE_W_800x600, DIS_WINDOW);
|
||||
add_mode(p, screen_modes, B_8_BIT_640x480, APPLE_8_BIT, APPLE_640x480, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_8_BIT_800x600, APPLE_8_BIT, APPLE_800x600, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_8_BIT_1024x768, APPLE_8_BIT, APPLE_1024x768, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_8_BIT_1152x900, APPLE_8_BIT, APPLE_1152x900, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_8_BIT_1280x1024, APPLE_8_BIT, APPLE_1280x1024, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_8_BIT_1600x1200, APPLE_8_BIT, APPLE_1600x1200, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_15_BIT_640x480, APPLE_16_BIT, APPLE_640x480, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_15_BIT_800x600, APPLE_16_BIT, APPLE_800x600, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_15_BIT_1024x768, APPLE_16_BIT, APPLE_1024x768, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_15_BIT_1152x900, APPLE_16_BIT, APPLE_1152x900, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_15_BIT_1280x1024, APPLE_16_BIT, APPLE_1280x1024, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_15_BIT_1600x1200, APPLE_16_BIT, APPLE_1600x1200, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_32_BIT_640x480, APPLE_32_BIT, APPLE_640x480, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_32_BIT_800x600, APPLE_32_BIT, APPLE_800x600, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_32_BIT_1024x768, APPLE_32_BIT, APPLE_1024x768, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_32_BIT_1152x900, APPLE_32_BIT, APPLE_1152x900, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_32_BIT_1280x1024, APPLE_32_BIT, APPLE_1280x1024, DIS_SCREEN);
|
||||
add_mode(p, screen_modes, B_32_BIT_1600x1200, APPLE_32_BIT, APPLE_1600x1200, DIS_SCREEN);
|
||||
p->viType = DIS_INVALID; // End marker
|
||||
p->viRowBytes = 0;
|
||||
p->viXsize = p->viYsize = 0;
|
||||
p->viAppleMode = 0;
|
||||
p->viAppleID = 0;
|
||||
|
||||
// Start display manager thread
|
||||
dm_thread = spawn_thread(display_manager, "Display Manager", B_NORMAL_PRIORITY, NULL);
|
||||
resume_thread(dm_thread);
|
||||
|
||||
// Open window/screen
|
||||
open_display();
|
||||
if (display_type == DIS_SCREEN && the_screen == NULL) {
|
||||
char str[256];
|
||||
sprintf(str, GetString(STR_FULL_SCREEN_ERR), strerror(screen_error), screen_error);
|
||||
ErrorAlert(str);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deinitialization
|
||||
*/
|
||||
|
||||
void VideoExit(void)
|
||||
{
|
||||
if (dm_thread >= 0) {
|
||||
|
||||
// Close display
|
||||
acquire_sem(video_lock);
|
||||
close_display();
|
||||
if (private_data != NULL) {
|
||||
delete private_data->gammaTable;
|
||||
delete private_data;
|
||||
}
|
||||
|
||||
// Stop display manager
|
||||
status_t l;
|
||||
send_data(dm_thread, MSG_QUIT_DISPLAY_MANAGER, NULL, 0);
|
||||
while (wait_for_thread(dm_thread, &l) == B_INTERRUPTED) ;
|
||||
}
|
||||
|
||||
// Delete semaphores
|
||||
delete_sem(video_lock);
|
||||
delete_sem(mac_os_lock);
|
||||
delete_sem(dm_done_sem);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Close screen in full-screen mode
|
||||
*/
|
||||
|
||||
void VideoQuitFullScreen(void)
|
||||
{
|
||||
D(bug("VideoQuitFullScreen()\n"));
|
||||
if (display_type == DIS_SCREEN) {
|
||||
acquire_sem(video_lock);
|
||||
close_display();
|
||||
release_sem(video_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Execute video VBL routine
|
||||
*/
|
||||
|
||||
void VideoVBL(void)
|
||||
{
|
||||
release_sem(mac_os_lock);
|
||||
if (private_data != NULL && private_data->interruptsEnabled)
|
||||
VSLDoInterruptService(private_data->vslServiceID);
|
||||
while (acquire_sem(mac_os_lock) == B_INTERRUPTED) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Filter function for receiving mouse and keyboard events
|
||||
*/
|
||||
|
||||
#define MENU_IS_POWER 0
|
||||
|
||||
// Be -> Mac raw keycode translation table
|
||||
static const uint8 keycode2mac[0x80] = {
|
||||
0xff, 0x35, 0x7a, 0x78, 0x63, 0x76, 0x60, 0x61, // inv Esc F1 F2 F3 F4 F5 F6
|
||||
0x62, 0x64, 0x65, 0x6d, 0x67, 0x6f, 0x69, 0x6b, // F7 F8 F9 F10 F11 F12 F13 F14
|
||||
0x71, 0x0a, 0x12, 0x13, 0x14, 0x15, 0x17, 0x16, // F15 ` 1 2 3 4 5 6
|
||||
0x1a, 0x1c, 0x19, 0x1d, 0x1b, 0x18, 0x33, 0x72, // 7 8 9 0 - = BSP INS
|
||||
0x73, 0x74, 0x47, 0x4b, 0x43, 0x4e, 0x30, 0x0c, // HOM PUP NUM / * - TAB Q
|
||||
0x0d, 0x0e, 0x0f, 0x11, 0x10, 0x20, 0x22, 0x1f, // W E R T Y U I O
|
||||
0x23, 0x21, 0x1e, 0x2a, 0x75, 0x77, 0x79, 0x59, // P [ ] \ DEL END PDN 7
|
||||
0x5b, 0x5c, 0x45, 0x39, 0x00, 0x01, 0x02, 0x03, // 8 9 + CAP A S D F
|
||||
0x05, 0x04, 0x26, 0x28, 0x25, 0x29, 0x27, 0x24, // G H J K L ; ' RET
|
||||
0x56, 0x57, 0x58, 0x38, 0x06, 0x07, 0x08, 0x09, // 4 5 6 SHL Z X C V
|
||||
0x0b, 0x2d, 0x2e, 0x2b, 0x2f, 0x2c, 0x38, 0x3e, // B N M , . / SHR CUP
|
||||
0x53, 0x54, 0x55, 0x4c, 0x36, 0x37, 0x31, 0x37, // 1 2 3 ENT CTL ALT SPC ALT
|
||||
0x36, 0x3b, 0x3d, 0x3c, 0x52, 0x41, 0x3a, 0x3a, // CTR CLF CDN CRT 0 . CMD CMD
|
||||
#if MENU_IS_POWER
|
||||
0x7f, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv
|
||||
#else
|
||||
0x32, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv
|
||||
#endif
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv
|
||||
};
|
||||
|
||||
static const uint8 modifier2mac[0x20] = {
|
||||
#if MENU_IS_POWER
|
||||
0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x7f, // SHF CMD inv CAP F14 NUM OPT MNU
|
||||
#else
|
||||
0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x32, // SHF CMD CTR CAP F14 NUM OPT MNU
|
||||
#endif
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv
|
||||
};
|
||||
|
||||
static filter_result filter_func(BMessage *msg, BHandler **target, BMessageFilter *filter)
|
||||
{
|
||||
// msg->PrintToStream();
|
||||
switch (msg->what) {
|
||||
case B_KEY_DOWN:
|
||||
case B_KEY_UP: {
|
||||
uint32 be_code = msg->FindInt32("key") & 0xff;
|
||||
uint32 mac_code = keycode2mac[be_code];
|
||||
|
||||
// Intercept Ctrl-F1 (mount floppy disk shortcut)
|
||||
uint32 mods = msg->FindInt32("modifiers");
|
||||
if (be_code == 0x02 && (mods & B_CONTROL_KEY))
|
||||
SysMountVolume("/dev/disk/floppy/raw");
|
||||
|
||||
if (mac_code == 0xff)
|
||||
return B_DISPATCH_MESSAGE;
|
||||
if (msg->what == B_KEY_DOWN)
|
||||
ADBKeyDown(mac_code);
|
||||
else
|
||||
ADBKeyUp(mac_code);
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
case B_MODIFIERS_CHANGED: {
|
||||
uint32 mods = msg->FindInt32("modifiers");
|
||||
uint32 old_mods = msg->FindInt32("be:old_modifiers");
|
||||
uint32 changed = mods ^ old_mods;
|
||||
uint32 mask = 1;
|
||||
for (int i=0; i<32; i++, mask<<=1)
|
||||
if (changed & mask) {
|
||||
uint32 mac_code = modifier2mac[i];
|
||||
if (mac_code == 0xff)
|
||||
continue;
|
||||
if (mods & mask)
|
||||
ADBKeyDown(mac_code);
|
||||
else
|
||||
ADBKeyUp(mac_code);
|
||||
}
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
case B_MOUSE_MOVED: {
|
||||
BPoint point;
|
||||
msg->FindPoint("where", &point);
|
||||
ADBMouseMoved(int(point.x), int(point.y));
|
||||
return B_DISPATCH_MESSAGE; // Otherwise BitmapView::MouseMoved() wouldn't be called
|
||||
}
|
||||
|
||||
case B_MOUSE_DOWN: {
|
||||
uint32 buttons = msg->FindInt32("buttons");
|
||||
if (buttons & B_PRIMARY_MOUSE_BUTTON)
|
||||
ADBMouseDown(0);
|
||||
if (buttons & B_SECONDARY_MOUSE_BUTTON)
|
||||
ADBMouseDown(1);
|
||||
if (buttons & B_TERTIARY_MOUSE_BUTTON)
|
||||
ADBMouseDown(2);
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
case B_MOUSE_UP: // B_MOUSE_UP means "all buttons released"
|
||||
ADBMouseUp(0);
|
||||
ADBMouseUp(1);
|
||||
ADBMouseUp(2);
|
||||
return B_SKIP_MESSAGE;
|
||||
|
||||
default:
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Install graphics acceleration
|
||||
*/
|
||||
|
||||
// Rectangle blitting
|
||||
static void accl_bitblt(accl_params *p)
|
||||
{
|
||||
D(bug("accl_bitblt\n"));
|
||||
|
||||
// Get blitting parameters
|
||||
int16 src_X = p->src_rect[1] - p->src_bounds[1];
|
||||
int16 src_Y = p->src_rect[0] - p->src_bounds[0];
|
||||
int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
|
||||
int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
|
||||
int16 width = p->dest_rect[3] - p->dest_rect[1] - 1;
|
||||
int16 height = p->dest_rect[2] - p->dest_rect[0] - 1;
|
||||
D(bug(" src X %d, src Y %d, dest X %d, dest Y %d\n", src_X, src_Y, dest_X, dest_Y));
|
||||
D(bug(" width %d, height %d\n", width, height));
|
||||
|
||||
// And perform the blit
|
||||
bitblt_hook(src_X, src_Y, dest_X, dest_Y, width, height);
|
||||
}
|
||||
|
||||
static bool accl_bitblt_hook(accl_params *p)
|
||||
{
|
||||
D(bug("accl_draw_hook %p\n", p));
|
||||
|
||||
// Check if we can accelerate this bitblt
|
||||
if (p->src_base_addr == screen_base && p->dest_base_addr == screen_base &&
|
||||
display_type == DIS_SCREEN && bitblt_hook != NULL &&
|
||||
((uint32 *)p)[0x18 >> 2] + ((uint32 *)p)[0x128 >> 2] == 0 &&
|
||||
((uint32 *)p)[0x130 >> 2] == 0 &&
|
||||
p->transfer_mode == 0 &&
|
||||
p->src_row_bytes > 0 && ((uint32 *)p)[0x15c >> 2] > 0) {
|
||||
|
||||
// Yes, set function pointer
|
||||
p->draw_proc = accl_bitblt;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rectangle filling/inversion
|
||||
static void accl_fillrect8(accl_params *p)
|
||||
{
|
||||
D(bug("accl_fillrect8\n"));
|
||||
|
||||
// Get filling parameters
|
||||
int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
|
||||
int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
|
||||
int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1;
|
||||
int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1;
|
||||
uint8 color = p->pen_mode == 8 ? p->fore_pen : p->back_pen;
|
||||
D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y));
|
||||
D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max));
|
||||
|
||||
// And perform the fill
|
||||
fillrect8_hook(dest_X, dest_Y, dest_X_max, dest_Y_max, color);
|
||||
}
|
||||
|
||||
static void accl_fillrect32(accl_params *p)
|
||||
{
|
||||
D(bug("accl_fillrect32\n"));
|
||||
|
||||
// Get filling parameters
|
||||
int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
|
||||
int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
|
||||
int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1;
|
||||
int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1;
|
||||
uint32 color = p->pen_mode == 8 ? p->fore_pen : p->back_pen;
|
||||
D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y));
|
||||
D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max));
|
||||
|
||||
// And perform the fill
|
||||
fillrect32_hook(dest_X, dest_Y, dest_X_max, dest_Y_max, color);
|
||||
}
|
||||
|
||||
static void accl_invrect(accl_params *p)
|
||||
{
|
||||
D(bug("accl_invrect\n"));
|
||||
|
||||
// Get inversion parameters
|
||||
int16 dest_X = p->dest_rect[1] - p->dest_bounds[1];
|
||||
int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0];
|
||||
int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1;
|
||||
int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1;
|
||||
D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y));
|
||||
D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max));
|
||||
|
||||
//!!?? pen_mode == 14
|
||||
|
||||
// And perform the inversion
|
||||
invrect_hook(dest_X, dest_Y, dest_X_max, dest_Y_max);
|
||||
}
|
||||
|
||||
static bool accl_fillrect_hook(accl_params *p)
|
||||
{
|
||||
D(bug("accl_fillrect_hook %p\n", p));
|
||||
|
||||
// Check if we can accelerate this fillrect
|
||||
if (p->dest_base_addr == screen_base && ((uint32 *)p)[0x284 >> 2] != 0 && display_type == DIS_SCREEN) {
|
||||
if (p->transfer_mode == 8) {
|
||||
// Fill
|
||||
if (p->dest_pixel_size == 8 && fillrect8_hook != NULL) {
|
||||
p->draw_proc = accl_fillrect8;
|
||||
return true;
|
||||
} else if (p->dest_pixel_size == 32 && fillrect32_hook != NULL) {
|
||||
p->draw_proc = accl_fillrect32;
|
||||
return true;
|
||||
}
|
||||
} else if (p->transfer_mode == 10 && invrect_hook != NULL) {
|
||||
// Invert
|
||||
p->draw_proc = accl_invrect;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Dummy for testing
|
||||
/*
|
||||
static void do_nothing(accl_params *p) {}
|
||||
static bool accl_foobar_hook(accl_params *p)
|
||||
{
|
||||
printf("accl_foobar_hook %p\n", p);
|
||||
printf(" src_base_addr %p, dest_base_addr %p\n", p->src_base_addr, p->dest_base_addr);
|
||||
printf(" src_row_bytes %d, dest_row_bytes %d\n", p->src_row_bytes, p->dest_row_bytes);
|
||||
printf(" src_pixel_size %d, dest_pixel_size %d\n", p->src_pixel_size, p->dest_pixel_size);
|
||||
printf(" src_bounds (%d,%d,%d,%d), dest_bounds (%d,%d,%d,%d)\n", p->src_bounds[0], p->src_bounds[1], p->src_bounds[2], p->src_bounds[3], p->dest_bounds[0], p->dest_bounds[1], p->dest_bounds[2], p->dest_bounds[3]);
|
||||
printf(" src_rect (%d,%d,%d,%d), dest_rect (%d,%d,%d,%d)\n", p->src_rect[0], p->src_rect[1], p->src_rect[2], p->src_rect[3], p->dest_rect[0], p->dest_rect[1], p->dest_rect[2], p->dest_rect[3]);
|
||||
printf(" transfer mode %d\n", p->transfer_mode);
|
||||
printf(" pen mode %d\n", p->pen_mode);
|
||||
printf(" fore_pen %08x, back_pen %08x\n", p->fore_pen, p->back_pen);
|
||||
printf(" val1 %08x, val2 %08x\n", ((uint32 *)p)[0x18 >> 2], ((uint32 *)p)[0x128 >> 2]);
|
||||
printf(" val3 %08x\n", ((uint32 *)p)[0x130 >> 2]);
|
||||
printf(" val4 %08x\n", ((uint32 *)p)[0x15c >> 2]);
|
||||
printf(" val5 %08x\n", ((uint32 *)p)[0x160 >> 2]);
|
||||
printf(" val6 %08x\n", ((uint32 *)p)[0x1b4 >> 2]);
|
||||
printf(" val7 %08x\n", ((uint32 *)p)[0x284 >> 2]);
|
||||
p->draw_proc = do_nothing;
|
||||
return true;
|
||||
}
|
||||
static struct accl_hook_info foobar_hook_info = {accl_foobar_hook, accl_sync_hook, 6};
|
||||
*/
|
||||
|
||||
// Wait for graphics operation to finish
|
||||
static bool accl_sync_hook(void *arg)
|
||||
{
|
||||
D(bug("accl_sync_hook %p\n", arg));
|
||||
if (sync_hook != NULL)
|
||||
sync_hook();
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct accl_hook_info bitblt_hook_info = {accl_bitblt_hook, accl_sync_hook, ACCL_BITBLT};
|
||||
static struct accl_hook_info fillrect_hook_info = {accl_fillrect_hook, accl_sync_hook, ACCL_FILLRECT};
|
||||
|
||||
void VideoInstallAccel(void)
|
||||
{
|
||||
// Install acceleration hooks
|
||||
if (PrefsFindBool("gfxaccel")) {
|
||||
D(bug("Video: Installing acceleration hooks\n"));
|
||||
NQDMisc(6, &bitblt_hook_info);
|
||||
NQDMisc(6, &fillrect_hook_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Change video mode
|
||||
*/
|
||||
|
||||
int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr)
|
||||
{
|
||||
/* return if no mode change */
|
||||
if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) &&
|
||||
(csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr;
|
||||
|
||||
/* first find video mode in table */
|
||||
for (int i=0; VModes[i].viType != DIS_INVALID; i++) {
|
||||
if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) &&
|
||||
(ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) {
|
||||
csSave->saveMode = ReadMacInt16(ParamPtr + csMode);
|
||||
csSave->saveData = ReadMacInt32(ParamPtr + csData);
|
||||
csSave->savePage = ReadMacInt16(ParamPtr + csPage);
|
||||
|
||||
while (acquire_sem(video_lock) == B_INTERRUPTED) ;
|
||||
DisableInterrupt();
|
||||
|
||||
/* close old display */
|
||||
close_display();
|
||||
|
||||
/* open new display */
|
||||
cur_mode = i;
|
||||
open_display();
|
||||
|
||||
/* opening the screen failed? Then bail out */
|
||||
if (display_type == DIS_SCREEN && the_screen == NULL) {
|
||||
release_sem(video_lock);
|
||||
ErrorAlert(GetString(STR_FULL_SCREEN_ERR));
|
||||
QuitEmulator();
|
||||
}
|
||||
|
||||
WriteMacInt32(ParamPtr + csBaseAddr, screen_base);
|
||||
csSave->saveBaseAddr=screen_base;
|
||||
csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */
|
||||
csSave->saveMode=VModes[cur_mode].viAppleMode;
|
||||
|
||||
EnableInterrupt();
|
||||
release_sem(video_lock);
|
||||
return noErr;
|
||||
}
|
||||
}
|
||||
return paramErr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set color palette
|
||||
*/
|
||||
|
||||
void video_set_palette(void)
|
||||
{
|
||||
if (display_type == DIS_SCREEN && the_screen != NULL)
|
||||
the_screen->palette_changed = true;
|
||||
else { // remap colors to BeOS-Palette
|
||||
BScreen screen;
|
||||
for (int i=0;i<256;i++)
|
||||
remap_mac_be[i]=screen.IndexForColor(mac_pal[i].red,mac_pal[i].green,mac_pal[i].blue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set cursor image for window
|
||||
*/
|
||||
|
||||
void video_set_cursor(void)
|
||||
{
|
||||
the_window->cursor_changed = true; // Inform window (don't set cursor directly because this may run at interrupt (i.e. signal handler) time)
|
||||
}
|
262
SheepShaver/src/BeOS/video_screen.h
Normal file
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* video_screen.h - Full screen video modes
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
static bool drawing_enable = false; // This flag indicated if the access to the screen is allowed
|
||||
static int page_num; // Index of the currently displayed buffer
|
||||
|
||||
|
||||
// Blitter functions
|
||||
typedef void (*bitblt_ptr)(int32, int32, int32, int32, int32, int32);
|
||||
static bitblt_ptr bitblt_hook;
|
||||
typedef void (*fillrect8_ptr)(int32, int32, int32, int32, uint8);
|
||||
static fillrect8_ptr fillrect8_hook;
|
||||
typedef void (*fillrect32_ptr)(int32, int32, int32, int32, uint32);
|
||||
static fillrect32_ptr fillrect32_hook;
|
||||
typedef void (*invrect_ptr)(int32, int32, int32, int32);
|
||||
static invrect_ptr invrect_hook;
|
||||
typedef void (*sync_ptr)(void);
|
||||
static sync_ptr sync_hook;
|
||||
|
||||
|
||||
class MacScreen : public BWindowScreen {
|
||||
public:
|
||||
MacScreen(const char *name, uint32 space);
|
||||
virtual ~MacScreen();
|
||||
virtual void Quit(void);
|
||||
virtual void ScreenConnected(bool active);
|
||||
|
||||
bool palette_changed;
|
||||
|
||||
private:
|
||||
static status_t tick_func(void *arg);
|
||||
|
||||
BView *view; // Main view for GetMouse()
|
||||
|
||||
uint8 *frame_backup; // Frame buffer backup when switching from/to different workspace
|
||||
bool quitting; // Flag for ScreenConnected: We are quitting, don't pause emulator thread
|
||||
bool first; // Flag for ScreenConnected: This is the first time we become active
|
||||
|
||||
thread_id tick_thread;
|
||||
bool tick_thread_active;
|
||||
};
|
||||
|
||||
|
||||
// Pointer to our screen
|
||||
static MacScreen *the_screen = NULL;
|
||||
|
||||
// Error code from BWindowScreen constructor
|
||||
static status_t screen_error;
|
||||
|
||||
// to enable debugger mode.
|
||||
#define SCREEN_DEBUG false
|
||||
|
||||
|
||||
/*
|
||||
* Screen constructor
|
||||
*/
|
||||
|
||||
MacScreen::MacScreen(const char *name, uint32 space) : BWindowScreen(name, space, &screen_error, SCREEN_DEBUG), tick_thread(-1)
|
||||
{
|
||||
D(bug("Screen constructor\n"));
|
||||
|
||||
// Set all variables
|
||||
frame_backup = NULL;
|
||||
palette_changed = false;
|
||||
quitting = false;
|
||||
first = true;
|
||||
drawing_enable = false;
|
||||
ADBSetRelMouseMode(true);
|
||||
|
||||
// Create view to poll the mouse
|
||||
view = new BView (BRect(0,0,VModes[cur_mode].viXsize-1,VModes[cur_mode].viYsize-1),NULL,B_FOLLOW_NONE,0);
|
||||
AddChild(view);
|
||||
|
||||
// Start 60Hz interrupt
|
||||
tick_thread_active = true;
|
||||
tick_thread = spawn_thread(tick_func, "Polling sucks...", B_DISPLAY_PRIORITY, this);
|
||||
RegisterThread(tick_thread);
|
||||
resume_thread(tick_thread);
|
||||
|
||||
// Add filter for keyboard and mouse events
|
||||
BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func);
|
||||
AddCommonFilter(filter);
|
||||
D(bug("Screen constructor done\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Screen destructor
|
||||
*/
|
||||
|
||||
MacScreen::~MacScreen()
|
||||
{
|
||||
D(bug("Screen destructor, quitting tick thread\n"));
|
||||
|
||||
// Stop 60Hz interrupt
|
||||
if (tick_thread > 0) {
|
||||
status_t l;
|
||||
tick_thread_active = false;
|
||||
while (wait_for_thread(tick_thread, &l) == B_INTERRUPTED) ;
|
||||
}
|
||||
D(bug("tick thread quit\n"));
|
||||
|
||||
// Tell the emulator that we're done
|
||||
the_screen = NULL;
|
||||
D(bug("Screen destructor done\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Screen closed
|
||||
*/
|
||||
|
||||
void MacScreen::Quit(void)
|
||||
{
|
||||
// Tell ScreenConnected() that we are quitting
|
||||
quitting = true;
|
||||
D(bug("MacScreen::Quit(), disconnecting\n"));
|
||||
Disconnect();
|
||||
D(bug("disconnected\n"));
|
||||
BWindowScreen::Quit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Screen connected/disconnected
|
||||
*/
|
||||
|
||||
void MacScreen::ScreenConnected(bool active)
|
||||
{
|
||||
D(bug("ScreenConnected(%d)\n", active));
|
||||
graphics_card_info *info = CardInfo();
|
||||
D(bug(" card_info %p\n", info));
|
||||
|
||||
if (active) {
|
||||
|
||||
// Read graphics parameters
|
||||
D(bug(" active\n"));
|
||||
screen_base = (uint32)info->frame_buffer;
|
||||
D(bug(" screen_base %p\n", screen_base));
|
||||
VModes[cur_mode].viRowBytes = info->bytes_per_row;
|
||||
D(bug(" xmod %d\n", info->bytes_per_row));
|
||||
|
||||
// Get acceleration functions
|
||||
if (PrefsFindBool("gfxaccel")) {
|
||||
bitblt_hook = (bitblt_ptr)CardHookAt(7);
|
||||
D(bug(" bitblt_hook %p\n", bitblt_hook));
|
||||
fillrect8_hook = (fillrect8_ptr)CardHookAt(5);
|
||||
D(bug(" fillrect8_hook %p\n", fillrect8_hook));
|
||||
fillrect32_hook = (fillrect32_ptr)CardHookAt(6);
|
||||
D(bug(" fillrect32_hook %p\n", fillrect32_hook));
|
||||
invrect_hook = (invrect_ptr)CardHookAt(11);
|
||||
D(bug(" invrect_hook %p\n", invrect_hook));
|
||||
sync_hook = (sync_ptr)CardHookAt(10);
|
||||
D(bug(" sync_hook %p\n", sync_hook));
|
||||
} else {
|
||||
bitblt_hook = NULL;
|
||||
fillrect8_hook = NULL;
|
||||
fillrect32_hook = NULL;
|
||||
invrect_hook = NULL;
|
||||
sync_hook = NULL;
|
||||
}
|
||||
|
||||
// The first time we got the screen, we need to init the Window
|
||||
if (first) {
|
||||
D(bug(" first time\n"));
|
||||
first = false;
|
||||
page_num = 0; // current display : page 0
|
||||
} else { // we get our screen back
|
||||
D(bug(" not first time\n"));
|
||||
// copy from backup bitmap to framebuffer
|
||||
memcpy((void *)screen_base, frame_backup, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
|
||||
// delete backup bitmap
|
||||
delete[] frame_backup;
|
||||
frame_backup = NULL;
|
||||
// restore palette
|
||||
if (info->bits_per_pixel == 8)
|
||||
SetColorList(mac_pal);
|
||||
// restart emul thread
|
||||
release_sem(mac_os_lock);
|
||||
}
|
||||
|
||||
// allow the drawing in the frame buffer
|
||||
D(bug(" enabling frame buffer access\n"));
|
||||
drawing_enable = true;
|
||||
video_activated = true;
|
||||
|
||||
} else {
|
||||
|
||||
drawing_enable = false; // stop drawing.
|
||||
video_activated = false;
|
||||
if (!quitting) {
|
||||
// stop emul thread
|
||||
acquire_sem(mac_os_lock);
|
||||
// create bitmap and store frame buffer into
|
||||
frame_backup = new uint8[VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize];
|
||||
memcpy(frame_backup, (void *)screen_base, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize);
|
||||
}
|
||||
}
|
||||
D(bug("ScreenConnected() done\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 60Hz interrupt routine
|
||||
*/
|
||||
|
||||
status_t MacScreen::tick_func(void *arg)
|
||||
{
|
||||
MacScreen *obj = (MacScreen *)arg;
|
||||
while (obj->tick_thread_active) {
|
||||
|
||||
// Wait
|
||||
snooze(16667);
|
||||
|
||||
// Workspace activated? Then poll the mouse and change the palette if needed
|
||||
if (video_activated) {
|
||||
BPoint pt;
|
||||
uint32 button = 0;
|
||||
if (obj->LockWithTimeout(200000) == B_OK) {
|
||||
if (obj->palette_changed) {
|
||||
obj->palette_changed = false;
|
||||
obj->SetColorList(mac_pal);
|
||||
}
|
||||
obj->view->GetMouse(&pt, &button);
|
||||
obj->Unlock();
|
||||
set_mouse_position(320, 240);
|
||||
ADBMouseMoved(int(pt.x) - 320, int(pt.y) - 240);
|
||||
if (button & B_PRIMARY_MOUSE_BUTTON)
|
||||
ADBMouseDown(0);
|
||||
if (!(button & B_PRIMARY_MOUSE_BUTTON))
|
||||
ADBMouseUp(0);
|
||||
if (button & B_SECONDARY_MOUSE_BUTTON)
|
||||
ADBMouseDown(1);
|
||||
if (!(button & B_SECONDARY_MOUSE_BUTTON))
|
||||
ADBMouseUp(1);
|
||||
if (button & B_TERTIARY_MOUSE_BUTTON)
|
||||
ADBMouseDown(2);
|
||||
if (!(button & B_TERTIARY_MOUSE_BUTTON))
|
||||
ADBMouseUp(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
523
SheepShaver/src/BeOS/video_window.h
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
* video_window.h - Window video modes
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <DirectWindow.h>
|
||||
|
||||
|
||||
// Messages
|
||||
static const uint32 MSG_REDRAW = 'draw';
|
||||
static const uint32 MSG_ABOUT_REQUESTED = B_ABOUT_REQUESTED;
|
||||
static const uint32 MSG_REF_5HZ = ' 5Hz';
|
||||
static const uint32 MSG_REF_7_5HZ = ' 7Hz';
|
||||
static const uint32 MSG_REF_10HZ = '10Hz';
|
||||
static const uint32 MSG_REF_15HZ = '15Hz';
|
||||
static const uint32 MSG_REF_30HZ = '30Hz';
|
||||
static const uint32 MSG_REF_60HZ = '60Hz';
|
||||
static const uint32 MSG_MOUNT = 'moun';
|
||||
|
||||
static bool mouse_in_view; // Flag: Mouse pointer within bitmap view
|
||||
|
||||
// From sys_beos.cpp
|
||||
extern void SysCreateVolumeMenu(BMenu *menu, uint32 msg);
|
||||
extern void SysMountVolume(const char *name);
|
||||
|
||||
|
||||
/*
|
||||
* A simple view class for blitting a bitmap on the screen
|
||||
*/
|
||||
|
||||
class BitmapView : public BView {
|
||||
public:
|
||||
BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "bitmap", B_FOLLOW_NONE, B_WILL_DRAW)
|
||||
{
|
||||
the_bitmap = bitmap;
|
||||
}
|
||||
virtual void Draw(BRect update)
|
||||
{
|
||||
if (the_bitmap)
|
||||
DrawBitmap(the_bitmap, update, update);
|
||||
}
|
||||
virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message);
|
||||
|
||||
private:
|
||||
BBitmap *the_bitmap;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Window class
|
||||
*/
|
||||
|
||||
class MacWindow : public BDirectWindow {
|
||||
public:
|
||||
MacWindow(BRect frame);
|
||||
virtual ~MacWindow();
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
virtual void DirectConnected(direct_buffer_info *info);
|
||||
virtual void WindowActivated(bool active);
|
||||
|
||||
int32 frame_skip;
|
||||
bool cursor_changed; // Flag: set new cursor image in tick function
|
||||
|
||||
private:
|
||||
static status_t tick_func(void *arg);
|
||||
|
||||
BitmapView *main_view;
|
||||
BBitmap *the_bitmap;
|
||||
uint8 *the_buffer;
|
||||
|
||||
uint32 old_scroll_lock_state;
|
||||
|
||||
thread_id tick_thread;
|
||||
bool tick_thread_active;
|
||||
|
||||
bool supports_direct_mode;
|
||||
bool bit_bang;
|
||||
sem_id drawing_sem;
|
||||
|
||||
color_space mode;
|
||||
void *bits;
|
||||
int32 bytes_per_row;
|
||||
color_space pixel_format;
|
||||
bool unclipped;
|
||||
};
|
||||
|
||||
|
||||
// Pointer to our window
|
||||
static MacWindow *the_window = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* Window constructor
|
||||
*/
|
||||
|
||||
MacWindow::MacWindow(BRect frame) : BDirectWindow(frame, GetString(STR_WINDOW_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE)
|
||||
{
|
||||
D(bug("Window constructor\n"));
|
||||
supports_direct_mode = SupportsWindowMode();
|
||||
cursor_changed = false;
|
||||
bit_bang = supports_direct_mode && PrefsFindBool("bitbang");
|
||||
|
||||
// Move window to right position
|
||||
Lock();
|
||||
MoveTo(80, 60);
|
||||
|
||||
// Allocate bitmap
|
||||
{
|
||||
BScreen scr(this);
|
||||
mode = B_COLOR_8_BIT;
|
||||
switch (VModes[cur_mode].viAppleMode) {
|
||||
case APPLE_8_BIT:
|
||||
mode = B_COLOR_8_BIT;
|
||||
bit_bang = false;
|
||||
break;
|
||||
case APPLE_16_BIT:
|
||||
mode = B_RGB_16_BIT;
|
||||
if (scr.ColorSpace() != B_RGB15_BIG && scr.ColorSpace() != B_RGBA15_BIG)
|
||||
bit_bang = false;
|
||||
break;
|
||||
case APPLE_32_BIT:
|
||||
mode = B_RGB_32_BIT;
|
||||
if (scr.ColorSpace() != B_RGB32_BIG && scr.ColorSpace() != B_RGBA32_BIG)
|
||||
bit_bang = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bit_bang) {
|
||||
the_bitmap = NULL;
|
||||
the_buffer = NULL;
|
||||
} else {
|
||||
the_bitmap = new BBitmap(frame, mode);
|
||||
the_buffer = new uint8[VModes[cur_mode].viRowBytes * (VModes[cur_mode].viYsize + 2)]; // ("height + 2" for safety)
|
||||
screen_base = (uint32)the_buffer;
|
||||
}
|
||||
|
||||
// Create bitmap view
|
||||
main_view = new BitmapView(frame, the_bitmap);
|
||||
AddChild(main_view);
|
||||
main_view->MakeFocus();
|
||||
|
||||
// Read frame skip prefs
|
||||
frame_skip = PrefsFindInt32("frameskip");
|
||||
|
||||
// Set up menus
|
||||
BRect bounds = Bounds();
|
||||
bounds.OffsetBy(0, bounds.IntegerHeight() + 1);
|
||||
BMenuItem *item;
|
||||
BMenuBar *bar = new BMenuBar(bounds, "menu");
|
||||
BMenu *menu = new BMenu(GetString(STR_WINDOW_MENU));
|
||||
menu->AddItem(new BMenuItem(GetString(STR_WINDOW_ITEM_ABOUT), new BMessage(MSG_ABOUT_REQUESTED)));
|
||||
menu->AddItem(new BSeparatorItem);
|
||||
BMenu *submenu = new BMenu(GetString(STR_WINDOW_ITEM_REFRESH));
|
||||
submenu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ)));
|
||||
submenu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ)));
|
||||
submenu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ)));
|
||||
submenu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ)));
|
||||
submenu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ)));
|
||||
submenu->AddItem(new BMenuItem(GetString(STR_REF_60HZ_LAB), new BMessage(MSG_REF_60HZ)));
|
||||
submenu->SetRadioMode(true);
|
||||
if (frame_skip == 12) {
|
||||
if ((item = submenu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (frame_skip == 8) {
|
||||
if ((item = submenu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (frame_skip == 6) {
|
||||
if ((item = submenu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (frame_skip == 4) {
|
||||
if ((item = submenu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (frame_skip == 2) {
|
||||
if ((item = submenu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
} else if (frame_skip == 1) {
|
||||
if ((item = submenu->FindItem(GetString(STR_REF_60HZ_LAB))) != NULL)
|
||||
item->SetMarked(true);
|
||||
}
|
||||
menu->AddItem(submenu);
|
||||
submenu = new BMenu(GetString(STR_WINDOW_ITEM_MOUNT));
|
||||
SysCreateVolumeMenu(submenu, MSG_MOUNT);
|
||||
menu->AddItem(submenu);
|
||||
bar->AddItem(menu);
|
||||
AddChild(bar);
|
||||
SetKeyMenuBar(bar);
|
||||
int mbar_height = bar->Frame().IntegerHeight() + 1;
|
||||
|
||||
// Resize window to fit menu bar
|
||||
ResizeBy(0, mbar_height);
|
||||
|
||||
// Set mouse mode and scroll lock state
|
||||
ADBSetRelMouseMode(false);
|
||||
mouse_in_view = true;
|
||||
old_scroll_lock_state = modifiers() & B_SCROLL_LOCK;
|
||||
if (old_scroll_lock_state)
|
||||
SetTitle(GetString(STR_WINDOW_TITLE_FROZEN));
|
||||
else
|
||||
SetTitle(GetString(STR_WINDOW_TITLE));
|
||||
|
||||
// Clear Mac cursor image
|
||||
memset(MacCursor + 4, 0, 64);
|
||||
|
||||
// Keep window aligned to 8-byte frame buffer boundaries for faster blitting
|
||||
SetWindowAlignment(B_BYTE_ALIGNMENT, 8);
|
||||
|
||||
// Create drawing semaphore (for direct mode)
|
||||
drawing_sem = create_sem(0, "direct frame buffer access");
|
||||
|
||||
// Start 60Hz interrupt
|
||||
tick_thread_active = true;
|
||||
tick_thread = spawn_thread(tick_func, "Window Redraw", B_DISPLAY_PRIORITY, this);
|
||||
resume_thread(tick_thread);
|
||||
|
||||
// Add filter for keyboard and mouse events
|
||||
BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func);
|
||||
main_view->AddFilter(filter);
|
||||
|
||||
// Show window
|
||||
Unlock();
|
||||
Show();
|
||||
Sync();
|
||||
D(bug("Window constructor done\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Window destructor
|
||||
*/
|
||||
|
||||
MacWindow::~MacWindow()
|
||||
{
|
||||
// Restore cursor
|
||||
mouse_in_view = false;
|
||||
be_app->SetCursor(B_HAND_CURSOR);
|
||||
|
||||
// Hide window
|
||||
D(bug("Window destructor, hiding window\n"));
|
||||
Hide();
|
||||
Sync();
|
||||
|
||||
// Stop 60Hz interrupt
|
||||
D(bug("Quitting tick thread\n"));
|
||||
status_t l;
|
||||
tick_thread_active = false;
|
||||
delete_sem(drawing_sem);
|
||||
while (wait_for_thread(tick_thread, &l) == B_INTERRUPTED) ;
|
||||
D(bug("tick thread quit\n"));
|
||||
|
||||
// dispose allocated memory
|
||||
delete the_bitmap;
|
||||
delete[] the_buffer;
|
||||
|
||||
// Tell emulator that we're done
|
||||
the_window = NULL;
|
||||
D(bug("Window destructor done\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Window connected/disconnected
|
||||
*/
|
||||
|
||||
void MacWindow::DirectConnected(direct_buffer_info *info)
|
||||
{
|
||||
D(bug("DirectConnected, state %d\n", info->buffer_state));
|
||||
switch (info->buffer_state & B_DIRECT_MODE_MASK) {
|
||||
case B_DIRECT_STOP:
|
||||
acquire_sem(drawing_sem);
|
||||
break;
|
||||
case B_DIRECT_MODIFY:
|
||||
acquire_sem(drawing_sem);
|
||||
case B_DIRECT_START:
|
||||
bits = (void *)((uint8 *)info->bits + info->window_bounds.top * info->bytes_per_row + info->window_bounds.left * info->bits_per_pixel / 8);
|
||||
bytes_per_row = info->bytes_per_row;
|
||||
pixel_format = info->pixel_format;
|
||||
unclipped = false;
|
||||
if (info->clip_list_count == 1)
|
||||
if (memcmp(&info->clip_bounds, &info->window_bounds, sizeof(clipping_rect)) == 0)
|
||||
unclipped = true;
|
||||
if (bit_bang) {
|
||||
screen_base = (uint32)bits;
|
||||
VModes[cur_mode].viRowBytes = bytes_per_row;
|
||||
}
|
||||
release_sem(drawing_sem);
|
||||
break;
|
||||
}
|
||||
D(bug("DirectConnected done\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handles redraw messages
|
||||
*/
|
||||
|
||||
void MacWindow::MessageReceived(BMessage *msg)
|
||||
{
|
||||
BMessage *msg2;
|
||||
|
||||
switch (msg->what) {
|
||||
case MSG_REDRAW: {
|
||||
|
||||
// Prevent backlog of messages
|
||||
MessageQueue()->Lock();
|
||||
while ((msg2 = MessageQueue()->FindMessage(MSG_REDRAW, 0)) != NULL) {
|
||||
MessageQueue()->RemoveMessage(msg2);
|
||||
delete msg2;
|
||||
}
|
||||
MessageQueue()->Unlock();
|
||||
|
||||
// Convert Mac screen buffer to BeOS palette and blit
|
||||
uint32 length = VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize;
|
||||
if (mode == B_COLOR_8_BIT) {
|
||||
// Palette conversion
|
||||
uint8 *source = the_buffer - 1;
|
||||
uint8 *dest = (uint8 *)the_bitmap->Bits() - 1;
|
||||
for (int i=0; i<length; i++)
|
||||
*++dest = remap_mac_be[*++source];
|
||||
} else if (mode == B_RGB_16_BIT) {
|
||||
// Endianess conversion
|
||||
uint16 *source = (uint16 *)the_buffer;
|
||||
uint16 *dest = (uint16 *)the_bitmap->Bits() - 1;
|
||||
for (int i=0; i<length/2; i++)
|
||||
*++dest = __lhbrx(source++, 0);
|
||||
} else if (mode == B_RGB_32_BIT) {
|
||||
// Endianess conversion
|
||||
uint32 *source = (uint32 *)the_buffer;
|
||||
uint32 *dest = (uint32 *)the_bitmap->Bits() - 1;
|
||||
for (int i=0; i<length/4; i++)
|
||||
*++dest = __lwbrx(source++, 0);
|
||||
}
|
||||
BRect update_rect = BRect(0, 0, VModes[cur_mode].viXsize-1, VModes[cur_mode].viYsize-1);
|
||||
main_view->DrawBitmapAsync(the_bitmap, update_rect, update_rect);
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_ABOUT_REQUESTED:
|
||||
OpenAboutWindow();
|
||||
break;
|
||||
|
||||
case MSG_REF_5HZ:
|
||||
PrefsReplaceInt32("frameskip", frame_skip = 12);
|
||||
break;
|
||||
|
||||
case MSG_REF_7_5HZ:
|
||||
PrefsReplaceInt32("frameskip", frame_skip = 8);
|
||||
break;
|
||||
|
||||
case MSG_REF_10HZ:
|
||||
PrefsReplaceInt32("frameskip", frame_skip = 6);
|
||||
break;
|
||||
|
||||
case MSG_REF_15HZ:
|
||||
PrefsReplaceInt32("frameskip", frame_skip = 4);
|
||||
break;
|
||||
|
||||
case MSG_REF_30HZ:
|
||||
PrefsReplaceInt32("frameskip", frame_skip = 2);
|
||||
break;
|
||||
|
||||
case MSG_REF_60HZ:
|
||||
PrefsReplaceInt32("frameskip", frame_skip = 1);
|
||||
break;
|
||||
|
||||
case MSG_MOUNT: {
|
||||
BMenuItem *source = NULL;
|
||||
msg->FindPointer("source", (void **)&source);
|
||||
if (source)
|
||||
SysMountVolume(source->Label());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BDirectWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Window activated/deactivated
|
||||
*/
|
||||
|
||||
void MacWindow::WindowActivated(bool active)
|
||||
{
|
||||
video_activated = active;
|
||||
if (active)
|
||||
frame_skip = PrefsFindInt32("frameskip");
|
||||
else
|
||||
frame_skip = 12; // 5Hz in background
|
||||
BDirectWindow::WindowActivated(active);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 60Hz interrupt routine
|
||||
*/
|
||||
|
||||
status_t MacWindow::tick_func(void *arg)
|
||||
{
|
||||
MacWindow *obj = (MacWindow *)arg;
|
||||
static int tick_counter = 0;
|
||||
while (obj->tick_thread_active) {
|
||||
|
||||
// Wait
|
||||
snooze(16667);
|
||||
|
||||
// Refresh window
|
||||
if (!obj->bit_bang)
|
||||
tick_counter++;
|
||||
if (tick_counter >= obj->frame_skip) {
|
||||
tick_counter = 0;
|
||||
|
||||
// Window title is determined by Scroll Lock state
|
||||
uint32 scroll_lock_state = modifiers() & B_SCROLL_LOCK;
|
||||
if (scroll_lock_state != obj->old_scroll_lock_state) {
|
||||
if (scroll_lock_state)
|
||||
obj->SetTitle(GetString(STR_WINDOW_TITLE_FROZEN));
|
||||
else
|
||||
obj->SetTitle(GetString(STR_WINDOW_TITLE));
|
||||
obj->old_scroll_lock_state = scroll_lock_state;
|
||||
}
|
||||
|
||||
// Refresh display unless Scroll Lock is down
|
||||
if (!scroll_lock_state) {
|
||||
|
||||
// If direct frame buffer access is supported and the content area is completely visible,
|
||||
// convert the Mac screen buffer directly. Otherwise, send a message to the window to do
|
||||
// it into a bitmap
|
||||
if (obj->supports_direct_mode) {
|
||||
if (acquire_sem_etc(obj->drawing_sem, 1, B_TIMEOUT, 200000) == B_NO_ERROR) {
|
||||
if (obj->unclipped && obj->mode == B_COLOR_8_BIT && obj->pixel_format == B_CMAP8) {
|
||||
uint8 *source = obj->the_buffer - 1;
|
||||
uint8 *dest = (uint8 *)obj->bits;
|
||||
uint32 bytes_per_row = obj->bytes_per_row;
|
||||
int xsize = VModes[cur_mode].viXsize;
|
||||
int ysize = VModes[cur_mode].viYsize;
|
||||
for (int y=0; y<ysize; y++) {
|
||||
uint32 *p = (uint32 *)dest - 1;
|
||||
for (int x=0; x<xsize/4; x++) {
|
||||
uint32 c = remap_mac_be[*++source] << 24;
|
||||
c |= remap_mac_be[*++source] << 16;
|
||||
c |= remap_mac_be[*++source] << 8;
|
||||
c |= remap_mac_be[*++source];
|
||||
*++p = c;
|
||||
}
|
||||
dest += bytes_per_row;
|
||||
}
|
||||
} else if (obj->unclipped && obj->mode == B_RGB_16_BIT && (obj->pixel_format == B_RGB15_BIG || obj->pixel_format == B_RGBA15_BIG)) {
|
||||
uint8 *source = obj->the_buffer;
|
||||
uint8 *dest = (uint8 *)obj->bits;
|
||||
uint32 sbpr = VModes[cur_mode].viRowBytes;
|
||||
uint32 dbpr = obj->bytes_per_row;
|
||||
int xsize = VModes[cur_mode].viXsize;
|
||||
int ysize = VModes[cur_mode].viYsize;
|
||||
for (int y=0; y<ysize; y++) {
|
||||
memcpy(dest, source, xsize * 2);
|
||||
source += sbpr;
|
||||
dest += dbpr;
|
||||
}
|
||||
} else if (obj->unclipped && obj->mode == B_RGB_32_BIT && (obj->pixel_format == B_RGB32_BIG || obj->pixel_format == B_RGBA32_BIG)) {
|
||||
uint8 *source = obj->the_buffer;
|
||||
uint8 *dest = (uint8 *)obj->bits;
|
||||
uint32 sbpr = VModes[cur_mode].viRowBytes;
|
||||
uint32 dbpr = obj->bytes_per_row;
|
||||
int xsize = VModes[cur_mode].viXsize;
|
||||
int ysize = VModes[cur_mode].viYsize;
|
||||
for (int y=0; y<ysize; y++) {
|
||||
memcpy(dest, source, xsize * 4);
|
||||
source += sbpr;
|
||||
dest += dbpr;
|
||||
}
|
||||
} else
|
||||
obj->PostMessage(MSG_REDRAW);
|
||||
release_sem(obj->drawing_sem);
|
||||
}
|
||||
} else
|
||||
obj->PostMessage(MSG_REDRAW);
|
||||
}
|
||||
}
|
||||
|
||||
// Set new cursor image if desired
|
||||
if (obj->cursor_changed) {
|
||||
if (mouse_in_view)
|
||||
be_app->SetCursor(MacCursor);
|
||||
obj->cursor_changed = false;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mouse moved
|
||||
*/
|
||||
|
||||
void BitmapView::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
|
||||
{
|
||||
switch (transit) {
|
||||
case B_ENTERED_VIEW:
|
||||
mouse_in_view = true;
|
||||
be_app->SetCursor(MacCursor);
|
||||
break;
|
||||
case B_EXITED_VIEW:
|
||||
mouse_in_view = false;
|
||||
be_app->SetCursor(B_HAND_CURSOR);
|
||||
break;
|
||||
}
|
||||
}
|
43
SheepShaver/src/EthernetDriverStub.i
Normal file
@ -0,0 +1,43 @@
|
||||
0x4a, 0x6f, 0x79, 0x21, 0x70, 0x65, 0x66, 0x66, 0x70, 0x77, 0x70, 0x63, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x01, 0x90,
|
||||
0x00, 0x04, 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x58,
|
||||
0x00, 0x00, 0x01, 0x54, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x04, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x80, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0xb4,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
|
||||
0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x46, 0x07, 0x09, 0xc1, 0x01, 0x43, 0x00, 0x41, 0x00, 0x41,
|
||||
0x00, 0x42, 0x00, 0x41, 0x00, 0x42, 0x00, 0x81, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74,
|
||||
0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x68, 0x65,
|
||||
0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4d, 0x6f, 0x64, 0x75, 0x6c,
|
||||
0x65, 0x47, 0x65, 0x74, 0x4f, 0x54, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72,
|
||||
0x65, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03,
|
||||
0x00, 0x04, 0x00, 0x04, 0x00, 0x15, 0x5e, 0x85, 0x00, 0x14, 0xbd, 0xe0, 0x00, 0x10, 0x8f, 0x84,
|
||||
0x00, 0x10, 0xae, 0x97, 0x00, 0x10, 0x4e, 0x3c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
|
||||
0x00, 0x01, 0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x44, 0x00, 0x01, 0x02, 0x00, 0x00, 0x29,
|
||||
0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x02, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01,
|
||||
0x02, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x38, 0x60, 0x00, 0x00, 0x4e, 0x80, 0x00, 0x20, 0x38, 0x62, 0x01, 0x3c, 0x4e, 0x80, 0x00, 0x20,
|
||||
0x80, 0x40, 0x28, 0x08, 0x80, 0x00, 0x28, 0xc0, 0x7c, 0x09, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20,
|
||||
0x80, 0x40, 0x28, 0x08, 0x80, 0x00, 0x28, 0xc4, 0x7c, 0x09, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20,
|
||||
0x80, 0x40, 0x28, 0x08, 0x80, 0x00, 0x28, 0xc8, 0x7c, 0x09, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20,
|
||||
0x80, 0x40, 0x28, 0x08, 0x80, 0x00, 0x28, 0xcc, 0x7c, 0x09, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20,
|
||||
0x80, 0x40, 0x28, 0x08, 0x80, 0x00, 0x28, 0xd0, 0x7c, 0x09, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20,
|
||||
0x80, 0x40, 0x28, 0x08, 0x80, 0x00, 0x28, 0xd4, 0x7c, 0x09, 0x03, 0xa6, 0x4e, 0x80, 0x04, 0x20,
|
||||
0x02, 0x22, 0x01, 0x3c, 0x03, 0x21, 0x20, 0x86, 0x02, 0x02, 0x00, 0x10, 0x00, 0x08, 0x09, 0x21,
|
||||
0x50, 0x86, 0x02, 0x02, 0x00, 0x60, 0x00, 0x30, 0x01, 0x21, 0x40, 0x04, 0x24, 0x6d, 0x74, 0x65,
|
||||
0x6a, 0x04, 0x35, 0x14, 0x53, 0x68, 0x65, 0x65, 0x70, 0x53, 0x68, 0x61, 0x76, 0x65, 0x72, 0x20,
|
||||
0x45, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x0b, 0x21, 0x01, 0x01, 0x21, 0x80, 0x04, 0x26,
|
||||
0x04, 0x04, 0x65, 0x6e, 0x65, 0x74, 0x00, 0x3e, 0x25, 0x01, 0x6f, 0x74, 0x61, 0x6e, 0x01, 0x24,
|
||||
0x0a, 0x0b, 0x01, 0x01, 0x03, 0x34, 0x53, 0x68, 0x65, 0x65, 0x70, 0x53, 0x68, 0x61, 0x76, 0x65,
|
||||
0x72, 0x20, 0x45, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x04, 0x22, 0x1b, 0xbd, 0x05, 0x21,
|
||||
0xc4, 0x06, 0x22, 0x05, 0xea, 0x02, 0x22, 0x17, 0x70, 0x02, 0x22, 0x13, 0x88, 0x07, 0x21, 0x2c,
|
||||
0x03, 0x21, 0x34, 0x03, 0x21, 0x3c, 0x86, 0x02, 0x02, 0x00, 0xdc, 0x00, 0x24, 0x01, 0x21, 0x34,
|
||||
0x03, 0x21, 0x3c, 0x86, 0x02, 0x01, 0x00, 0xdc, 0x01, 0x21, 0xf4, 0x02, 0x22, 0x01, 0x10, 0x0a,
|
||||
0x22, 0x01, 0x2c, 0x03, 0x21, 0x01, 0x03, 0x21, 0x03, 0x0c,
|
888
SheepShaver/src/Unix/Linux/asm_linux.S
Normal file
@ -0,0 +1,888 @@
|
||||
/*
|
||||
* asm_linux.S - Assembly routines
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <xlowmem.h>
|
||||
|
||||
#define SAVE_FP_EXEC_68K 1
|
||||
|
||||
|
||||
/*
|
||||
* void *get_toc(void) - Get TOC pointer (small data pointer r13 under Linux)
|
||||
*/
|
||||
|
||||
.globl get_toc
|
||||
get_toc:
|
||||
mr r3,r13
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* void *get_sp(void) - Get stack pointer
|
||||
*/
|
||||
|
||||
.globl get_sp
|
||||
get_sp:
|
||||
mr r3,r1
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* void set_r2(uint32 val {r3}) - Set r2
|
||||
*/
|
||||
|
||||
.globl set_r2
|
||||
set_r2:
|
||||
mr r2,r3
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* void flush_icache_range(void *start {r3}, void *end {r3}) - Flush D and I cache
|
||||
*/
|
||||
|
||||
CACHE_LINE_SIZE = 32
|
||||
LG_CACHE_LINE_SIZE = 5
|
||||
|
||||
.globl flush_icache_range
|
||||
flush_icache_range:
|
||||
li r5,CACHE_LINE_SIZE-1
|
||||
andc r3,r3,r5
|
||||
subf r4,r3,r4
|
||||
add r4,r4,r5
|
||||
srwi. r4,r4,LG_CACHE_LINE_SIZE
|
||||
beqlr
|
||||
mtctr r4
|
||||
mr r6,r3
|
||||
1: dcbst 0,r3
|
||||
addi r3,r3,CACHE_LINE_SIZE
|
||||
bdnz 1b
|
||||
sync /* wait for dcbst's to get to ram */
|
||||
mtctr r4
|
||||
2: icbi 0,r6
|
||||
addi r6,r6,CACHE_LINE_SIZE
|
||||
bdnz 2b
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* long atomic_add(long *var{r3}, long add{r4}) - Atomic add operation
|
||||
* long atomic_and(long *var{r3}, long and{r4}) - Atomic and operation
|
||||
* long atomic_or(long *var{r3}, long or{r4}) - Atomic or operation
|
||||
* int test_and_set(int *var{r3}, int val{r4}) - Atomic test-and-set
|
||||
*/
|
||||
|
||||
.globl atomic_add
|
||||
atomic_add:
|
||||
10: dcbf r0,r3
|
||||
sync
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
isync
|
||||
lwarx r5,r0,r3
|
||||
add r0,r4,r5
|
||||
stwcx. r0,r0,r3
|
||||
bne- 10b
|
||||
mr r3,r5
|
||||
isync
|
||||
blr
|
||||
|
||||
.globl atomic_and
|
||||
atomic_and:
|
||||
10: dcbf r0,r3
|
||||
sync
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
isync
|
||||
lwarx r5,r0,r3
|
||||
and r0,r4,r5
|
||||
stwcx. r0,r0,r3
|
||||
bne- 10b
|
||||
mr r3,r5
|
||||
isync
|
||||
blr
|
||||
|
||||
.globl atomic_or
|
||||
atomic_or:
|
||||
10: dcbf r0,r3
|
||||
sync
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
isync
|
||||
lwarx r5,r0,r3
|
||||
or r0,r4,r5
|
||||
stwcx. r0,r0,r3
|
||||
bne- 10b
|
||||
mr r3,r5
|
||||
isync
|
||||
blr
|
||||
|
||||
.globl test_and_set
|
||||
test_and_set:
|
||||
10: dcbf r0,r3
|
||||
sync
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
ori r0,r0,1
|
||||
isync
|
||||
lwarx r5,r0,r3
|
||||
cmpi 0,r5,0x0000
|
||||
beq 1f
|
||||
stwcx. r4,r0,r3
|
||||
bne- 10b
|
||||
1: isync
|
||||
mr r3,r5
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* void quit_emulator(void) - Jump to XLM_EMUL_RETURN_PROC
|
||||
*/
|
||||
|
||||
.globl quit_emulator
|
||||
quit_emulator:
|
||||
lwz r0,XLM_EMUL_RETURN_PROC(r0)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* void jump_to_rom(uint32 entry {r3}, uint32 emulator_data {r4}) - Jump to Mac ROM
|
||||
*/
|
||||
|
||||
.globl jump_to_rom
|
||||
jump_to_rom:
|
||||
// Create stack frame
|
||||
mflr r0
|
||||
stw r0,4(r1)
|
||||
stwu r1,-(20+19*4+18*8)(r1) // maintain 16 byte alignment
|
||||
|
||||
// Save PowerPC registers
|
||||
stmw r13,20(r1)
|
||||
stfd f14,20+19*4+0*8(r1)
|
||||
stfd f15,20+19*4+1*8(r1)
|
||||
stfd f16,20+19*4+2*8(r1)
|
||||
stfd f17,20+19*4+3*8(r1)
|
||||
stfd f18,20+19*4+4*8(r1)
|
||||
stfd f19,20+19*4+5*8(r1)
|
||||
stfd f20,20+19*4+6*8(r1)
|
||||
stfd f21,20+19*4+7*8(r1)
|
||||
stfd f22,20+19*4+8*8(r1)
|
||||
stfd f23,20+19*4+9*8(r1)
|
||||
stfd f24,20+19*4+10*8(r1)
|
||||
stfd f25,20+19*4+11*8(r1)
|
||||
stfd f26,20+19*4+12*8(r1)
|
||||
stfd f27,20+19*4+13*8(r1)
|
||||
stfd f28,20+19*4+14*8(r1)
|
||||
stfd f29,20+19*4+15*8(r1)
|
||||
stfd f30,20+19*4+16*8(r1)
|
||||
stfd f31,20+19*4+17*8(r1)
|
||||
|
||||
// Move entry address to ctr
|
||||
mtctr r3
|
||||
|
||||
// Skip over EMUL_RETURN routine and get its address
|
||||
bl 1f
|
||||
|
||||
|
||||
/*
|
||||
* EMUL_RETURN: Returned from emulator
|
||||
*/
|
||||
|
||||
// Restore PowerPC registers
|
||||
lwz r1,XLM_EMUL_RETURN_STACK(r0)
|
||||
lmw r13,20(r1)
|
||||
lfd f14,20+19*4+0*8(r1)
|
||||
lfd f15,20+19*4+1*8(r1)
|
||||
lfd f16,20+19*4+2*8(r1)
|
||||
lfd f17,20+19*4+3*8(r1)
|
||||
lfd f18,20+19*4+4*8(r1)
|
||||
lfd f19,20+19*4+5*8(r1)
|
||||
lfd f20,20+19*4+6*8(r1)
|
||||
lfd f21,20+19*4+7*8(r1)
|
||||
lfd f22,20+19*4+8*8(r1)
|
||||
lfd f23,20+19*4+9*8(r1)
|
||||
lfd f24,20+19*4+10*8(r1)
|
||||
lfd f25,20+19*4+11*8(r1)
|
||||
lfd f26,20+19*4+12*8(r1)
|
||||
lfd f27,20+19*4+13*8(r1)
|
||||
lfd f28,20+19*4+14*8(r1)
|
||||
lfd f29,20+19*4+15*8(r1)
|
||||
lfd f30,20+19*4+16*8(r1)
|
||||
lfd f31,20+19*4+17*8(r1)
|
||||
|
||||
// Exiting from 68k emulator
|
||||
li r0,1
|
||||
stw r0,XLM_IRQ_NEST(r0)
|
||||
li r0,MODE_NATIVE
|
||||
stw r0,XLM_RUN_MODE(r0)
|
||||
|
||||
// Return to caller of jump_to_rom()
|
||||
lwz r0,20+19*4+18*8+4(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,20+19*4+18*8
|
||||
blr
|
||||
|
||||
|
||||
// Save address of EMUL_RETURN routine for 68k emulator patch
|
||||
1: mflr r0
|
||||
stw r0,XLM_EMUL_RETURN_PROC(r0)
|
||||
|
||||
// Skip over EXEC_RETURN routine and get its address
|
||||
bl 2f
|
||||
|
||||
|
||||
/*
|
||||
* EXEC_RETURN: Returned from 68k routine executed with Execute68k()
|
||||
*/
|
||||
|
||||
// Save r25 (contains current 68k interrupt level)
|
||||
stw r25,XLM_68K_R25(r0)
|
||||
|
||||
// Reentering EMUL_OP mode
|
||||
li r0,MODE_EMUL_OP
|
||||
stw r0,XLM_RUN_MODE(r0)
|
||||
|
||||
// Save 68k registers
|
||||
lwz r4,48(r1) // Pointer to M68kRegisters
|
||||
stw r8,0*4(r4) // d[0]...d[7]
|
||||
stw r9,1*4(r4)
|
||||
stw r10,2*4(r4)
|
||||
stw r11,3*4(r4)
|
||||
stw r12,4*4(r4)
|
||||
stw r13,5*4(r4)
|
||||
stw r14,6*4(r4)
|
||||
stw r15,7*4(r4)
|
||||
stw r16,8*4(r4) // a[0]..a[6]
|
||||
stw r17,9*4(r4)
|
||||
stw r18,10*4(r4)
|
||||
stw r19,11*4(r4)
|
||||
stw r20,12*4(r4)
|
||||
stw r21,13*4(r4)
|
||||
stw r22,14*4(r4)
|
||||
|
||||
// Restore PowerPC registers
|
||||
lmw r13,56(r1)
|
||||
#if SAVE_FP_EXEC_68K
|
||||
lfd f14,56+19*4+0*8(r1)
|
||||
lfd f15,56+19*4+1*8(r1)
|
||||
lfd f16,56+19*4+2*8(r1)
|
||||
lfd f17,56+19*4+3*8(r1)
|
||||
lfd f18,56+19*4+4*8(r1)
|
||||
lfd f19,56+19*4+5*8(r1)
|
||||
lfd f20,56+19*4+6*8(r1)
|
||||
lfd f21,56+19*4+7*8(r1)
|
||||
lfd f22,56+19*4+8*8(r1)
|
||||
lfd f23,56+19*4+9*8(r1)
|
||||
lfd f24,56+19*4+10*8(r1)
|
||||
lfd f25,56+19*4+11*8(r1)
|
||||
lfd f26,56+19*4+12*8(r1)
|
||||
lfd f27,56+19*4+13*8(r1)
|
||||
lfd f28,56+19*4+14*8(r1)
|
||||
lfd f29,56+19*4+15*8(r1)
|
||||
lfd f30,56+19*4+16*8(r1)
|
||||
lfd f31,56+19*4+17*8(r1)
|
||||
#endif
|
||||
|
||||
// Return to caller
|
||||
lwz r0,52(r1)
|
||||
mtcrf 0xff,r0
|
||||
lwz r0,56+19*4+18*8+4(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,56+19*4+18*8
|
||||
blr
|
||||
|
||||
|
||||
// Save address of EXEC_RETURN routine for 68k emulator patch
|
||||
2: mflr r0
|
||||
stw r0,XLM_EXEC_RETURN_PROC(r0)
|
||||
|
||||
// Skip over EMUL_BREAK/EMUL_OP routine and get its address
|
||||
bl 3f
|
||||
|
||||
|
||||
/*
|
||||
* EMUL_BREAK/EMUL_OP: Execute native routine, selector in r5 (my own private mode switch)
|
||||
*
|
||||
* 68k registers are stored in a M68kRegisters struct on the stack
|
||||
* which the native routine may read and modify
|
||||
*/
|
||||
|
||||
// Save r25 (contains current 68k interrupt level)
|
||||
stw r25,XLM_68K_R25(r0)
|
||||
|
||||
// Entering EMUL_OP mode within 68k emulator
|
||||
li r0,MODE_EMUL_OP
|
||||
stw r0,XLM_RUN_MODE(r0)
|
||||
|
||||
// Create PowerPC stack frame, reserve space for M68kRegisters
|
||||
mr r3,r1
|
||||
subi r1,r1,64 // Fake "caller" frame
|
||||
rlwinm r1,r1,0,0,27 // Align stack
|
||||
|
||||
mfcr r0
|
||||
rlwinm r0,r0,0,11,8
|
||||
stw r0,4(r1)
|
||||
mfxer r0
|
||||
stw r0,16(r1)
|
||||
stw r2,12(r1)
|
||||
stwu r1,-(8+16*4+15*8)(r1)
|
||||
|
||||
// Save 68k registers (M68kRegisters)
|
||||
stw r8,8+0*4(r1) // d[0]..d[7]
|
||||
stw r9,8+1*4(r1)
|
||||
stw r10,8+2*4(r1)
|
||||
stw r11,8+3*4(r1)
|
||||
stw r12,8+4*4(r1)
|
||||
stw r13,8+5*4(r1)
|
||||
stw r14,8+6*4(r1)
|
||||
stw r15,8+7*4(r1)
|
||||
stw r16,8+8*4(r1) // a[0]..a[7]
|
||||
stw r17,8+9*4(r1)
|
||||
stw r18,8+10*4(r1)
|
||||
stw r19,8+11*4(r1)
|
||||
stw r20,8+12*4(r1)
|
||||
stw r21,8+13*4(r1)
|
||||
stw r22,8+14*4(r1)
|
||||
stw r3,8+15*4(r1)
|
||||
stfd f0,8+16*4+0*8(r1)
|
||||
stfd f1,8+16*4+1*8(r1)
|
||||
stfd f2,8+16*4+2*8(r1)
|
||||
stfd f3,8+16*4+3*8(r1)
|
||||
stfd f4,8+16*4+4*8(r1)
|
||||
stfd f5,8+16*4+5*8(r1)
|
||||
stfd f6,8+16*4+6*8(r1)
|
||||
stfd f7,8+16*4+7*8(r1)
|
||||
mffs f0
|
||||
stfd f8,8+16*4+8*8(r1)
|
||||
stfd f9,8+16*4+9*8(r1)
|
||||
stfd f10,8+16*4+10*8(r1)
|
||||
stfd f11,8+16*4+11*8(r1)
|
||||
stfd f12,8+16*4+12*8(r1)
|
||||
stfd f13,8+16*4+13*8(r1)
|
||||
stfd f0,8+16*4+14*8(r1)
|
||||
|
||||
// Execute native routine
|
||||
lwz r13,XLM_TOC(r0)
|
||||
addi r3,r1,8
|
||||
mr r4,r24
|
||||
bl EmulOp__FP13M68kRegistersUii
|
||||
|
||||
// Restore 68k registers (M68kRegisters)
|
||||
lwz r8,8+0*4(r1) // d[0]..d[7]
|
||||
lwz r9,8+1*4(r1)
|
||||
lwz r10,8+2*4(r1)
|
||||
lwz r11,8+3*4(r1)
|
||||
lwz r12,8+4*4(r1)
|
||||
lwz r13,8+5*4(r1)
|
||||
lwz r14,8+6*4(r1)
|
||||
lwz r15,8+7*4(r1)
|
||||
lwz r16,8+8*4(r1) // a[0]..a[7]
|
||||
lwz r17,8+9*4(r1)
|
||||
lwz r18,8+10*4(r1)
|
||||
lwz r19,8+11*4(r1)
|
||||
lwz r20,8+12*4(r1)
|
||||
lwz r21,8+13*4(r1)
|
||||
lwz r22,8+14*4(r1)
|
||||
lwz r3,8+15*4(r1)
|
||||
lfd f13,8+16*4+14*8(r1)
|
||||
lfd f0,8+16*4+0*8(r1)
|
||||
lfd f1,8+16*4+1*8(r1)
|
||||
lfd f2,8+16*4+2*8(r1)
|
||||
lfd f3,8+16*4+3*8(r1)
|
||||
lfd f4,8+16*4+4*8(r1)
|
||||
lfd f5,8+16*4+5*8(r1)
|
||||
lfd f6,8+16*4+6*8(r1)
|
||||
lfd f7,8+16*4+7*8(r1)
|
||||
mtfsf 0xff,f13
|
||||
lfd f8,8+16*4+8*8(r1)
|
||||
lfd f9,8+16*4+9*8(r1)
|
||||
lfd f10,8+16*4+10*8(r1)
|
||||
lfd f11,8+16*4+11*8(r1)
|
||||
lfd f12,8+16*4+12*8(r1)
|
||||
lfd f13,8+16*4+13*8(r1)
|
||||
|
||||
// Delete PowerPC stack frame
|
||||
lwz r2,8+16*4+15*8+12(r1)
|
||||
lwz r0,8+16*4+15*8+16(r1)
|
||||
mtxer r0
|
||||
lwz r0,8+16*4+15*8+4(r1)
|
||||
mtcrf 0xff,r0
|
||||
mr r1,r3
|
||||
|
||||
// Reentering 68k emulator
|
||||
li r0,MODE_68K
|
||||
stw r0,XLM_RUN_MODE(r0)
|
||||
|
||||
// Set r0 to 0 for 68k emulator
|
||||
li r0,0
|
||||
|
||||
// Execute next 68k opcode
|
||||
rlwimi r29,r27,3,13,28
|
||||
lhau r27,2(r24)
|
||||
mtlr r29
|
||||
blr
|
||||
|
||||
|
||||
// Save address of EMUL_BREAK/EMUL_OP routine for 68k emulator patch
|
||||
3: mflr r0
|
||||
stw r0,XLM_EMUL_OP_PROC(r0)
|
||||
|
||||
// Save stack pointer for EMUL_RETURN
|
||||
stw r1,XLM_EMUL_RETURN_STACK(r0)
|
||||
|
||||
// Preset registers for ROM boot routine
|
||||
lis r3,0x40b0 // Pointer to ROM boot structure
|
||||
ori r3,r3,0xd000
|
||||
|
||||
// 68k emulator is now active
|
||||
li r0,MODE_68K
|
||||
stw r0,XLM_RUN_MODE(r0)
|
||||
|
||||
// Jump to ROM
|
||||
bctr
|
||||
|
||||
|
||||
/*
|
||||
* void execute_68k(uint32 pc {r3}, M68kRegisters *r {r4}) - Execute 68k routine
|
||||
*/
|
||||
|
||||
.globl execute_68k
|
||||
execute_68k:
|
||||
// Create MacOS stack frame
|
||||
mflr r0
|
||||
stw r0,4(r1)
|
||||
stwu r1,-(56+19*4+18*8)(r1)
|
||||
mfcr r0
|
||||
stw r4,48(r1) // save pointer to M68kRegisters for EXEC_RETURN
|
||||
stw r0,52(r1) // save CR
|
||||
|
||||
// Save PowerPC registers
|
||||
stmw r13,56(r1)
|
||||
#if SAVE_FP_EXEC_68K
|
||||
stfd f14,56+19*4+0*8(r1)
|
||||
stfd f15,56+19*4+1*8(r1)
|
||||
stfd f16,56+19*4+2*8(r1)
|
||||
stfd f17,56+19*4+3*8(r1)
|
||||
stfd f18,56+19*4+4*8(r1)
|
||||
stfd f19,56+19*4+5*8(r1)
|
||||
stfd f20,56+19*4+6*8(r1)
|
||||
stfd f21,56+19*4+7*8(r1)
|
||||
stfd f22,56+19*4+8*8(r1)
|
||||
stfd f23,56+19*4+9*8(r1)
|
||||
stfd f24,56+19*4+10*8(r1)
|
||||
stfd f25,56+19*4+11*8(r1)
|
||||
stfd f26,56+19*4+12*8(r1)
|
||||
stfd f27,56+19*4+13*8(r1)
|
||||
stfd f28,56+19*4+14*8(r1)
|
||||
stfd f29,56+19*4+15*8(r1)
|
||||
stfd f30,56+19*4+16*8(r1)
|
||||
stfd f31,56+19*4+17*8(r1)
|
||||
#endif
|
||||
|
||||
// Set up registers for 68k emulator
|
||||
lwz r31,XLM_KERNEL_DATA(r0) // Pointer to Kernel Data
|
||||
addi r31,r31,0x1000
|
||||
li r0,0
|
||||
mtcrf 0xff,r0
|
||||
creqv 11,11,11 // Supervisor mode
|
||||
lwz r8,0*4(r4) // d[0]..d[7]
|
||||
lwz r9,1*4(r4)
|
||||
lwz r10,2*4(r4)
|
||||
lwz r11,3*4(r4)
|
||||
lwz r12,4*4(r4)
|
||||
lwz r13,5*4(r4)
|
||||
lwz r14,6*4(r4)
|
||||
lwz r15,7*4(r4)
|
||||
lwz r16,8*4(r4) // a[0]..a[6]
|
||||
lwz r17,9*4(r4)
|
||||
lwz r18,10*4(r4)
|
||||
lwz r19,11*4(r4)
|
||||
lwz r20,12*4(r4)
|
||||
lwz r21,13*4(r4)
|
||||
lwz r22,14*4(r4)
|
||||
li r23,0
|
||||
mr r24,r3
|
||||
lwz r25,XLM_68K_R25(r0) // MSB of SR
|
||||
li r26,0
|
||||
li r28,0 // VBR
|
||||
lwz r29,0x74(r31) // Pointer to opcode table
|
||||
lwz r30,0x78(r31) // Address of emulator
|
||||
|
||||
// Push return address (points to EXEC_RETURN opcode) on stack
|
||||
li r0,XLM_EXEC_RETURN_OPCODE
|
||||
stwu r0,-4(r1)
|
||||
|
||||
// Reentering 68k emulator
|
||||
li r0,MODE_68K
|
||||
stw r0,XLM_RUN_MODE(r0)
|
||||
|
||||
// Set r0 to 0 for 68k emulator
|
||||
li r0,0
|
||||
|
||||
// Execute 68k opcode
|
||||
lha r27,0(r24)
|
||||
rlwimi r29,r27,3,13,28
|
||||
lhau r27,2(r24)
|
||||
mtlr r29
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* uint32 call_macos1(uint32 tvect{r3}, uint32 arg1{r4}) ... - Call MacOS routines
|
||||
*/
|
||||
|
||||
#define prolog \
|
||||
mflr r0; \
|
||||
stw r0,4(r1); \
|
||||
stwu r1,-64(r1)
|
||||
|
||||
#define epilog \
|
||||
lwz r13,XLM_TOC(r0);\
|
||||
lwz r0,64+4(r1); \
|
||||
mtlr r0; \
|
||||
addi r1,r1,64; \
|
||||
blr
|
||||
|
||||
.globl call_macos
|
||||
call_macos:
|
||||
prolog
|
||||
lwz r0,0(r3) // Get routine address
|
||||
lwz r2,4(r3) // Load TOC pointer
|
||||
mtctr r0
|
||||
bctrl
|
||||
epilog
|
||||
|
||||
.globl call_macos1
|
||||
call_macos1:
|
||||
prolog
|
||||
lwz r0,0(r3) // Get routine address
|
||||
lwz r2,4(r3) // Load TOC pointer
|
||||
mtctr r0
|
||||
mr r3,r4
|
||||
bctrl
|
||||
epilog
|
||||
|
||||
.globl call_macos2
|
||||
call_macos2:
|
||||
prolog
|
||||
lwz r0,0(r3) // Get routine address
|
||||
lwz r2,4(r3) // Load TOC pointer
|
||||
mtctr r0
|
||||
mr r3,r4
|
||||
mr r4,r5
|
||||
bctrl
|
||||
epilog
|
||||
|
||||
.globl call_macos3
|
||||
call_macos3:
|
||||
prolog
|
||||
lwz r0,0(r3) // Get routine address
|
||||
lwz r2,4(r3) // Load TOC pointer
|
||||
mtctr r0
|
||||
mr r3,r4
|
||||
mr r4,r5
|
||||
mr r5,r6
|
||||
bctrl
|
||||
epilog
|
||||
|
||||
.globl call_macos4
|
||||
call_macos4:
|
||||
prolog
|
||||
lwz r0,0(r3) // Get routine address
|
||||
lwz r2,4(r3) // Load TOC pointer
|
||||
mtctr r0
|
||||
mr r3,r4
|
||||
mr r4,r5
|
||||
mr r5,r6
|
||||
mr r6,r7
|
||||
bctrl
|
||||
epilog
|
||||
|
||||
.globl call_macos5
|
||||
call_macos5:
|
||||
prolog
|
||||
lwz r0,0(r3) // Get routine address
|
||||
lwz r2,4(r3) // Load TOC pointer
|
||||
mtctr r0
|
||||
mr r3,r4
|
||||
mr r4,r5
|
||||
mr r5,r6
|
||||
mr r6,r7
|
||||
mr r7,r8
|
||||
bctrl
|
||||
epilog
|
||||
|
||||
.globl call_macos6
|
||||
call_macos6:
|
||||
prolog
|
||||
lwz r0,0(r3) // Get routine address
|
||||
lwz r2,4(r3) // Load TOC pointer
|
||||
mtctr r0
|
||||
mr r3,r4
|
||||
mr r4,r5
|
||||
mr r5,r6
|
||||
mr r6,r7
|
||||
mr r7,r8
|
||||
mr r8,r9
|
||||
bctrl
|
||||
epilog
|
||||
|
||||
.globl call_macos7
|
||||
call_macos7:
|
||||
prolog
|
||||
lwz r0,0(r3) // Get routine address
|
||||
lwz r2,4(r3) // Load TOC pointer
|
||||
mtctr r0
|
||||
mr r3,r4
|
||||
mr r4,r5
|
||||
mr r5,r6
|
||||
mr r6,r7
|
||||
mr r7,r8
|
||||
mr r8,r9
|
||||
mr r9,r10
|
||||
bctrl
|
||||
epilog
|
||||
|
||||
|
||||
/*
|
||||
* Native resource manager patches
|
||||
*/
|
||||
|
||||
.globl get_resource
|
||||
get_resource:
|
||||
// Create stack frame
|
||||
mflr r0
|
||||
stw r0,8(r1)
|
||||
stwu r1,-(56+12)(r1)
|
||||
|
||||
// Save type/ID
|
||||
stw r3,56(r1)
|
||||
stw r4,56+4(r1)
|
||||
|
||||
// Call old routine
|
||||
lwz r0,XLM_GET_RESOURCE(r0)
|
||||
lwz r2,XLM_RES_LIB_TOC(r0)
|
||||
mtctr r0
|
||||
bctrl
|
||||
stw r3,56+8(r1) // Save handle
|
||||
|
||||
// Call CheckLoad
|
||||
lwz r3,56(r1)
|
||||
lwz r4,56+4(r1)
|
||||
lwz r5,56+8(r1)
|
||||
bl check_load_invoc__FUisPPUs
|
||||
lwz r3,56+8(r1) // Restore handle
|
||||
|
||||
// Return to caller
|
||||
lwz r0,56+12+8(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,56+12
|
||||
blr
|
||||
|
||||
.globl get_1_resource
|
||||
get_1_resource:
|
||||
// Create stack frame
|
||||
mflr r0
|
||||
stw r0,8(r1)
|
||||
stwu r1,-(56+12)(r1)
|
||||
|
||||
// Save type/ID
|
||||
stw r3,56(r1)
|
||||
stw r4,56+4(r1)
|
||||
|
||||
// Call old routine
|
||||
lwz r0,XLM_GET_1_RESOURCE(r0)
|
||||
lwz r2,XLM_RES_LIB_TOC(r0)
|
||||
mtctr r0
|
||||
bctrl
|
||||
stw r3,56+8(r1) // Save handle
|
||||
|
||||
// Call CheckLoad
|
||||
lwz r3,56(r1)
|
||||
lwz r4,56+4(r1)
|
||||
lwz r5,56+8(r1)
|
||||
bl check_load_invoc__FUisPPUs
|
||||
lwz r3,56+8(r1) // Restore handle
|
||||
|
||||
// Return to caller
|
||||
lwz r0,56+12+8(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,56+12
|
||||
blr
|
||||
|
||||
.globl get_ind_resource
|
||||
get_ind_resource:
|
||||
// Create stack frame
|
||||
mflr r0
|
||||
stw r0,8(r1)
|
||||
stwu r1,-(56+12)(r1)
|
||||
|
||||
// Save type/index
|
||||
stw r3,56(r1)
|
||||
stw r4,56+4(r1)
|
||||
|
||||
// Call old routine
|
||||
lwz r0,XLM_GET_IND_RESOURCE(r0)
|
||||
lwz r2,XLM_RES_LIB_TOC(r0)
|
||||
mtctr r0
|
||||
bctrl
|
||||
stw r3,56+8(r1) // Save handle
|
||||
|
||||
// Call CheckLoad
|
||||
lwz r3,56(r1)
|
||||
lwz r4,56+4(r1)
|
||||
lwz r5,56+8(r1)
|
||||
bl check_load_invoc__FUisPPUs
|
||||
lwz r3,56+8(r1) // Restore handle
|
||||
|
||||
// Return to caller
|
||||
lwz r0,56+12+8(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,56+12
|
||||
blr
|
||||
|
||||
.globl get_1_ind_resource
|
||||
get_1_ind_resource:
|
||||
// Create stack frame
|
||||
mflr r0
|
||||
stw r0,8(r1)
|
||||
stwu r1,-(56+12)(r1)
|
||||
|
||||
// Save type/index
|
||||
stw r3,56(r1)
|
||||
stw r4,56+4(r1)
|
||||
|
||||
// Call old routine
|
||||
lwz r0,XLM_GET_1_IND_RESOURCE(r0)
|
||||
lwz r2,XLM_RES_LIB_TOC(r0)
|
||||
mtctr r0
|
||||
bctrl
|
||||
stw r3,56+8(r1) // Save handle
|
||||
|
||||
// Call CheckLoad
|
||||
lwz r3,56(r1)
|
||||
lwz r4,56+4(r1)
|
||||
lwz r5,56+8(r1)
|
||||
bl check_load_invoc__FUisPPUs
|
||||
lwz r3,56+8(r1) // Restore handle
|
||||
|
||||
// Return to caller
|
||||
lwz r0,56+12+8(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,56+12
|
||||
blr
|
||||
|
||||
.globl r_get_resource
|
||||
r_get_resource:
|
||||
// Create stack frame
|
||||
mflr r0
|
||||
stw r0,8(r1)
|
||||
stwu r1,-(56+12)(r1)
|
||||
|
||||
// Save type/ID
|
||||
stw r3,56(r1)
|
||||
stw r4,56+4(r1)
|
||||
|
||||
// Call old routine
|
||||
lwz r0,XLM_R_GET_RESOURCE(r0)
|
||||
lwz r2,XLM_RES_LIB_TOC(r0)
|
||||
mtctr r0
|
||||
bctrl
|
||||
stw r3,56+8(r1) // Save handle
|
||||
|
||||
// Call CheckLoad
|
||||
lwz r3,56(r1)
|
||||
lwz r4,56+4(r1)
|
||||
lwz r5,56+8(r1)
|
||||
bl check_load_invoc__FUisPPUs
|
||||
lwz r3,56+8(r1) // Restore handle
|
||||
|
||||
// Return to caller
|
||||
lwz r0,56+12+8(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,56+12
|
||||
blr
|
||||
|
||||
|
||||
/*
|
||||
* void ppc_interrupt(uint32 entry{r3}, uint32 kernel_data{r4}) - Execute PPC interrupt
|
||||
*/
|
||||
|
||||
.globl ppc_interrupt
|
||||
ppc_interrupt:
|
||||
mflr r0
|
||||
stw r0,4(r1)
|
||||
stwu r1,-64(r1)
|
||||
|
||||
// Get address of return routine
|
||||
bl 1f
|
||||
|
||||
// Return routine
|
||||
lwz r0,64+4(r1)
|
||||
mtlr r0
|
||||
addi r1,r1,64
|
||||
blr
|
||||
|
||||
// Prepare registers for nanokernel interrupt routine
|
||||
1: mtctr r1
|
||||
mr r1,r4
|
||||
stw r6,0x018(r1)
|
||||
mfctr r6
|
||||
stw r6,0x004(r1)
|
||||
lwz r6,0x65c(r1)
|
||||
stw r7,0x13c(r6)
|
||||
stw r8,0x144(r6)
|
||||
stw r9,0x14c(r6)
|
||||
stw r10,0x154(r6)
|
||||
stw r11,0x15c(r6)
|
||||
stw r12,0x164(r6)
|
||||
stw r13,0x16c(r6)
|
||||
|
||||
mflr r10
|
||||
mfcr r13
|
||||
lwz r7,0x660(r1)
|
||||
mflr r12
|
||||
rlwimi. r7,r7,8,0,0
|
||||
li r11,0
|
||||
ori r11,r11,0xf072 // MSR (SRR1)
|
||||
mtcrf 0x70,r11
|
||||
li r8,0
|
||||
|
||||
// Enter nanokernel
|
||||
mtlr r3
|
||||
blr
|
396
SheepShaver/src/Unix/Linux/ether_linux.cpp
Normal file
@ -0,0 +1,396 @@
|
||||
/*
|
||||
* ether_linux.cpp - SheepShaver Ethernet Device Driver (DLPI), Linux specific stuff
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "main.h"
|
||||
#include "macos_util.h"
|
||||
#include "prefs.h"
|
||||
#include "user_strings.h"
|
||||
#include "ether.h"
|
||||
#include "ether_defs.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define STATISTICS 0
|
||||
#define MONITOR 0
|
||||
|
||||
|
||||
// Global variables
|
||||
static int fd = -1; // fd of sheep_net device
|
||||
|
||||
static pthread_t ether_thread; // Packet reception thread
|
||||
static bool thread_active = false; // Flag: Packet reception thread installed
|
||||
|
||||
static sem_t int_ack; // Interrupt acknowledge semaphore
|
||||
static uint8 ether_addr[6]; // Our Ethernet address
|
||||
|
||||
static bool net_open = false; // Flag: initialization succeeded, network device open
|
||||
static bool is_ethertap = false; // Flag: Ethernet device is ethertap
|
||||
|
||||
|
||||
// Prototypes
|
||||
static void *receive_func(void *arg);
|
||||
|
||||
|
||||
/*
|
||||
* Initialize ethernet
|
||||
*/
|
||||
|
||||
void EtherInit(void)
|
||||
{
|
||||
int nonblock = 1;
|
||||
char str[256];
|
||||
|
||||
// Do nothing if the user disabled the network
|
||||
if (PrefsFindBool("nonet"))
|
||||
return;
|
||||
|
||||
// Do nothing if no Ethernet device specified
|
||||
const char *name = PrefsFindString("ether");
|
||||
if (name == NULL)
|
||||
return;
|
||||
|
||||
// Is it Ethertap?
|
||||
is_ethertap = (strncmp(name, "tap", 3) == 0);
|
||||
|
||||
// Open sheep_net or ethertap device
|
||||
char dev_name[16];
|
||||
if (is_ethertap)
|
||||
sprintf(dev_name, "/dev/%s", name);
|
||||
else
|
||||
strcpy(dev_name, "/dev/sheep_net");
|
||||
fd = open(dev_name, O_RDWR);
|
||||
if (fd < 0) {
|
||||
sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno));
|
||||
WarningAlert(str);
|
||||
goto open_error;
|
||||
}
|
||||
|
||||
// Attach to selected Ethernet card
|
||||
if (!is_ethertap && ioctl(fd, SIOCSIFLINK, name) < 0) {
|
||||
sprintf(str, GetString(STR_SHEEP_NET_ATTACH_WARN), strerror(errno));
|
||||
WarningAlert(str);
|
||||
goto open_error;
|
||||
}
|
||||
|
||||
// Set nonblocking I/O
|
||||
ioctl(fd, FIONBIO, &nonblock);
|
||||
|
||||
// Get Ethernet address
|
||||
if (is_ethertap) {
|
||||
pid_t p = getpid(); // If configured for multicast, ethertap requires that the lower 32 bit of the Ethernet address are our PID
|
||||
ether_addr[0] = 0xfe;
|
||||
ether_addr[1] = 0xfd;
|
||||
ether_addr[2] = p >> 24;
|
||||
ether_addr[3] = p >> 16;
|
||||
ether_addr[4] = p >> 8;
|
||||
ether_addr[5] = p;
|
||||
} else
|
||||
ioctl(fd, SIOCGIFADDR, ether_addr);
|
||||
D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
|
||||
|
||||
// Start packet reception thread
|
||||
if (sem_init(&int_ack, 0, 0) < 0) {
|
||||
WarningAlert("WARNING: Cannot init semaphore");
|
||||
goto open_error;
|
||||
}
|
||||
thread_active = (pthread_create(ðer_thread, NULL, receive_func, NULL) == 0);
|
||||
if (!thread_active) {
|
||||
WarningAlert("WARNING: Cannot start Ethernet thread");
|
||||
goto open_error;
|
||||
}
|
||||
|
||||
// Everything OK
|
||||
net_open = true;
|
||||
return;
|
||||
|
||||
open_error:
|
||||
if (thread_active) {
|
||||
pthread_cancel(ether_thread);
|
||||
pthread_join(ether_thread, NULL);
|
||||
sem_destroy(&int_ack);
|
||||
thread_active = false;
|
||||
}
|
||||
if (fd > 0) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Exit ethernet
|
||||
*/
|
||||
|
||||
void EtherExit(void)
|
||||
{
|
||||
// Stop reception thread
|
||||
if (thread_active) {
|
||||
pthread_cancel(ether_thread);
|
||||
pthread_join(ether_thread, NULL);
|
||||
sem_destroy(&int_ack);
|
||||
thread_active = false;
|
||||
}
|
||||
|
||||
// Close sheep_net device
|
||||
if (fd > 0)
|
||||
close(fd);
|
||||
|
||||
#if STATISTICS
|
||||
// Show statistics
|
||||
printf("%ld messages put on write queue\n", num_wput);
|
||||
printf("%ld error acks\n", num_error_acks);
|
||||
printf("%ld packets transmitted (%ld raw, %ld normal)\n", num_tx_packets, num_tx_raw_packets, num_tx_normal_packets);
|
||||
printf("%ld tx packets dropped because buffer full\n", num_tx_buffer_full);
|
||||
printf("%ld packets received\n", num_rx_packets);
|
||||
printf("%ld packets passed upstream (%ld Fast Path, %ld normal)\n", num_rx_fastpath + num_unitdata_ind, num_rx_fastpath, num_unitdata_ind);
|
||||
printf("EtherIRQ called %ld times\n", num_ether_irq);
|
||||
printf("%ld rx packets dropped due to low memory\n", num_rx_no_mem);
|
||||
printf("%ld rx packets dropped because no stream found\n", num_rx_dropped);
|
||||
printf("%ld rx packets dropped because stream not ready\n", num_rx_stream_not_ready);
|
||||
printf("%ld rx packets dropped because no memory for unitdata_ind\n", num_rx_no_unitdata_mem);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get ethernet hardware address
|
||||
*/
|
||||
|
||||
void AO_get_ethernet_address(uint8 *addr)
|
||||
{
|
||||
if (net_open) {
|
||||
OTCopy48BitAddress(ether_addr, addr);
|
||||
} else {
|
||||
addr[0] = 0x12;
|
||||
addr[1] = 0x34;
|
||||
addr[2] = 0x56;
|
||||
addr[3] = 0x78;
|
||||
addr[4] = 0x9a;
|
||||
addr[5] = 0xbc;
|
||||
}
|
||||
D(bug("AO_get_ethernet_address: got address %02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable multicast address
|
||||
*/
|
||||
|
||||
void AO_enable_multicast(uint8 *addr)
|
||||
{
|
||||
D(bug("AO_enable_multicast\n"));
|
||||
if (net_open) {
|
||||
if (ioctl(fd, SIOCADDMULTI, addr) < 0) {
|
||||
D(bug("WARNING: couldn't enable multicast address\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disable multicast address
|
||||
*/
|
||||
|
||||
void AO_disable_multicast(uint8 *addr)
|
||||
{
|
||||
D(bug("AO_disable_multicast\n"));
|
||||
if (net_open) {
|
||||
if (ioctl(fd, SIOCDELMULTI, addr) < 0) {
|
||||
D(bug("WARNING: couldn't disable multicast address\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Transmit one packet
|
||||
*/
|
||||
|
||||
void AO_transmit_packet(mblk_t *mp)
|
||||
{
|
||||
D(bug("AO_transmit_packet\n"));
|
||||
if (net_open) {
|
||||
|
||||
// Copy packet to buffer
|
||||
uint8 packet[1516], *p = packet;
|
||||
int len = 0;
|
||||
if (is_ethertap) {
|
||||
*p++ = 0; // Ethertap discards the first 2 bytes
|
||||
*p++ = 0;
|
||||
len += 2;
|
||||
}
|
||||
while (mp) {
|
||||
uint32 size = mp->b_wptr - mp->b_rptr;
|
||||
memcpy(p, mp->b_rptr, size);
|
||||
len += size;
|
||||
p += size;
|
||||
mp = mp->b_cont;
|
||||
}
|
||||
|
||||
#if MONITOR
|
||||
bug("Sending Ethernet packet:\n");
|
||||
for (int i=0; i<len; i++) {
|
||||
bug("%02x ", packet[i]);
|
||||
}
|
||||
bug("\n");
|
||||
#endif
|
||||
|
||||
// Transmit packet
|
||||
if (write(fd, packet, len) < 0) {
|
||||
D(bug("WARNING: couldn't transmit packet\n"));
|
||||
num_tx_buffer_full++;
|
||||
} else
|
||||
num_tx_packets++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Packet reception thread
|
||||
*/
|
||||
|
||||
static void *receive_func(void *arg)
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
// Wait for packets to arrive
|
||||
struct pollfd pf = {fd, POLLIN, 0};
|
||||
int res = poll(&pf, 1, -1);
|
||||
if (res <= 0)
|
||||
break;
|
||||
|
||||
if (ether_driver_opened) {
|
||||
// Trigger Ethernet interrupt
|
||||
D(bug(" packet received, triggering Ethernet interrupt\n"));
|
||||
SetInterruptFlag(INTFLAG_ETHER);
|
||||
TriggerInterrupt();
|
||||
|
||||
// Wait for interrupt acknowledge by EtherInterrupt()
|
||||
sem_wait(&int_ack);
|
||||
} else
|
||||
usleep(20000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ethernet interrupt
|
||||
*/
|
||||
|
||||
void EtherIRQ(void)
|
||||
{
|
||||
D(bug("EtherIRQ\n"));
|
||||
num_ether_irq++;
|
||||
OTEnterInterrupt();
|
||||
|
||||
// Send received packets to OpenTransport
|
||||
uint8 packet[1516];
|
||||
for (;;) {
|
||||
|
||||
if (is_ethertap) {
|
||||
|
||||
// Read packet from ethertap device
|
||||
ssize_t size = read(fd, packet, 1516);
|
||||
if (size < 14)
|
||||
break;
|
||||
|
||||
#if MONITOR
|
||||
bug("Receiving Ethernet packet:\n");
|
||||
for (int i=0; i<size; i++) {
|
||||
bug("%02x ", packet[i]);
|
||||
}
|
||||
bug("\n");
|
||||
#endif
|
||||
|
||||
// Pointer to packet data (Ethernet header)
|
||||
uint8 *p = packet + 2; // Ethertap has two random bytes before the packet
|
||||
size -= 2;
|
||||
|
||||
// Wrap packet in message block
|
||||
num_rx_packets++;
|
||||
mblk_t *mp;
|
||||
if ((mp = allocb(size, 0)) != NULL) {
|
||||
D(bug(" packet data at %p\n", mp->b_rptr));
|
||||
memcpy(mp->b_rptr, p, size);
|
||||
mp->b_wptr += size;
|
||||
ether_packet_received(mp);
|
||||
} else {
|
||||
D(bug("WARNING: Cannot allocate mblk for received packet\n"));
|
||||
num_rx_no_mem++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Get size of first packet
|
||||
int size = 0;
|
||||
if (ioctl(fd, FIONREAD, &size) < 0 || size == 0)
|
||||
break;
|
||||
|
||||
// Discard packets which are too short
|
||||
if (size < 14) {
|
||||
uint8 dummy[14];
|
||||
read(fd, dummy, size);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Truncate packets which are too long
|
||||
if (size > 1514)
|
||||
size = 1514;
|
||||
|
||||
// Read packet and wrap it in message block
|
||||
num_rx_packets++;
|
||||
mblk_t *mp;
|
||||
if ((mp = allocb(size, 0)) != NULL) {
|
||||
D(bug(" packet data at %p\n", mp->b_rptr));
|
||||
read(fd, mp->b_rptr, 1514);
|
||||
#if MONITOR
|
||||
bug("Receiving Ethernet packet:\n");
|
||||
for (int i=0; i<size; i++) {
|
||||
bug("%02x ", ((uint8 *)mp->b_rptr)[i]);
|
||||
}
|
||||
bug("\n");
|
||||
#endif
|
||||
mp->b_wptr += size;
|
||||
ether_packet_received(mp);
|
||||
} else {
|
||||
D(bug("WARNING: Cannot allocate mblk for received packet\n"));
|
||||
num_rx_no_mem++;
|
||||
}
|
||||
}
|
||||
}
|
||||
OTLeaveInterrupt();
|
||||
|
||||
// Acknowledge interrupt to reception thread
|
||||
D(bug(" EtherIRQ done\n"));
|
||||
sem_post(&int_ack);
|
||||
}
|
168
SheepShaver/src/Unix/Linux/paranoia.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* paranoia.cpp - Check undocumented features of the Linux kernel that
|
||||
* SheepShaver relies upon
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "main.h"
|
||||
#include "user_strings.h"
|
||||
|
||||
typedef struct {
|
||||
uint32 u[4];
|
||||
} __attribute((aligned(16))) vector128;
|
||||
#include <linux/elf.h>
|
||||
|
||||
#define DEBUG 1
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
// Constants
|
||||
const uint32 SIG_STACK_SIZE = 0x10000; // Size of signal stack
|
||||
|
||||
// Prototypes
|
||||
extern "C" void *get_sp(void);
|
||||
extern "C" void set_r2(uint32 val);
|
||||
extern void paranoia_check(void);
|
||||
static void sigusr2_handler(int sig, sigcontext_struct *sc);
|
||||
|
||||
// Global variables
|
||||
static void *sig_stack = NULL;
|
||||
|
||||
static int err = 0;
|
||||
static void *sig_sp = NULL;
|
||||
static void *sig_r4 = NULL;
|
||||
static int sig_sc_signal = 0;
|
||||
static void *sig_sc_regs = NULL;
|
||||
static uint32 sig_r2 = 0;
|
||||
|
||||
|
||||
void paranoia_check(void)
|
||||
{
|
||||
char str[256];
|
||||
|
||||
D(bug("Paranoia checks...\n"));
|
||||
|
||||
// Create and install stack for signal handler
|
||||
sig_stack = malloc(SIG_STACK_SIZE);
|
||||
if (sig_stack == NULL) {
|
||||
ErrorAlert(GetString(STR_NOT_ENOUGH_MEMORY_ERR));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct sigaltstack old_stack;
|
||||
struct sigaltstack new_stack;
|
||||
new_stack.ss_sp = sig_stack;
|
||||
new_stack.ss_flags = 0;
|
||||
new_stack.ss_size = SIG_STACK_SIZE;
|
||||
if (sigaltstack(&new_stack, &old_stack) < 0) {
|
||||
sprintf(str, GetString(STR_SIGALTSTACK_ERR), strerror(errno));
|
||||
ErrorAlert(str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Install SIGUSR2 signal handler
|
||||
static struct sigaction old_action;
|
||||
static struct sigaction sigusr2_action;
|
||||
sigemptyset(&sigusr2_action.sa_mask);
|
||||
sigusr2_action.sa_handler = (__sighandler_t)sigusr2_handler;
|
||||
sigusr2_action.sa_flags = SA_ONSTACK | SA_RESTART;
|
||||
sigusr2_action.sa_restorer = NULL;
|
||||
if (sigaction(SIGUSR2, &sigusr2_action, &old_action) < 0) {
|
||||
sprintf(str, GetString(STR_SIGUSR2_INSTALL_ERR), strerror(errno));
|
||||
ErrorAlert(str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Raise SIGUSR2
|
||||
set_r2(0xaffebad5);
|
||||
raise(SIGUSR2);
|
||||
|
||||
// Check error code
|
||||
switch (err) {
|
||||
case 1:
|
||||
printf("FATAL: sigaltstack() doesn't seem to work (sp in signal handler was %08lx, expected %08lx..%08lx)\n", (uint32)sig_sp, (uint32)sig_stack, (uint32)sig_stack + SIG_STACK_SIZE);
|
||||
break;
|
||||
case 2:
|
||||
printf("FATAL: r4 in signal handler (%08lx) doesn't point to stack\n", (uint32)sig_r4);
|
||||
break;
|
||||
case 3:
|
||||
printf("FATAL: r4 in signal handler doesn't seem to point to a sigcontext_struct (signal number was %d, expected %d)", sig_sc_signal, SIGUSR2);
|
||||
break;
|
||||
case 4:
|
||||
printf("FATAL: sc->regs in signal handler (%08lx) doesn't point to stack\n", (uint32)sig_sc_regs);
|
||||
break;
|
||||
case 5:
|
||||
printf("FATAL: sc->regs->gpr[2] in signal handler (%08lx) doesn't have expected value (%08x)\n", (uint32)sig_r2, 0xaffebad5);
|
||||
break;
|
||||
}
|
||||
if (err) {
|
||||
printf("Maybe you need a different kernel?\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
D(bug("...passed\n"));
|
||||
sigaction(SIGUSR2, &old_action, NULL);
|
||||
sigaltstack(&old_stack, NULL);
|
||||
free(sig_stack);
|
||||
}
|
||||
|
||||
|
||||
static void sigusr2_handler(int sig, sigcontext_struct *sc)
|
||||
{
|
||||
// Check whether sigaltstack works
|
||||
sig_sp = get_sp();
|
||||
if (sig_sp < sig_stack || sig_sp >= ((uint8 *)sig_stack + SIG_STACK_SIZE)) {
|
||||
err = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether r4 points to info on the stack
|
||||
sig_r4 = sc;
|
||||
if (sig_r4 < sig_stack || sig_r4 >= ((uint8 *)sig_stack + SIG_STACK_SIZE)) {
|
||||
err = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether r4 looks like a sigcontext
|
||||
sig_sc_signal = sc->signal;
|
||||
if (sig_sc_signal != SIGUSR2) {
|
||||
err = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether sc->regs points to info on the stack
|
||||
sig_sc_regs = sc->regs;
|
||||
if (sig_sc_regs < sig_stack || sig_sc_regs >= ((uint8 *)sig_stack + SIG_STACK_SIZE)) {
|
||||
err = 4;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether r2 still holds the value we set it to
|
||||
sig_r2 = sc->regs->gpr[2];
|
||||
if (sig_r2 != 0xaffebad5) {
|
||||
err = 5;
|
||||
return;
|
||||
}
|
||||
}
|
251
SheepShaver/src/Unix/Linux/sheepthreads.c
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* sheepthreads.c - Minimal pthreads implementation (libpthreads doesn't
|
||||
* like nonstandard stacks)
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTES:
|
||||
* - pthread_cancel() kills the thread immediately
|
||||
* - Semaphores are VERY restricted: the only supported use is to have one
|
||||
* thread sem_wait() on the semaphore while other threads sem_post() it
|
||||
* (i.e. to use the semaphore as a signal)
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
|
||||
/* Thread stack size */
|
||||
#define STACK_SIZE 65536
|
||||
|
||||
/* From asm_linux.S */
|
||||
extern int atomic_add(int *var, int add);
|
||||
extern int atomic_and(int *var, int and);
|
||||
extern int atomic_or(int *var, int or);
|
||||
extern int test_and_set(int *var, int val);
|
||||
|
||||
/* Linux kernel calls */
|
||||
extern int __clone(int (*fn)(void *), void *, int, void *);
|
||||
|
||||
/* struct sem_t */
|
||||
#define sem_lock __sem_lock
|
||||
#define sem_value __sem_value
|
||||
#define sem_waiting __sem_waiting
|
||||
|
||||
|
||||
/*
|
||||
* Return pthread ID of self
|
||||
*/
|
||||
|
||||
pthread_t pthread_self(void)
|
||||
{
|
||||
return getpid();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test whether two pthread IDs are equal
|
||||
*/
|
||||
|
||||
int pthread_equal(pthread_t t1, pthread_t t2)
|
||||
{
|
||||
return t1 == t2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send signal to thread
|
||||
*/
|
||||
|
||||
int pthread_kill(pthread_t thread, int sig)
|
||||
{
|
||||
if (kill(thread, sig) == -1)
|
||||
return errno;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create pthread
|
||||
*/
|
||||
|
||||
struct new_thread {
|
||||
void *(*fn)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static int start_thread(void *arg)
|
||||
{
|
||||
struct new_thread *nt = (struct new_thread *)arg;
|
||||
nt->fn(nt->arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
|
||||
{
|
||||
struct new_thread *nt;
|
||||
void *stack;
|
||||
int pid;
|
||||
|
||||
nt = (struct new_thread *)malloc(sizeof(struct new_thread));
|
||||
nt->fn = start_routine;
|
||||
nt->arg = arg;
|
||||
stack = malloc(STACK_SIZE);
|
||||
|
||||
pid = __clone(start_thread, (char *)stack + STACK_SIZE - 16, CLONE_VM | CLONE_FS | CLONE_FILES, nt);
|
||||
if (pid == -1) {
|
||||
free(stack);
|
||||
free(nt);
|
||||
return errno;
|
||||
} else {
|
||||
*thread = pid;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Join pthread
|
||||
*/
|
||||
|
||||
int pthread_join(pthread_t thread, void **ret)
|
||||
{
|
||||
do {
|
||||
if (waitpid(thread, NULL, 0) >= 0)
|
||||
break;
|
||||
} while (errno == EINTR);
|
||||
if (ret)
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Cancel thread
|
||||
*/
|
||||
|
||||
int pthread_cancel(pthread_t thread)
|
||||
{
|
||||
kill(thread, SIGINT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test for cancellation
|
||||
*/
|
||||
|
||||
void pthread_testcancel(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Spinlocks
|
||||
*/
|
||||
|
||||
static void acquire_spinlock(volatile int *lock)
|
||||
{
|
||||
do {
|
||||
while (*lock) ;
|
||||
} while (test_and_set((int *)lock, 1) != 0);
|
||||
}
|
||||
|
||||
static void release_spinlock(int *lock)
|
||||
{
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Init semaphore
|
||||
*/
|
||||
|
||||
int sem_init(sem_t *sem, int pshared, unsigned int value)
|
||||
{
|
||||
sem->sem_lock.status = 0;
|
||||
sem->sem_lock.spinlock = 0;
|
||||
sem->sem_value = value;
|
||||
sem->sem_waiting = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Delete remaphore
|
||||
*/
|
||||
|
||||
int sem_destroy(sem_t *sem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wait on semaphore
|
||||
*/
|
||||
|
||||
void null_handler(int sig)
|
||||
{
|
||||
}
|
||||
|
||||
int sem_wait(sem_t *sem)
|
||||
{
|
||||
acquire_spinlock(&sem->sem_lock.spinlock);
|
||||
if (atomic_add((int *)&sem->sem_value, -1) >= 0) {
|
||||
sigset_t mask;
|
||||
if (!sem->sem_lock.status) {
|
||||
struct sigaction sa;
|
||||
sem->sem_lock.status = SIGUSR2;
|
||||
sa.sa_handler = null_handler;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaction(sem->sem_lock.status, &sa, NULL);
|
||||
}
|
||||
sem->sem_waiting = (struct _pthread_descr_struct *)getpid();
|
||||
sigemptyset(&mask);
|
||||
sigsuspend(&mask);
|
||||
sem->sem_waiting = NULL;
|
||||
}
|
||||
release_spinlock(&sem->sem_lock.spinlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Post semaphore
|
||||
*/
|
||||
|
||||
int sem_post(sem_t *sem)
|
||||
{
|
||||
acquire_spinlock(&sem->sem_lock.spinlock);
|
||||
atomic_add((int *)&sem->sem_value, 1);
|
||||
if (sem->sem_waiting)
|
||||
kill((pid_t)sem->sem_waiting, sem->sem_lock.status);
|
||||
release_spinlock(&sem->sem_lock.spinlock);
|
||||
return 0;
|
||||
}
|
96
SheepShaver/src/Unix/Makefile.in
Normal file
@ -0,0 +1,96 @@
|
||||
# Linux makefile for SheepShaver
|
||||
|
||||
## System specific configuration
|
||||
@SET_MAKE@
|
||||
SHELL = /bin/sh
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
datadir = @datadir@
|
||||
mandir = @mandir@
|
||||
man1dir = $(mandir)/man1
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
CFLAGS = @CFLAGS@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@ -I../include -I.
|
||||
DEFS = @DEFS@ -D_REENTRANT -DDATADIR=\"$(datadir)/$(APP)\"
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
SYSSRCS = @SYSSRCS@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
## Files
|
||||
SRCS = main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp sys_unix.cpp \
|
||||
../rom_patches.cpp ../rsrc_patches.cpp ../emul_op.cpp ../name_registry.cpp \
|
||||
../macos_util.cpp ../timer.cpp timer_unix.cpp ../xpram.cpp xpram_unix.cpp \
|
||||
../adb.cpp clip_unix.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp \
|
||||
Linux/scsi_linux.cpp ../video.cpp video_x.cpp ../audio.cpp audio_oss_esd.cpp ../ether.cpp \
|
||||
Linux/ether_linux.cpp ../serial.cpp serial_unix.cpp ../extfs.cpp extfs_unix.cpp \
|
||||
about_window_unix.cpp ../user_strings.cpp user_strings_unix.cpp $(SYSSRCS)
|
||||
APP = SheepShaver
|
||||
|
||||
## Rules
|
||||
.PHONY: modules install uninstall clean distclean depend dep
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .cpp .S .o .h
|
||||
|
||||
all: $(APP)
|
||||
|
||||
OBJ_DIR = obj
|
||||
$(OBJ_DIR)::
|
||||
@[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1
|
||||
|
||||
define SRCS_LIST_TO_OBJS
|
||||
$(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \
|
||||
$(basename $(notdir $(file))))))
|
||||
endef
|
||||
OBJS = $(SRCS_LIST_TO_OBJS)
|
||||
|
||||
SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file))))
|
||||
VPATH :=
|
||||
VPATH += $(addprefix :, $(subst ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS))))
|
||||
|
||||
$(APP): $(OBJ_DIR) $(OBJS)
|
||||
$(CXX) -o $(APP) $(LDFLAGS) $(OBJS) $(LIBS)
|
||||
|
||||
modules:
|
||||
cd NetDriver; make
|
||||
|
||||
install: $(APP) installdirs
|
||||
$(INSTALL_PROGRAM) $(APP) $(bindir)/$(APP)
|
||||
-$(INSTALL_DATA) $(APP).1 $(man1dir)/$(APP).1
|
||||
|
||||
installdirs:
|
||||
$(SHELL) mkinstalldirs $(bindir) $(man1dir)
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/$(APP)
|
||||
rm -f $(man1dir)/$(APP).1
|
||||
|
||||
clean:
|
||||
rm -f $(APP) $(OBJ_DIR)/* core* *.core *~ *.bak
|
||||
|
||||
distclean: clean
|
||||
rm -rf $(OBJ_DIR)
|
||||
rm -f Makefile
|
||||
rm -f config.cache config.log config.status config.h
|
||||
|
||||
depend dep:
|
||||
makedepend $(CPPFLAGS) -Y. $(SRCS) 2>/dev/null
|
||||
|
||||
$(OBJ_DIR)/%.o : %.c
|
||||
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
||||
$(OBJ_DIR)/%.o : %.cpp
|
||||
$(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@
|
||||
$(OBJ_DIR)/%.o : %.S
|
||||
$(CPP) $(CPPFLAGS) -D__ASSEMBLY__ $< -o $*.s
|
||||
$(AS) $(ASFLAGS) -o $@ $*.s
|
||||
rm $*.s
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
29
SheepShaver/src/Unix/SheepShaver.1
Normal file
@ -0,0 +1,29 @@
|
||||
.TH SheepShaver 1 "April, 2000"
|
||||
.SH NAME
|
||||
SheepShaver \- Macintosh emulator
|
||||
.SH SYNOPSIS
|
||||
.B SheepShaver
|
||||
[\-display
|
||||
.IR display-name ]
|
||||
.SH DESCRIPTION
|
||||
.B SheepShaver
|
||||
is a Macintosh emulator for PowerPC-based Linux systems.
|
||||
For more information, see the included documentation.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "\-display " display-name
|
||||
specifies the display to use; see
|
||||
.BR X (1)
|
||||
.SH FILES
|
||||
.TP
|
||||
.I ~/.sheepshaver_prefs
|
||||
User-specific configuration file.
|
||||
.TP
|
||||
.I ~/.sheeshaver_nvram
|
||||
Contents of Mac non-volatile RAM.
|
||||
.SH SEE ALSO
|
||||
http://www.sheepshaver.com/ (Official SheepShaver homepage)
|
||||
.SH AUTHORS
|
||||
Christian Bauer <Christian.Bauer@uni-mainz.de>
|
||||
.br
|
||||
Marc Hellwig <Marc.Hellwig@uni-mainz.de>
|
30
SheepShaver/src/Unix/about_window_unix.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* about_window_unix.cpp - "About" window, Unix implementation
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "about_window.h"
|
||||
|
||||
|
||||
/*
|
||||
* Open "About" window
|
||||
*/
|
||||
|
||||
void OpenAboutWindow(void)
|
||||
{
|
||||
}
|
39
SheepShaver/src/Unix/acconfig.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* acconfig.h
|
||||
This file is in the public domain.
|
||||
|
||||
Descriptive text for the C preprocessor macros that
|
||||
the distributed Autoconf macros can define.
|
||||
No software package will use all of them; autoheader copies the ones
|
||||
your configure.in uses into your configuration header file templates.
|
||||
|
||||
The entries are in sort -df order: alphabetical, case insensitive,
|
||||
ignoring punctuation (such as underscores). Although this order
|
||||
can split up related entries, it makes it easier to check whether
|
||||
a given entry is in the file.
|
||||
|
||||
Leave the following blank line there!! Autoheader needs it. */
|
||||
|
||||
|
||||
/* Define to 'off_t' if <sys/types.h> doesn't define. */
|
||||
#undef loff_t
|
||||
|
||||
/* Define if using ESD. */
|
||||
#undef ENABLE_ESD
|
||||
|
||||
/* Define if using GTK. */
|
||||
#undef ENABLE_GTK
|
||||
|
||||
/* Define if using "mon". */
|
||||
#undef ENABLE_MON
|
||||
|
||||
/* Define if using XFree86 DGA extension. */
|
||||
#undef ENABLE_XF86_DGA
|
||||
|
||||
/* Define if using XFree86 VidMode extension. */
|
||||
#undef ENABLE_XF86_VIDMODE
|
||||
|
||||
|
||||
/* Leave that blank line there!! Autoheader needs it.
|
||||
If you're adding to this file, keep in mind:
|
||||
The entries are in sort -df order: alphabetical, case insensitive,
|
||||
ignoring punctuation (such as underscores). */
|
36
SheepShaver/src/Unix/autogen.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#! /bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
# This was lifted from the Gimp, and adapted slightly by
|
||||
# Christian Bauer.
|
||||
|
||||
DIE=0
|
||||
|
||||
PROG=SheepShaver
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have autoconf installed to compile $PROG."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$*"; then
|
||||
echo "I am going to run ./configure with no arguments - if you wish "
|
||||
echo "to pass any to it, please specify them on the $0 command line."
|
||||
fi
|
||||
|
||||
for dir in .
|
||||
do
|
||||
echo processing $dir
|
||||
(cd $dir; \
|
||||
aclocalinclude="$ACLOCAL_FLAGS"; \
|
||||
aclocal $aclocalinclude; \
|
||||
autoheader; autoconf)
|
||||
done
|
||||
|
||||
./configure "$@"
|
124
SheepShaver/src/Unix/clip_unix.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* clip_unix.cpp - Clipboard handling, Unix implementation
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "macos_util.h"
|
||||
#include "clip.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
// From main_linux.cpp
|
||||
extern Display *x_display;
|
||||
|
||||
|
||||
// Conversion tables
|
||||
static const uint8 mac2iso[0x80] = {
|
||||
0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1,
|
||||
0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8,
|
||||
0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3,
|
||||
0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc,
|
||||
0x2b, 0xb0, 0xa2, 0xa3, 0xa7, 0xb7, 0xb6, 0xdf,
|
||||
0xae, 0xa9, 0x20, 0xb4, 0xa8, 0x23, 0xc6, 0xd8,
|
||||
0x20, 0xb1, 0x3c, 0x3e, 0xa5, 0xb5, 0xf0, 0x53,
|
||||
0x50, 0x70, 0x2f, 0xaa, 0xba, 0x4f, 0xe6, 0xf8,
|
||||
0xbf, 0xa1, 0xac, 0x2f, 0x66, 0x7e, 0x44, 0xab,
|
||||
0xbb, 0x2e, 0x20, 0xc0, 0xc3, 0xd5, 0x4f, 0x6f,
|
||||
0x2d, 0x2d, 0x22, 0x22, 0x60, 0x27, 0xf7, 0x20,
|
||||
0xff, 0x59, 0x2f, 0xa4, 0x3c, 0x3e, 0x66, 0x66,
|
||||
0x23, 0xb7, 0x2c, 0x22, 0x25, 0xc2, 0xca, 0xc1,
|
||||
0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4,
|
||||
0x20, 0xd2, 0xda, 0xdb, 0xd9, 0x69, 0x5e, 0x7e,
|
||||
0xaf, 0x20, 0xb7, 0xb0, 0xb8, 0x22, 0xb8, 0x20
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
void ClipInit(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deinitialization
|
||||
*/
|
||||
|
||||
void ClipExit(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mac application wrote to clipboard
|
||||
*/
|
||||
|
||||
void PutScrap(uint32 type, void *scrap, int32 length)
|
||||
{
|
||||
D(bug("PutScrap type %08lx, data %p, length %ld\n", type, scrap, length));
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case FOURCC('T','E','X','T'):
|
||||
D(bug(" clipping TEXT\n"));
|
||||
|
||||
// Convert text from Mac charset to ISO-Latin1
|
||||
uint8 *buf = new uint8[length];
|
||||
uint8 *p = (uint8 *)scrap;
|
||||
uint8 *q = buf;
|
||||
for (int i=0; i<length; i++) {
|
||||
uint8 c = *p++;
|
||||
if (c < 0x80) {
|
||||
if (c == 13) // CR -> LF
|
||||
c = 10;
|
||||
} else
|
||||
c = mac2iso[c & 0x7f];
|
||||
*q++ = c;
|
||||
}
|
||||
|
||||
// Put text into cut buffer
|
||||
//!! XStoreBytes(x_display, buf, length);
|
||||
delete[] buf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mac application reads clipboard
|
||||
*/
|
||||
|
||||
void GetScrap(void **handle, uint32 type, int32 offset)
|
||||
{
|
||||
D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset));
|
||||
switch (type) {
|
||||
case FOURCC('T','E','X','T'):
|
||||
D(bug(" clipping TEXT\n"));
|
||||
//!!
|
||||
break;
|
||||
}
|
||||
}
|
180
SheepShaver/src/Unix/configure.in
Normal file
@ -0,0 +1,180 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl Written in 2002 by Christian Bauer
|
||||
|
||||
AC_INIT(main_unix.cpp)
|
||||
AC_PREREQ(2.12)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Options.
|
||||
AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes])
|
||||
AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes])
|
||||
AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes])
|
||||
AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [WANT_GTK=$withval], [WANT_GTK=yes])
|
||||
AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=yes])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_INSTALL
|
||||
|
||||
dnl Check for PowerPC target CPU.
|
||||
HAVE_PPC=no
|
||||
AC_MSG_CHECKING(for PowerPC target CPU)
|
||||
AC_EGREP_CPP(yes,
|
||||
[
|
||||
#ifdef __powerpc__
|
||||
yes
|
||||
#endif
|
||||
], [AC_MSG_RESULT(yes); HAVE_PPC=yes], AC_MSG_RESULT(no))
|
||||
|
||||
dnl We use mon if possible.
|
||||
MONSRCS=
|
||||
if [[ "x$WANT_MON" = "xyes" ]]; then
|
||||
AC_MSG_CHECKING(for mon)
|
||||
mon_srcdir=../../../mon/src
|
||||
if grep mon_init $mon_srcdir/mon.h >/dev/null 2>/dev/null; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(ENABLE_MON)
|
||||
MONSRCS="$mon_srcdir/mon.cpp $mon_srcdir/mon_6502.cpp $mon_srcdir/mon_z80.cpp $mon_srcdir/mon_cmd.cpp $mon_srcdir/mon_lowmem.cpp $mon_srcdir/mon_disass.cpp $mon_srcdir/mon_ppc.cpp $mon_srcdir/disass/floatformat.c $mon_srcdir/disass/i386-dis.c $mon_srcdir/disass/m68k-dis.c $mon_srcdir/disass/m68k-opc.c"
|
||||
CXXFLAGS="$CXXFLAGS -I$mon_srcdir -I$mon_srcdir/disass"
|
||||
AC_CHECK_LIB(readline, readline)
|
||||
AC_CHECK_LIB(termcap, tputs)
|
||||
AC_CHECK_HEADERS(readline.h history.h readline/readline.h readline/history.h)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_WARN([Could not find mon, ignoring --with-mon.])
|
||||
WANT_MON=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_CHECK_LIB(posix4, sem_init)
|
||||
|
||||
dnl We need X11.
|
||||
AC_PATH_XTRA
|
||||
if [[ "x$no_x" = "xyes" ]]; then
|
||||
AC_MSG_ERROR([You need X11 to run SheepShaver.])
|
||||
fi
|
||||
CFLAGS="$CFLAGS $X_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $X_CFLAGS"
|
||||
LIBS="$LIBS $X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS"
|
||||
|
||||
dnl We need pthreads on non-PowerPC systems. Try libpthread first, then libc_r (FreeBSD), then PTL.
|
||||
HAVE_PTHREADS=yes
|
||||
if [[ "x$HAVE_PPC" = "xno" ]]; then
|
||||
AC_CHECK_LIB(pthread, pthread_create, , [
|
||||
AC_CHECK_LIB(c_r, pthread_create, , [
|
||||
AC_CHECK_LIB(PTL, pthread_create, , [
|
||||
AC_MSG_ERROR([You need pthreads to run Basilisk II.])
|
||||
])
|
||||
])
|
||||
])
|
||||
AC_CHECK_FUNCS(pthread_cancel)
|
||||
fi
|
||||
|
||||
dnl If POSIX.4 semaphores are not available, we emulate them with pthread mutexes.
|
||||
SEMSRC=
|
||||
AC_CHECK_FUNCS(sem_init, , [
|
||||
if [[ "x$HAVE_PTHREADS" = "xyes" ]]; then
|
||||
SEMSRC=posix_sem.cpp
|
||||
fi
|
||||
])
|
||||
|
||||
dnl We use XFree86 DGA if possible.
|
||||
if [[ "x$WANT_XF86_DGA" = "xyes" ]]; then
|
||||
AC_CHECK_LIB(Xxf86dga, XF86DGAQueryExtension, [
|
||||
AC_DEFINE(ENABLE_XF86_DGA)
|
||||
LIBS="$LIBS -lXxf86dga"
|
||||
], [
|
||||
AC_MSG_WARN([Could not find XFree86 DGA extension, ignoring --enable-xf86-dga.])
|
||||
WANT_XF86_DGA=no
|
||||
])
|
||||
fi
|
||||
|
||||
dnl We use XFree86 VidMode if possible.
|
||||
if [[ "x$WANT_XF86_VIDMODE" = "xyes" ]]; then
|
||||
AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryExtension, [
|
||||
AC_DEFINE(ENABLE_XF86_VIDMODE)
|
||||
LIBS="$LIBS -lXxf86vm"
|
||||
], [
|
||||
AC_MSG_WARN([Could not find XFree86 VidMode extension, ignoring --enable-xf86-vidmode.])
|
||||
WANT_XF86_VIDMODE=no
|
||||
])
|
||||
fi
|
||||
|
||||
dnl We use GTK+ if possible.
|
||||
UISRCS=
|
||||
if [[ "x$WANT_GTK" = "xyes" ]]; then
|
||||
AM_PATH_GTK(1.2.0, [
|
||||
AC_DEFINE(ENABLE_GTK)
|
||||
CFLAGS="$CFLAGS $GTK_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $GTK_CFLAGS"
|
||||
LIBS="$LIBS $GTK_LIBS"
|
||||
UISRCS=prefs_editor_gtk.cpp
|
||||
], [
|
||||
AC_MSG_WARN([Could not find GTK+, disabling user interface.])
|
||||
WANT_GTK=no
|
||||
])
|
||||
fi
|
||||
|
||||
dnl We use ESD if possible.
|
||||
if [[ "x$WANT_ESD" = "xyes" ]]; then
|
||||
AM_PATH_ESD(0.2.8, [
|
||||
AC_DEFINE(ENABLE_ESD)
|
||||
CFLAGS="$CFLAGS $ESD_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $ESD_CFLAGS"
|
||||
LIBS="$LIBS $ESD_LIBS"
|
||||
], [
|
||||
AC_MSG_WARN([Could not find ESD, disabling ESD support.])
|
||||
WANT_ESD=no
|
||||
])
|
||||
fi
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(unistd.h fcntl.h sys/time.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_BIGENDIAN
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_CHECK_SIZEOF(short, 2)
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
AC_CHECK_SIZEOF(long, 4)
|
||||
AC_CHECK_SIZEOF(long long, 8)
|
||||
AC_TYPE_OFF_T
|
||||
AC_CHECK_TYPE(loff_t, off_t)
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS(strdup cfmakeraw)
|
||||
AC_CHECK_FUNCS(nanosleep clock_gettime timer_create)
|
||||
|
||||
dnl Select system-dependant sources.
|
||||
if [[ "x$HAVE_PPC" = "xyes" ]]; then
|
||||
SYSSRCS="Linux/paranoia.cpp Linux/sheepthreads.c Linux/asm_linux.S"
|
||||
else
|
||||
SYSSRCS="../emul_ppc/emul_ppc.cpp"
|
||||
fi
|
||||
SYSSRCS="$SYSSRCS $SEMSRCS $UISRCS $MONSRCS"
|
||||
|
||||
dnl Generate Makefile.
|
||||
AC_SUBST(SYSSRCS)
|
||||
AC_OUTPUT(Makefile)
|
||||
|
||||
dnl Print summary.
|
||||
echo
|
||||
echo SheepShaver configuration summary:
|
||||
echo
|
||||
echo XFree86 DGA support .............. : $WANT_XF86_DGA
|
||||
echo XFree86 VidMode support .......... : $WANT_XF86_VIDMODE
|
||||
echo ESD sound support ................ : $WANT_ESD
|
||||
echo GTK user interface ............... : $WANT_GTK
|
||||
echo mon debugger support ............. : $WANT_MON
|
||||
echo
|
||||
echo "Configuration done. Now type \"make\"."
|
238
SheepShaver/src/Unix/install-sh
Executable file
@ -0,0 +1,238 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
# 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}"
|
||||
|
||||
tranformbasename=""
|
||||
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
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
instcmd=mkdir
|
||||
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
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
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
|
||||
true
|
||||
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
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; 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
|
||||
true
|
||||
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 true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
1805
SheepShaver/src/Unix/main_unix.cpp
Normal file
40
SheepShaver/src/Unix/mkinstalldirs
Executable file
@ -0,0 +1,40 @@
|
||||
#! /bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Public domain
|
||||
|
||||
# $Id$
|
||||
|
||||
errstatus=0
|
||||
|
||||
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
|
||||
fi
|
||||
fi
|
||||
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# mkinstalldirs ends here
|
66
SheepShaver/src/Unix/ppc_asm.tmpl
Normal file
@ -0,0 +1,66 @@
|
||||
/* Register names */
|
||||
#define r0 0
|
||||
#define r1 1
|
||||
#define r2 2
|
||||
#define r3 3
|
||||
#define r4 4
|
||||
#define r5 5
|
||||
#define r6 6
|
||||
#define r7 7
|
||||
#define r8 8
|
||||
#define r9 9
|
||||
#define r10 10
|
||||
#define r11 11
|
||||
#define r12 12
|
||||
#define r13 13
|
||||
#define r14 14
|
||||
#define r15 15
|
||||
#define r16 16
|
||||
#define r17 17
|
||||
#define r18 18
|
||||
#define r19 19
|
||||
#define r20 20
|
||||
#define r21 21
|
||||
#define r22 22
|
||||
#define r23 23
|
||||
#define r24 24
|
||||
#define r25 25
|
||||
#define r26 26
|
||||
#define r27 27
|
||||
#define r28 28
|
||||
#define r29 29
|
||||
#define r30 30
|
||||
#define r31 31
|
||||
|
||||
#define f0 0
|
||||
#define f1 1
|
||||
#define f2 2
|
||||
#define f3 3
|
||||
#define f4 4
|
||||
#define f5 5
|
||||
#define f6 6
|
||||
#define f7 7
|
||||
#define f8 8
|
||||
#define f9 9
|
||||
#define f10 10
|
||||
#define f11 11
|
||||
#define f12 12
|
||||
#define f13 13
|
||||
#define f14 14
|
||||
#define f15 15
|
||||
#define f16 16
|
||||
#define f17 17
|
||||
#define f18 18
|
||||
#define f19 19
|
||||
#define f20 20
|
||||
#define f21 21
|
||||
#define f22 22
|
||||
#define f23 23
|
||||
#define f24 24
|
||||
#define f25 25
|
||||
#define f26 26
|
||||
#define f27 27
|
||||
#define f28 28
|
||||
#define f29 29
|
||||
#define f30 30
|
||||
#define f31 31
|
859
SheepShaver/src/Unix/prefs_editor_gtk.cpp
Normal file
@ -0,0 +1,859 @@
|
||||
/*
|
||||
* prefs_editor_linux.cpp - Preferences editor, Linux implementation using GTK+
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
|
||||
#include "user_strings.h"
|
||||
#include "version.h"
|
||||
#include "cdrom.h"
|
||||
#include "xpram.h"
|
||||
#include "prefs.h"
|
||||
#include "prefs_editor.h"
|
||||
|
||||
|
||||
// Global variables
|
||||
static GtkWidget *win; // Preferences window
|
||||
static bool start_clicked = true; // Return value of PrefsEditor() function
|
||||
|
||||
|
||||
// Prototypes
|
||||
static void create_volumes_pane(GtkWidget *top);
|
||||
static void create_graphics_pane(GtkWidget *top);
|
||||
static void create_serial_pane(GtkWidget *top);
|
||||
static void create_memory_pane(GtkWidget *top);
|
||||
static void read_settings(void);
|
||||
|
||||
|
||||
/*
|
||||
* Utility functions
|
||||
*/
|
||||
|
||||
struct opt_desc {
|
||||
int label_id;
|
||||
GtkSignalFunc func;
|
||||
};
|
||||
|
||||
static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func)
|
||||
{
|
||||
GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id));
|
||||
gtk_widget_show(item);
|
||||
gtk_signal_connect(GTK_OBJECT(item), "activate", func, NULL);
|
||||
gtk_menu_append(GTK_MENU(menu), item);
|
||||
}
|
||||
|
||||
static GtkWidget *make_pane(GtkWidget *notebook, int title_id)
|
||||
{
|
||||
GtkWidget *frame, *label, *box;
|
||||
|
||||
frame = gtk_frame_new(NULL);
|
||||
gtk_widget_show(frame);
|
||||
gtk_container_border_width(GTK_CONTAINER(frame), 4);
|
||||
|
||||
label = gtk_label_new(GetString(title_id));
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
|
||||
|
||||
box = gtk_vbox_new(FALSE, 4);
|
||||
gtk_widget_show(box);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(box), 4);
|
||||
gtk_container_add(GTK_CONTAINER(frame), box);
|
||||
return box;
|
||||
}
|
||||
|
||||
static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons)
|
||||
{
|
||||
GtkWidget *bb, *button;
|
||||
|
||||
bb = gtk_hbutton_box_new();
|
||||
gtk_widget_show(bb);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(bb), border);
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(bb), GTK_BUTTONBOX_DEFAULT_STYLE);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bb), 4);
|
||||
gtk_box_pack_start(GTK_BOX(top), bb, FALSE, FALSE, 0);
|
||||
|
||||
while (buttons->label_id) {
|
||||
button = gtk_button_new_with_label(GetString(buttons->label_id));
|
||||
gtk_widget_show(button);
|
||||
gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0);
|
||||
buttons++;
|
||||
}
|
||||
return bb;
|
||||
}
|
||||
|
||||
static GtkWidget *make_separator(GtkWidget *top)
|
||||
{
|
||||
GtkWidget *sep = gtk_hseparator_new();
|
||||
gtk_box_pack_start(GTK_BOX(top), sep, FALSE, FALSE, 0);
|
||||
gtk_widget_show(sep);
|
||||
return sep;
|
||||
}
|
||||
|
||||
static GtkWidget *make_table(GtkWidget *top, int x, int y)
|
||||
{
|
||||
GtkWidget *table = gtk_table_new(x, y, FALSE);
|
||||
gtk_widget_show(table);
|
||||
gtk_box_pack_start(GTK_BOX(top), table, FALSE, FALSE, 0);
|
||||
return table;
|
||||
}
|
||||
|
||||
static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc *options, int active)
|
||||
{
|
||||
GtkWidget *box, *label, *opt, *menu;
|
||||
|
||||
box = gtk_hbox_new(FALSE, 4);
|
||||
gtk_widget_show(box);
|
||||
gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new(GetString(label_id));
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
|
||||
|
||||
opt = gtk_option_menu_new();
|
||||
gtk_widget_show(opt);
|
||||
menu = gtk_menu_new();
|
||||
|
||||
while (options->label_id) {
|
||||
add_menu_item(menu, options->label_id, options->func);
|
||||
options++;
|
||||
}
|
||||
gtk_menu_set_active(GTK_MENU(menu), active);
|
||||
|
||||
gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu);
|
||||
gtk_box_pack_start(GTK_BOX(box), opt, FALSE, FALSE, 0);
|
||||
return menu;
|
||||
}
|
||||
|
||||
static GtkWidget *make_entry(GtkWidget *top, int label_id, const char *prefs_item)
|
||||
{
|
||||
GtkWidget *box, *label, *entry;
|
||||
|
||||
box = gtk_hbox_new(FALSE, 4);
|
||||
gtk_widget_show(box);
|
||||
gtk_box_pack_start(GTK_BOX(top), box, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new(GetString(label_id));
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
|
||||
|
||||
entry = gtk_entry_new();
|
||||
gtk_widget_show(entry);
|
||||
const char *str = PrefsFindString(prefs_item);
|
||||
if (str == NULL)
|
||||
str = "";
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), str);
|
||||
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
|
||||
return entry;
|
||||
}
|
||||
|
||||
static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func)
|
||||
{
|
||||
GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
|
||||
gtk_widget_show(button);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item));
|
||||
gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
|
||||
gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
|
||||
return button;
|
||||
}
|
||||
|
||||
static GtkWidget *make_checkbox(GtkWidget *top, int label_id, bool active, GtkSignalFunc func)
|
||||
{
|
||||
GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id));
|
||||
gtk_widget_show(button);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), active);
|
||||
gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button);
|
||||
gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0);
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Show preferences editor
|
||||
* Returns true when user clicked on "Start", false otherwise
|
||||
*/
|
||||
|
||||
// Window closed
|
||||
static gint window_closed(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Window destroyed
|
||||
static void window_destroyed(void)
|
||||
{
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
// "Start" button clicked
|
||||
static void cb_start(...)
|
||||
{
|
||||
start_clicked = true;
|
||||
read_settings();
|
||||
SavePrefs();
|
||||
gtk_widget_destroy(win);
|
||||
}
|
||||
|
||||
// "Quit" button clicked
|
||||
static void cb_quit(...)
|
||||
{
|
||||
start_clicked = false;
|
||||
gtk_widget_destroy(win);
|
||||
}
|
||||
|
||||
// "OK" button of "About" dialog clicked
|
||||
static void dl_quit(GtkWidget *dialog)
|
||||
{
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
// "About" selected
|
||||
static void mn_about(...)
|
||||
{
|
||||
GtkWidget *dialog, *label, *button;
|
||||
|
||||
char str[512];
|
||||
sprintf(str,
|
||||
"SheepShaver\nVersion %d.%d\n\n"
|
||||
"Copyright (C) 1997-2002 Christian Bauer and Marc Hellwig\n"
|
||||
"E-mail: Christian.Bauer@uni-mainz.de\n"
|
||||
"http://www.uni-mainz.de/~bauec002/\n\n"
|
||||
"SheepShaver comes with ABSOLUTELY NO\n"
|
||||
"WARRANTY. This is free software, and\n"
|
||||
"you are welcome to redistribute it\n"
|
||||
"under the terms of the GNU General\n"
|
||||
"Public License.\n",
|
||||
VERSION_MAJOR, VERSION_MINOR
|
||||
);
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE));
|
||||
gtk_container_border_width(GTK_CONTAINER(dialog), 5);
|
||||
gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
|
||||
|
||||
label = gtk_label_new(str);
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
|
||||
|
||||
button = gtk_button_new_with_label(GetString(STR_OK_BUTTON));
|
||||
gtk_widget_show(button);
|
||||
gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
|
||||
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
|
||||
gtk_widget_grab_default(button);
|
||||
gtk_widget_show(dialog);
|
||||
}
|
||||
|
||||
// "Zap NVRAM" selected
|
||||
static void mn_zap_pram(...)
|
||||
{
|
||||
ZapPRAM();
|
||||
}
|
||||
|
||||
// Menu item descriptions
|
||||
static GtkItemFactoryEntry menu_items[] = {
|
||||
{(gchar *)GetString(STR_PREFS_MENU_FILE_GTK), NULL, NULL, 0, "<Branch>"},
|
||||
{(gchar *)GetString(STR_PREFS_ITEM_START_GTK), NULL, GTK_SIGNAL_FUNC(cb_start), 0, NULL},
|
||||
{(gchar *)GetString(STR_PREFS_ITEM_ZAP_PRAM_GTK), NULL, GTK_SIGNAL_FUNC(mn_zap_pram), 0, NULL},
|
||||
{(gchar *)GetString(STR_PREFS_ITEM_SEPL_GTK), NULL, NULL, 0, "<Separator>"},
|
||||
{(gchar *)GetString(STR_PREFS_ITEM_QUIT_GTK), "<control>Q", GTK_SIGNAL_FUNC(cb_quit), 0, NULL},
|
||||
{(gchar *)GetString(STR_HELP_MENU_GTK), NULL, NULL, 0, "<LastBranch>"},
|
||||
{(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, GTK_SIGNAL_FUNC(mn_about), 0, NULL}
|
||||
};
|
||||
|
||||
bool PrefsEditor(void)
|
||||
{
|
||||
// Create window
|
||||
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE));
|
||||
gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL);
|
||||
|
||||
// Create window contents
|
||||
GtkWidget *box = gtk_vbox_new(FALSE, 4);
|
||||
gtk_widget_show(box);
|
||||
gtk_container_add(GTK_CONTAINER(win), box);
|
||||
|
||||
GtkAccelGroup *accel_group = gtk_accel_group_new();
|
||||
GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
|
||||
gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL);
|
||||
gtk_accel_group_attach(accel_group, GTK_OBJECT(win));
|
||||
GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "<main>");
|
||||
gtk_widget_show(menu_bar);
|
||||
gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);
|
||||
|
||||
GtkWidget *notebook = gtk_notebook_new();
|
||||
gtk_widget_show(notebook);
|
||||
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
|
||||
gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
|
||||
|
||||
create_volumes_pane(notebook);
|
||||
create_graphics_pane(notebook);
|
||||
create_serial_pane(notebook);
|
||||
create_memory_pane(notebook);
|
||||
|
||||
static const opt_desc buttons[] = {
|
||||
{STR_START_BUTTON, GTK_SIGNAL_FUNC(cb_start)},
|
||||
{STR_QUIT_BUTTON, GTK_SIGNAL_FUNC(cb_quit)},
|
||||
{0, NULL}
|
||||
};
|
||||
make_button_box(box, 4, buttons);
|
||||
|
||||
// Show window and enter main loop
|
||||
gtk_widget_show(win);
|
||||
gtk_main();
|
||||
return start_clicked;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Volumes" pane
|
||||
*/
|
||||
|
||||
static GtkWidget *volume_list, *w_extfs;
|
||||
static int selected_volume;
|
||||
|
||||
// Volume in list selected
|
||||
static void cl_selected(GtkWidget *list, int row, int column)
|
||||
{
|
||||
selected_volume = row;
|
||||
}
|
||||
|
||||
struct file_req_assoc {
|
||||
file_req_assoc(GtkWidget *r, GtkWidget *e) : req(r), entry(e) {}
|
||||
GtkWidget *req;
|
||||
GtkWidget *entry;
|
||||
};
|
||||
|
||||
// Volume selected for addition
|
||||
static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
|
||||
{
|
||||
char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
|
||||
gtk_clist_append(GTK_CLIST(volume_list), &file);
|
||||
gtk_widget_destroy(assoc->req);
|
||||
delete assoc;
|
||||
}
|
||||
|
||||
// Volume selected for creation
|
||||
static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
|
||||
{
|
||||
char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
|
||||
|
||||
char *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry));
|
||||
int size = atoi(str);
|
||||
|
||||
char cmd[1024];
|
||||
sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", file, size);
|
||||
int ret = system(cmd);
|
||||
if (ret == 0)
|
||||
gtk_clist_append(GTK_CLIST(volume_list), &file);
|
||||
gtk_widget_destroy(GTK_WIDGET(assoc->req));
|
||||
delete assoc;
|
||||
}
|
||||
|
||||
// "Add Volume" button clicked
|
||||
static void cb_add_volume(...)
|
||||
{
|
||||
GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_TITLE));
|
||||
gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
|
||||
gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL));
|
||||
gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
|
||||
gtk_widget_show(req);
|
||||
}
|
||||
|
||||
// "Create Hardfile" button clicked
|
||||
static void cb_create_volume(...)
|
||||
{
|
||||
GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE));
|
||||
|
||||
GtkWidget *box = gtk_hbox_new(FALSE, 4);
|
||||
gtk_widget_show(box);
|
||||
GtkWidget *label = gtk_label_new(GetString(STR_HARDFILE_SIZE_CTRL));
|
||||
gtk_widget_show(label);
|
||||
GtkWidget *entry = gtk_entry_new();
|
||||
gtk_widget_show(entry);
|
||||
char str[32];
|
||||
sprintf(str, "%d", 40);
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), str);
|
||||
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0);
|
||||
|
||||
gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
|
||||
gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry));
|
||||
gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req));
|
||||
gtk_widget_show(req);
|
||||
}
|
||||
|
||||
// "Remove Volume" button clicked
|
||||
static void cb_remove_volume(...)
|
||||
{
|
||||
gtk_clist_remove(GTK_CLIST(volume_list), selected_volume);
|
||||
}
|
||||
|
||||
// "Boot From" selected
|
||||
static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);}
|
||||
static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);}
|
||||
|
||||
// "No CD-ROM Driver" button toggled
|
||||
static void tb_nocdrom(GtkWidget *widget)
|
||||
{
|
||||
PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
|
||||
// Read settings from widgets and set preferences
|
||||
static void read_volumes_settings(void)
|
||||
{
|
||||
while (PrefsFindString("disk"))
|
||||
PrefsRemoveItem("disk");
|
||||
|
||||
for (int i=0; i<GTK_CLIST(volume_list)->rows; i++) {
|
||||
char *str;
|
||||
gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str);
|
||||
PrefsAddString("disk", str);
|
||||
}
|
||||
|
||||
PrefsReplaceString("extfs", gtk_entry_get_text(GTK_ENTRY(w_extfs)));
|
||||
}
|
||||
|
||||
// Create "Volumes" pane
|
||||
static void create_volumes_pane(GtkWidget *top)
|
||||
{
|
||||
GtkWidget *box, *scroll, *menu;
|
||||
|
||||
box = make_pane(top, STR_VOLUMES_PANE_TITLE);
|
||||
|
||||
scroll = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_widget_show(scroll);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
volume_list = gtk_clist_new(1);
|
||||
gtk_widget_show(volume_list);
|
||||
gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
|
||||
gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
|
||||
gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
|
||||
gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
|
||||
char *str;
|
||||
int32 index = 0;
|
||||
while ((str = (char *)PrefsFindString("disk", index++)) != NULL)
|
||||
gtk_clist_append(GTK_CLIST(volume_list), &str);
|
||||
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list);
|
||||
gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0);
|
||||
selected_volume = 0;
|
||||
|
||||
static const opt_desc buttons[] = {
|
||||
{STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)},
|
||||
{STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)},
|
||||
{STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)},
|
||||
{0, NULL},
|
||||
};
|
||||
make_button_box(box, 0, buttons);
|
||||
make_separator(box);
|
||||
|
||||
w_extfs = make_entry(box, STR_EXTFS_CTRL, "extfs");
|
||||
|
||||
static const opt_desc options[] = {
|
||||
{STR_BOOT_ANY_LAB, GTK_SIGNAL_FUNC(mn_boot_any)},
|
||||
{STR_BOOT_CDROM_LAB, GTK_SIGNAL_FUNC(mn_boot_cdrom)},
|
||||
{0, NULL}
|
||||
};
|
||||
int bootdriver = PrefsFindInt32("bootdriver"), active = 0;
|
||||
switch (bootdriver) {
|
||||
case 0: active = 0; break;
|
||||
case CDROMRefNum: active = 1; break;
|
||||
}
|
||||
menu = make_option_menu(box, STR_BOOTDRIVER_CTRL, options, active);
|
||||
|
||||
make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Graphics/Sound" pane
|
||||
*/
|
||||
|
||||
static GtkWidget *w_frameskip;
|
||||
|
||||
// "5 Hz".."60Hz" selected
|
||||
static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);}
|
||||
static void mn_7hz(...) {PrefsReplaceInt32("frameskip", 8);}
|
||||
static void mn_10hz(...) {PrefsReplaceInt32("frameskip", 6);}
|
||||
static void mn_15hz(...) {PrefsReplaceInt32("frameskip", 4);}
|
||||
static void mn_30hz(...) {PrefsReplaceInt32("frameskip", 2);}
|
||||
static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);}
|
||||
|
||||
// Video modes
|
||||
static void tb_w640x480(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") | 1);
|
||||
else
|
||||
PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") & ~1);
|
||||
}
|
||||
|
||||
static void tb_w800x600(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") | 2);
|
||||
else
|
||||
PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") & ~2);
|
||||
}
|
||||
|
||||
static void tb_fs640x480(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 1);
|
||||
else
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~1);
|
||||
}
|
||||
|
||||
static void tb_fs800x600(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 2);
|
||||
else
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~2);
|
||||
}
|
||||
|
||||
static void tb_fs1024x768(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 4);
|
||||
else
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~4);
|
||||
}
|
||||
|
||||
static void tb_fs1152x900(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 8);
|
||||
else
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~8);
|
||||
}
|
||||
|
||||
static void tb_fs1280x1024(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 16);
|
||||
else
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~16);
|
||||
}
|
||||
|
||||
static void tb_fs1600x1200(GtkWidget *widget)
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | 32);
|
||||
else
|
||||
PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~32);
|
||||
}
|
||||
|
||||
// "Disable Sound Output" button toggled
|
||||
static void tb_nosound(GtkWidget *widget)
|
||||
{
|
||||
PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
|
||||
// Read settings from widgets and set preferences
|
||||
static void read_graphics_settings(void)
|
||||
{
|
||||
}
|
||||
|
||||
// Create "Graphics/Sound" pane
|
||||
static void create_graphics_pane(GtkWidget *top)
|
||||
{
|
||||
GtkWidget *box, *vbox, *frame;
|
||||
|
||||
box = make_pane(top, STR_GRAPHICS_SOUND_PANE_TITLE);
|
||||
|
||||
static const opt_desc options[] = {
|
||||
{STR_REF_5HZ_LAB, GTK_SIGNAL_FUNC(mn_5hz)},
|
||||
{STR_REF_7_5HZ_LAB, GTK_SIGNAL_FUNC(mn_7hz)},
|
||||
{STR_REF_10HZ_LAB, GTK_SIGNAL_FUNC(mn_10hz)},
|
||||
{STR_REF_15HZ_LAB, GTK_SIGNAL_FUNC(mn_15hz)},
|
||||
{STR_REF_30HZ_LAB, GTK_SIGNAL_FUNC(mn_30hz)},
|
||||
{STR_REF_60HZ_LAB, GTK_SIGNAL_FUNC(mn_60hz)},
|
||||
{0, NULL}
|
||||
};
|
||||
int frameskip = PrefsFindInt32("frameskip"), active = 0;
|
||||
switch (frameskip) {
|
||||
case 12: active = 0; break;
|
||||
case 8: active = 1; break;
|
||||
case 6: active = 2; break;
|
||||
case 4: active = 3; break;
|
||||
case 2: active = 4; break;
|
||||
case 1: active = 5; break;
|
||||
}
|
||||
w_frameskip = make_option_menu(box, STR_FRAMESKIP_CTRL, options, active);
|
||||
|
||||
frame = gtk_frame_new (GetString(STR_VIDEO_MODE_CTRL));
|
||||
gtk_widget_show(frame);
|
||||
gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 4);
|
||||
gtk_widget_show(vbox);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
|
||||
gtk_container_add(GTK_CONTAINER(frame), vbox);
|
||||
|
||||
make_checkbox(vbox, STR_W_640x480_CTRL, PrefsFindInt32("windowmodes") & 1, GTK_SIGNAL_FUNC(tb_w640x480));
|
||||
make_checkbox(vbox, STR_W_800x600_CTRL, PrefsFindInt32("windowmodes") & 2, GTK_SIGNAL_FUNC(tb_w800x600));
|
||||
make_checkbox(vbox, STR_640x480_CTRL, PrefsFindInt32("screenmodes") & 1, GTK_SIGNAL_FUNC(tb_fs640x480));
|
||||
make_checkbox(vbox, STR_800x600_CTRL, PrefsFindInt32("screenmodes") & 2, GTK_SIGNAL_FUNC(tb_fs800x600));
|
||||
make_checkbox(vbox, STR_1024x768_CTRL, PrefsFindInt32("screenmodes") & 4, GTK_SIGNAL_FUNC(tb_fs1024x768));
|
||||
make_checkbox(vbox, STR_1152x900_CTRL, PrefsFindInt32("screenmodes") & 8, GTK_SIGNAL_FUNC(tb_fs1152x900));
|
||||
make_checkbox(vbox, STR_1280x1024_CTRL, PrefsFindInt32("screenmodes") & 16, GTK_SIGNAL_FUNC(tb_fs1280x1024));
|
||||
make_checkbox(vbox, STR_1600x1200_CTRL, PrefsFindInt32("screenmodes") & 32, GTK_SIGNAL_FUNC(tb_fs1600x1200));
|
||||
|
||||
make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Serial/Network" pane
|
||||
*/
|
||||
|
||||
static GtkWidget *w_seriala, *w_serialb, *w_ether;
|
||||
|
||||
// Read settings from widgets and set preferences
|
||||
static void read_serial_settings(void)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
str = gtk_entry_get_text(GTK_ENTRY(w_seriala));
|
||||
PrefsReplaceString("seriala", str);
|
||||
|
||||
str = gtk_entry_get_text(GTK_ENTRY(w_serialb));
|
||||
PrefsReplaceString("serialb", str);
|
||||
|
||||
str = gtk_entry_get_text(GTK_ENTRY(w_ether));
|
||||
if (str && strlen(str))
|
||||
PrefsReplaceString("ether", str);
|
||||
else
|
||||
PrefsRemoveItem("ether");
|
||||
}
|
||||
|
||||
// Add names of serial devices
|
||||
static gint gl_str_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return strcmp((char *)a, (char *)b);
|
||||
}
|
||||
|
||||
static GList *add_serial_names(void)
|
||||
{
|
||||
GList *glist = NULL;
|
||||
|
||||
// Search /dev for ttyS* and lp*
|
||||
DIR *d = opendir("/dev");
|
||||
if (d) {
|
||||
struct dirent *de;
|
||||
while ((de = readdir(d)) != NULL) {
|
||||
if (strncmp(de->d_name, "ttyS", 4) == 0 || strncmp(de->d_name, "lp", 2) == 0) {
|
||||
char *str = new char[64];
|
||||
sprintf(str, "/dev/%s", de->d_name);
|
||||
glist = g_list_append(glist, str);
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
if (glist)
|
||||
g_list_sort(glist, gl_str_cmp);
|
||||
else
|
||||
glist = g_list_append(glist, (void *)"<none>");
|
||||
return glist;
|
||||
}
|
||||
|
||||
// Add names of ethernet interfaces
|
||||
static GList *add_ether_names(void)
|
||||
{
|
||||
GList *glist = NULL;
|
||||
|
||||
// Get list of all Ethernet interfaces
|
||||
int s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
char inbuf[8192];
|
||||
struct ifconf ifc;
|
||||
ifc.ifc_len = sizeof(inbuf);
|
||||
ifc.ifc_buf = inbuf;
|
||||
if (ioctl(s, SIOCGIFCONF, &ifc) == 0) {
|
||||
struct ifreq req, *ifr = ifc.ifc_req;
|
||||
for (int i=0; i<ifc.ifc_len; i+=sizeof(ifreq), ifr++) {
|
||||
req = *ifr;
|
||||
if (ioctl(s, SIOCGIFHWADDR, &req) == 0 && req.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
|
||||
char *str = new char[64];
|
||||
strncpy(str, ifr->ifr_name, 63);
|
||||
glist = g_list_append(glist, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(s);
|
||||
}
|
||||
if (glist)
|
||||
g_list_sort(glist, gl_str_cmp);
|
||||
else
|
||||
glist = g_list_append(glist, (void *)"<none>");
|
||||
return glist;
|
||||
}
|
||||
|
||||
// Create "Serial/Network" pane
|
||||
static void create_serial_pane(GtkWidget *top)
|
||||
{
|
||||
GtkWidget *box, *table, *label, *combo;
|
||||
GList *glist = add_serial_names();
|
||||
|
||||
box = make_pane(top, STR_SERIAL_NETWORK_PANE_TITLE);
|
||||
table = make_table(box, 2, 3);
|
||||
|
||||
label = gtk_label_new(GetString(STR_SERPORTA_CTRL));
|
||||
gtk_widget_show(label);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
|
||||
|
||||
combo = gtk_combo_new();
|
||||
gtk_widget_show(combo);
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
|
||||
const char *str = PrefsFindString("seriala");
|
||||
if (str == NULL)
|
||||
str = "";
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
|
||||
gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
|
||||
w_seriala = GTK_COMBO(combo)->entry;
|
||||
|
||||
label = gtk_label_new(GetString(STR_SERPORTB_CTRL));
|
||||
gtk_widget_show(label);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
|
||||
|
||||
combo = gtk_combo_new();
|
||||
gtk_widget_show(combo);
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
|
||||
str = PrefsFindString("serialb");
|
||||
if (str == NULL)
|
||||
str = "";
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
|
||||
gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
|
||||
w_serialb = GTK_COMBO(combo)->entry;
|
||||
|
||||
label = gtk_label_new(GetString(STR_ETHERNET_IF_CTRL));
|
||||
gtk_widget_show(label);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
|
||||
|
||||
glist = add_ether_names();
|
||||
combo = gtk_combo_new();
|
||||
gtk_widget_show(combo);
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
|
||||
str = PrefsFindString("ether");
|
||||
if (str == NULL)
|
||||
str = "";
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), str);
|
||||
gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)0, 4, 4);
|
||||
w_ether = GTK_COMBO(combo)->entry;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Memory/Misc" pane
|
||||
*/
|
||||
|
||||
static GtkObject *w_ramsize_adj;
|
||||
static GtkWidget *w_rom_file;
|
||||
|
||||
// "Ignore SEGV" button toggled
|
||||
static void tb_ignoresegv(GtkWidget *widget)
|
||||
{
|
||||
PrefsReplaceBool("ignoresegv", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
|
||||
// Read settings from widgets and set preferences
|
||||
static void read_memory_settings(void)
|
||||
{
|
||||
PrefsReplaceInt32("ramsize", int(GTK_ADJUSTMENT(w_ramsize_adj)->value) << 20);
|
||||
|
||||
const char *str = gtk_entry_get_text(GTK_ENTRY(w_rom_file));
|
||||
if (str && strlen(str))
|
||||
PrefsReplaceString("rom", str);
|
||||
else
|
||||
PrefsRemoveItem("rom");
|
||||
}
|
||||
|
||||
// Create "Memory/Misc" pane
|
||||
static void create_memory_pane(GtkWidget *top)
|
||||
{
|
||||
GtkWidget *box, *vbox, *hbox, *hbox2, *label, *scale;
|
||||
|
||||
box = make_pane(top, STR_MEMORY_MISC_PANE_TITLE);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 4);
|
||||
gtk_widget_show(hbox);
|
||||
|
||||
label = gtk_label_new(GetString(STR_RAMSIZE_SLIDER));
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 4);
|
||||
gtk_widget_show(vbox);
|
||||
|
||||
gfloat min, max;
|
||||
min = 1;
|
||||
max = 256;
|
||||
w_ramsize_adj = gtk_adjustment_new(min, min, max, 1, 16, 0);
|
||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(w_ramsize_adj), PrefsFindInt32("ramsize") >> 20);
|
||||
|
||||
scale = gtk_hscale_new(GTK_ADJUSTMENT(w_ramsize_adj));
|
||||
gtk_widget_show(scale);
|
||||
gtk_scale_set_digits(GTK_SCALE(scale), 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0);
|
||||
|
||||
hbox2 = gtk_hbox_new(FALSE, 4);
|
||||
gtk_widget_show(hbox2);
|
||||
|
||||
char val[32];
|
||||
sprintf(val, GetString(STR_RAMSIZE_FMT), int(min));
|
||||
label = gtk_label_new(val);
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
|
||||
|
||||
sprintf(val, GetString(STR_RAMSIZE_FMT), int(max));
|
||||
label = gtk_label_new(val);
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_end(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
|
||||
|
||||
w_rom_file = make_entry(box, STR_ROM_FILE_CTRL, "rom");
|
||||
|
||||
make_checkbox(box, STR_IGNORESEGV_CTRL, "ignoresegv", GTK_SIGNAL_FUNC(tb_ignoresegv));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read settings from widgets and set preferences
|
||||
*/
|
||||
|
||||
static void read_settings(void)
|
||||
{
|
||||
read_volumes_settings();
|
||||
read_graphics_settings();
|
||||
read_serial_settings();
|
||||
read_memory_settings();
|
||||
}
|
97
SheepShaver/src/Unix/prefs_unix.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* prefs_unix.cpp - Preferences handling, Unix specific things
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prefs.h"
|
||||
|
||||
|
||||
// Platform-specific preferences items
|
||||
prefs_desc platform_prefs_items[] = {
|
||||
{"ether", TYPE_STRING, false, "device name of Mac ethernet adapter"},
|
||||
{NULL, TYPE_END, false, NULL} // End of list
|
||||
};
|
||||
|
||||
|
||||
// Prefs file name and path
|
||||
const char PREFS_FILE_NAME[] = ".sheepshaver_prefs";
|
||||
static char prefs_path[1024];
|
||||
|
||||
|
||||
/*
|
||||
* Load preferences from settings file
|
||||
*/
|
||||
|
||||
void LoadPrefs(void)
|
||||
{
|
||||
// Construct prefs path
|
||||
prefs_path[0] = 0;
|
||||
char *home = getenv("HOME");
|
||||
if (home != NULL && strlen(home) < 1000) {
|
||||
strncpy(prefs_path, home, 1000);
|
||||
strcat(prefs_path, "/");
|
||||
}
|
||||
strcat(prefs_path, PREFS_FILE_NAME);
|
||||
|
||||
// Read preferences from settings file
|
||||
FILE *f = fopen(prefs_path, "r");
|
||||
if (f != NULL) {
|
||||
|
||||
// Prefs file found, load settings
|
||||
LoadPrefsFromStream(f);
|
||||
fclose(f);
|
||||
|
||||
} else {
|
||||
|
||||
// No prefs file, save defaults
|
||||
SavePrefs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save preferences to settings file
|
||||
*/
|
||||
|
||||
void SavePrefs(void)
|
||||
{
|
||||
FILE *f;
|
||||
if ((f = fopen(prefs_path, "w")) != NULL) {
|
||||
SavePrefsToStream(f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add defaults of platform-specific prefs items
|
||||
* You may also override the defaults set in PrefsInit()
|
||||
*/
|
||||
|
||||
void AddPlatformPrefsDefaults(void)
|
||||
{
|
||||
PrefsReplaceString("extfs", "/");
|
||||
PrefsAddInt32("windowmodes", 3);
|
||||
PrefsAddInt32("screenmodes", 0x3f);
|
||||
}
|
136
SheepShaver/src/Unix/sysdeps.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* sysdeps.h - System dependent definitions for Linux
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 SYSDEPS_H
|
||||
#define SYSDEPS_H
|
||||
|
||||
#ifndef __STDC__
|
||||
#error "Your compiler is not ANSI. Get a real one."
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "user_strings_unix.h"
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
#error "You don't have ANSI C header files."
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Are we using a PPC emulator or the real thing?
|
||||
#ifdef __powerpc__
|
||||
#define EMULATED_PPC 0
|
||||
#else
|
||||
#define EMULATED_PPC 1
|
||||
#endif
|
||||
|
||||
#define POWERPC_ROM 1
|
||||
|
||||
// Data types
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
#if SIZEOF_SHORT == 2
|
||||
typedef unsigned short uint16;
|
||||
typedef short int16;
|
||||
#elif SIZEOF_INT == 2
|
||||
typedef unsigned int uint16;
|
||||
typedef int int16;
|
||||
#else
|
||||
#error "No 2 byte type, you lose."
|
||||
#endif
|
||||
#if SIZEOF_INT == 4
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32;
|
||||
#elif SIZEOF_LONG == 4
|
||||
typedef unsigned long uint32;
|
||||
typedef long int32;
|
||||
#else
|
||||
#error "No 4 byte type, you lose."
|
||||
#endif
|
||||
#if SIZEOF_LONG == 8
|
||||
typedef unsigned long uint64;
|
||||
typedef long int64;
|
||||
#elif SIZEOF_LONG_LONG == 8
|
||||
typedef unsigned long long uint64;
|
||||
typedef long long int64;
|
||||
#else
|
||||
#error "No 8 byte type, you lose."
|
||||
#endif
|
||||
|
||||
// Time data type for Time Manager emulation
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
typedef struct timespec tm_time_t;
|
||||
#else
|
||||
typedef struct timeval tm_time_t;
|
||||
#endif
|
||||
|
||||
// Various definitions
|
||||
typedef struct rgb_color {
|
||||
uint8 red;
|
||||
uint8 green;
|
||||
uint8 blue;
|
||||
uint8 alpha;
|
||||
} rgb_color;
|
||||
|
||||
// Macro for calling MacOS routines
|
||||
#define CallMacOS(type, tvect) call_macos((uint32)tvect)
|
||||
#define CallMacOS1(type, tvect, arg1) call_macos1((uint32)tvect, (uint32)arg1)
|
||||
#define CallMacOS2(type, tvect, arg1, arg2) call_macos2((uint32)tvect, (uint32)arg1, (uint32)arg2)
|
||||
#define CallMacOS3(type, tvect, arg1, arg2, arg3) call_macos3((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3)
|
||||
#define CallMacOS4(type, tvect, arg1, arg2, arg3, arg4) call_macos4((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3, (uint32)arg4)
|
||||
#define CallMacOS5(type, tvect, arg1, arg2, arg3, arg4, arg5) call_macos5((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3, (uint32)arg4, (uint32)arg5)
|
||||
#define CallMacOS6(type, tvect, arg1, arg2, arg3, arg4, arg5, arg6) call_macos6((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3, (uint32)arg4, (uint32)arg5, (uint32)arg6)
|
||||
#define CallMacOS7(type, tvect, arg1, arg2, arg3, arg4, arg5, arg6, arg7) call_macos7((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3, (uint32)arg4, (uint32)arg5, (uint32)arg6, (uint32)arg7)
|
||||
|
||||
extern "C" uint32 call_macos(uint32 tvect);
|
||||
extern "C" uint32 call_macos1(uint32 tvect, uint32 arg1);
|
||||
extern "C" uint32 call_macos2(uint32 tvect, uint32 arg1, uint32 arg2);
|
||||
extern "C" uint32 call_macos3(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3);
|
||||
extern "C" uint32 call_macos4(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4);
|
||||
extern "C" uint32 call_macos5(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5);
|
||||
extern "C" uint32 call_macos6(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5, uint32 arg6);
|
||||
extern "C" uint32 call_macos7(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5, uint32 arg6, uint32 arg7);
|
||||
|
||||
#endif
|
92
SheepShaver/src/Unix/user_strings_unix.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* user_strings_unix.cpp - Localizable strings, Unix specific strings
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "user_strings.h"
|
||||
|
||||
|
||||
// Platform-specific string definitions
|
||||
user_string_def platform_strings[] = {
|
||||
// Common strings that have a platform-specific variant
|
||||
{STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under Linux. Basilisk II will try to unmount it."},
|
||||
{STR_EXTFS_CTRL, "Linux Root"},
|
||||
{STR_EXTFS_NAME, "Linux Directory Tree"},
|
||||
{STR_EXTFS_VOLUME_NAME, "Linux"},
|
||||
|
||||
// Purely platform-specific strings
|
||||
{STR_NO_DEV_ZERO_ERR, "Cannot open /dev/zero: %s."},
|
||||
{STR_LOW_MEM_MMAP_ERR, "Cannot map Low Memory Globals: %s."},
|
||||
{STR_KD_SHMGET_ERR, "Cannot create SHM segment for Kernel Data: %s."},
|
||||
{STR_KD_SHMAT_ERR, "Cannot map first Kernel Data area: %s."},
|
||||
{STR_KD2_SHMAT_ERR, "Cannot map second Kernel Data area: %s."},
|
||||
{STR_ROM_MMAP_ERR, "Cannot map ROM: %s."},
|
||||
{STR_RAM_MMAP_ERR, "Cannot map RAM: %s."},
|
||||
{STR_SIGALTSTACK_ERR, "Cannot install alternate signal stack (%s). It seems that you need a newer kernel."},
|
||||
{STR_SIGSEGV_INSTALL_ERR, "Cannot install SIGSEGV handler: %s."},
|
||||
{STR_SIGILL_INSTALL_ERR, "Cannot install SIGILL handler: %s."},
|
||||
{STR_SIGUSR2_INSTALL_ERR, "Cannot install SIGUSR2 handler (%s). It seems that you need a newer libc."},
|
||||
{STR_NO_XSERVER_ERR, "Cannot connect to X server %s."},
|
||||
{STR_NO_XVISUAL_ERR, "Cannot obtain appropriate X visual."},
|
||||
{STR_UNSUPP_DEPTH_ERR, "Unsupported color depth of screen."},
|
||||
{STR_PROC_CPUINFO_WARN, "Cannot open /proc/cpuinfo (%s). Assuming 100MHz PowerPC 604."},
|
||||
{STR_NO_SHEEP_NET_DRIVER_WARN, "Cannot open %s (%s). Ethernet will not be available."},
|
||||
{STR_SHEEP_NET_ATTACH_WARN, "Cannot attach to Ethernet card (%s). Ethernet will not be available."},
|
||||
{STR_NO_AUDIO_DEV_WARN, "Cannot open %s (%s). Audio output will be disabled."},
|
||||
{STR_NO_AUDIO_WARN, "No audio device found, audio output will be disabled."},
|
||||
{STR_NO_ESD_WARN, "Cannot open ESD connection. Audio output will be disabled."},
|
||||
{STR_AUDIO_FORMAT_WARN, "/dev/dsp doesn't support signed 16 bit format. Audio output will be disabled."},
|
||||
{STR_SCSI_DEVICE_OPEN_WARN, "Cannot open %s (%s). SCSI Manager access to this device will be disabled."},
|
||||
{STR_SCSI_DEVICE_NOT_SCSI_WARN, "%s doesn't seem to comply to the Generic SCSI API. SCSI Manager access to this device will be disabled."},
|
||||
{STR_PREFS_MENU_FILE_GTK, "/_File"},
|
||||
{STR_PREFS_ITEM_START_GTK, "/File/_Start SheepShaver"},
|
||||
{STR_PREFS_ITEM_ZAP_PRAM_GTK, "/File/_Zap PRAM File"},
|
||||
{STR_PREFS_ITEM_SEPL_GTK, "/File/sepl"},
|
||||
{STR_PREFS_ITEM_QUIT_GTK, "/File/_Quit SheepShaver"},
|
||||
{STR_HELP_MENU_GTK, "/_Help"},
|
||||
{STR_HELP_ITEM_ABOUT_GTK, "/Help/_About SheepShaver"},
|
||||
{STR_SUSPEND_WINDOW_TITLE, "SheepShaver suspended. Press Space to reactivate."},
|
||||
|
||||
{-1, NULL} // End marker
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Fetch pointer to string, given the string number
|
||||
*/
|
||||
|
||||
const char *GetString(int num)
|
||||
{
|
||||
// First search for platform-specific string
|
||||
int i = 0;
|
||||
while (platform_strings[i].num >= 0) {
|
||||
if (platform_strings[i].num == num)
|
||||
return platform_strings[i].str;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Not found, search for common string
|
||||
i = 0;
|
||||
while (common_strings[i].num >= 0) {
|
||||
if (common_strings[i].num == num)
|
||||
return common_strings[i].str;
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
58
SheepShaver/src/Unix/user_strings_unix.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* user_strings_unix.h - Unix-specific localizable strings
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 USER_STRINGS_LINUX_H
|
||||
#define USER_STRINGS_LINUX_H
|
||||
|
||||
enum {
|
||||
STR_NO_DEV_ZERO_ERR = 10000,
|
||||
STR_LOW_MEM_MMAP_ERR,
|
||||
STR_KD_SHMGET_ERR,
|
||||
STR_KD_SHMAT_ERR,
|
||||
STR_KD2_SHMAT_ERR,
|
||||
STR_ROM_MMAP_ERR,
|
||||
STR_RAM_MMAP_ERR,
|
||||
STR_SIGALTSTACK_ERR,
|
||||
STR_SIGSEGV_INSTALL_ERR,
|
||||
STR_SIGILL_INSTALL_ERR,
|
||||
STR_SIGUSR2_INSTALL_ERR,
|
||||
STR_NO_XSERVER_ERR,
|
||||
STR_NO_XVISUAL_ERR,
|
||||
STR_UNSUPP_DEPTH_ERR,
|
||||
STR_PROC_CPUINFO_WARN,
|
||||
STR_NO_SHEEP_NET_DRIVER_WARN,
|
||||
STR_SHEEP_NET_ATTACH_WARN,
|
||||
STR_NO_AUDIO_DEV_WARN,
|
||||
STR_NO_AUDIO_WARN,
|
||||
STR_NO_ESD_WARN,
|
||||
STR_AUDIO_FORMAT_WARN,
|
||||
STR_SCSI_DEVICE_OPEN_WARN,
|
||||
STR_SCSI_DEVICE_NOT_SCSI_WARN,
|
||||
STR_PREFS_MENU_FILE_GTK,
|
||||
STR_PREFS_ITEM_START_GTK,
|
||||
STR_PREFS_ITEM_ZAP_PRAM_GTK,
|
||||
STR_PREFS_ITEM_SEPL_GTK,
|
||||
STR_PREFS_ITEM_QUIT_GTK,
|
||||
STR_HELP_MENU_GTK,
|
||||
STR_HELP_ITEM_ABOUT_GTK,
|
||||
STR_SUSPEND_WINDOW_TITLE
|
||||
};
|
||||
|
||||
#endif
|
1419
SheepShaver/src/Unix/video_x.cpp
Normal file
24
SheepShaver/src/VideoDriverStub.i
Normal file
@ -0,0 +1,24 @@
|
||||
0x4a, 0x6f, 0x79, 0x21, 0x70, 0x65, 0x66, 0x66, 0x70, 0x77, 0x70, 0x63, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0x10,
|
||||
0x00, 0x04, 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c,
|
||||
0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x01, 0x40, 0x02, 0x01, 0x04, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x80, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x68,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x54, 0x68, 0x65, 0x44, 0x72, 0x69, 0x76, 0x65,
|
||||
0x72, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x44, 0x72,
|
||||
0x69, 0x76, 0x65, 0x72, 0x49, 0x4f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,
|
||||
0x00, 0x14, 0xbd, 0xe0, 0x00, 0x0a, 0xd1, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x00, 0x01, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x90, 0x61, 0x00, 0x18, 0x90, 0x81, 0x00, 0x1c, 0x90, 0xa1, 0x00, 0x20, 0x90, 0xc1, 0x00, 0x24,
|
||||
0x90, 0xe1, 0x00, 0x28, 0x80, 0x40, 0x28, 0x08, 0x80, 0x00, 0x28, 0xd8, 0x7c, 0x09, 0x03, 0xa6,
|
||||
0x4e, 0x80, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x24, 0x6d, 0x74, 0x65, 0x6a, 0x04, 0x26, 0x05, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x1a, 0x21,
|
||||
0x01, 0x01, 0x21, 0x80, 0x04, 0x3b, 0x06, 0x19, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f,
|
||||
0x56, 0x69, 0x64, 0x65, 0x6f, 0x5f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x5f, 0x53, 0x68, 0x65, 0x65,
|
||||
0x70, 0x00, 0x29, 0x2a, 0x01, 0x6e, 0x64, 0x72, 0x76, 0x76, 0x69, 0x64, 0x6f, 0x01, 0x03,
|
477
SheepShaver/src/emul_op.cpp
Normal file
@ -0,0 +1,477 @@
|
||||
/*
|
||||
* emul_op.cpp - 68k opcodes for ROM patches
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "main.h"
|
||||
#include "version.h"
|
||||
#include "prefs.h"
|
||||
#include "cpu_emulation.h"
|
||||
#include "xlowmem.h"
|
||||
#include "xpram.h"
|
||||
#include "timer.h"
|
||||
#include "adb.h"
|
||||
#include "sony.h"
|
||||
#include "disk.h"
|
||||
#include "cdrom.h"
|
||||
#include "scsi.h"
|
||||
#include "video.h"
|
||||
#include "audio.h"
|
||||
#include "ether.h"
|
||||
#include "serial.h"
|
||||
#include "clip.h"
|
||||
#include "extfs.h"
|
||||
#include "macos_util.h"
|
||||
#include "rom_patches.h"
|
||||
#include "rsrc_patches.h"
|
||||
#include "name_registry.h"
|
||||
#include "user_strings.h"
|
||||
#include "emul_op.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#if __BEOS__
|
||||
#define PRECISE_TIMING 1
|
||||
#else
|
||||
#define PRECISE_TIMING 0
|
||||
#endif
|
||||
|
||||
|
||||
// TVector of MakeExecutable
|
||||
static uint32 *MakeExecutableTvec;
|
||||
|
||||
|
||||
/*
|
||||
* Execute EMUL_OP opcode (called by 68k emulator)
|
||||
*/
|
||||
|
||||
void EmulOp(M68kRegisters *r, uint32 pc, int selector)
|
||||
{
|
||||
|
||||
D(bug("EmulOp %04x at %08x\n", selector, pc));
|
||||
switch (selector) {
|
||||
case OP_BREAK: // Breakpoint
|
||||
printf("*** Breakpoint\n");
|
||||
Dump68kRegs(r);
|
||||
break;
|
||||
|
||||
case OP_XPRAM1: { // Read/write from/to XPRam
|
||||
uint32 len = r->d[3];
|
||||
uint8 *adr = Mac2HostAddr(r->a[3]);
|
||||
D(bug("XPRAMReadWrite d3: %08lx, a3: %p\n", len, adr));
|
||||
int ofs = len & 0xffff;
|
||||
len >>= 16;
|
||||
if (len & 0x8000) {
|
||||
len &= 0x7fff;
|
||||
for (uint32 i=0; i<len; i++)
|
||||
XPRAM[((ofs + i) & 0xff) + 0x1300] = *adr++;
|
||||
} else {
|
||||
for (uint32 i=0; i<len; i++)
|
||||
*adr++ = XPRAM[((ofs + i) & 0xff) + 0x1300];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_XPRAM2: // Read from XPRam
|
||||
r->d[1] = XPRAM[(r->d[1] & 0xff) + 0x1300];
|
||||
break;
|
||||
|
||||
case OP_XPRAM3: // Write to XPRam
|
||||
XPRAM[(r->d[1] & 0xff) + 0x1300] = r->d[2];
|
||||
break;
|
||||
|
||||
case OP_NVRAM1: { // Read from NVRAM
|
||||
int ofs = r->d[0];
|
||||
r->d[0] = XPRAM[ofs & 0x1fff];
|
||||
bool localtalk = !(XPRAM[0x13e0] || XPRAM[0x13e1]); // LocalTalk enabled?
|
||||
switch (ofs) {
|
||||
case 0x13e0: // Disable LocalTalk (use EtherTalk instead)
|
||||
if (localtalk)
|
||||
r->d[0] = 0x00;
|
||||
break;
|
||||
case 0x13e1:
|
||||
if (localtalk)
|
||||
r->d[0] = 0x01;
|
||||
break;
|
||||
case 0x13e2:
|
||||
if (localtalk)
|
||||
r->d[0] = 0x00;
|
||||
break;
|
||||
case 0x13e3:
|
||||
if (localtalk)
|
||||
r->d[0] = 0x0a;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_NVRAM2: // Write to NVRAM
|
||||
XPRAM[r->d[0] & 0x1fff] = r->d[1];
|
||||
break;
|
||||
|
||||
case OP_NVRAM3: // Read/write from/to NVRAM
|
||||
if (r->d[3]) {
|
||||
r->d[0] = XPRAM[(r->d[4] + 0x1300) & 0x1fff];
|
||||
} else {
|
||||
XPRAM[(r->d[4] + 0x1300) & 0x1fff] = r->d[5];
|
||||
r->d[0] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_FIX_MEMTOP: // Fixes MemTop in BootGlobs during startup
|
||||
D(bug("Fix MemTop\n"));
|
||||
WriteMacInt32(BootGlobsAddr - 20, RAMBase + RAMSize); // MemTop
|
||||
r->a[6] = RAMBase + RAMSize;
|
||||
break;
|
||||
|
||||
case OP_FIX_MEMSIZE: { // Fixes physical/logical RAM size during startup
|
||||
D(bug("Fix MemSize\n"));
|
||||
uint32 diff = ReadMacInt32(0x1ef8) - ReadMacInt32(0x1ef4);
|
||||
WriteMacInt32(0x1ef8, RAMSize); // Physical RAM size
|
||||
WriteMacInt32(0x1ef4, RAMSize - diff); // Logical RAM size
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_FIX_BOOTSTACK: // Fixes boot stack pointer in boot 3 resource
|
||||
D(bug("Fix BootStack\n"));
|
||||
r->a[1] = r->a[7] = RAMBase + RAMSize * 3 / 4;
|
||||
break;
|
||||
|
||||
case OP_SONY_OPEN: // Floppy driver functions
|
||||
r->d[0] = SonyOpen(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_SONY_PRIME:
|
||||
r->d[0] = SonyPrime(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_SONY_CONTROL:
|
||||
r->d[0] = SonyControl(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_SONY_STATUS:
|
||||
r->d[0] = SonyStatus(r->a[0], r->a[1]);
|
||||
break;
|
||||
|
||||
case OP_DISK_OPEN: // Disk driver functions
|
||||
r->d[0] = DiskOpen(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_DISK_PRIME:
|
||||
r->d[0] = DiskPrime(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_DISK_CONTROL:
|
||||
r->d[0] = DiskControl(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_DISK_STATUS:
|
||||
r->d[0] = DiskStatus(r->a[0], r->a[1]);
|
||||
break;
|
||||
|
||||
case OP_CDROM_OPEN: // CD-ROM driver functions
|
||||
r->d[0] = CDROMOpen(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_CDROM_PRIME:
|
||||
r->d[0] = CDROMPrime(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_CDROM_CONTROL:
|
||||
r->d[0] = CDROMControl(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_CDROM_STATUS:
|
||||
r->d[0] = CDROMStatus(r->a[0], r->a[1]);
|
||||
break;
|
||||
|
||||
case OP_AUDIO_DISPATCH: // Audio component functions
|
||||
r->d[0] = AudioDispatch(r->a[3], r->a[4]);
|
||||
break;
|
||||
|
||||
case OP_SOUNDIN_OPEN: // Sound input driver functions
|
||||
r->d[0] = SoundInOpen(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_SOUNDIN_PRIME:
|
||||
r->d[0] = SoundInPrime(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_SOUNDIN_CONTROL:
|
||||
r->d[0] = SoundInControl(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_SOUNDIN_STATUS:
|
||||
r->d[0] = SoundInStatus(r->a[0], r->a[1]);
|
||||
break;
|
||||
case OP_SOUNDIN_CLOSE:
|
||||
r->d[0] = SoundInClose(r->a[0], r->a[1]);
|
||||
break;
|
||||
|
||||
case OP_ADBOP: // ADBOp() replacement
|
||||
ADBOp(r->d[0], Mac2HostAddr(ReadMacInt32(r->a[0])));
|
||||
break;
|
||||
|
||||
case OP_INSTIME: // InsTime() replacement
|
||||
r->d[0] = InsTime(r->a[0], r->d[1]);
|
||||
break;
|
||||
case OP_RMVTIME: // RmvTime() replacement
|
||||
r->d[0] = RmvTime(r->a[0]);
|
||||
break;
|
||||
case OP_PRIMETIME: // PrimeTime() replacement
|
||||
r->d[0] = PrimeTime(r->a[0], r->d[0]);
|
||||
break;
|
||||
|
||||
case OP_MICROSECONDS: // Microseconds() replacement
|
||||
Microseconds(r->a[0], r->d[0]);
|
||||
break;
|
||||
|
||||
case OP_PUT_SCRAP: // PutScrap() patch
|
||||
PutScrap(ReadMacInt32(r->a[7] + 8), Mac2HostAddr(ReadMacInt32(r->a[7] + 4)), ReadMacInt32(r->a[7] + 12));
|
||||
break;
|
||||
|
||||
case OP_GET_SCRAP: // GetScrap() patch
|
||||
GetScrap((void **)Mac2HostAddr(ReadMacInt32(r->a[7] + 4)), ReadMacInt32(r->a[7] + 8), ReadMacInt32(r->a[7] + 12));
|
||||
break;
|
||||
|
||||
case OP_DEBUG_STR: // DebugStr() shows warning message
|
||||
if (PrefsFindBool("nogui")) {
|
||||
uint8 *pstr = Mac2HostAddr(ReadMacInt32(r->a[7] + 4));
|
||||
char str[256];
|
||||
int i;
|
||||
for (i=0; i<pstr[0]; i++)
|
||||
str[i] = pstr[i+1];
|
||||
str[i] = 0;
|
||||
WarningAlert(str);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_INSTALL_DRIVERS: { // Patch to install our own drivers during startup
|
||||
// Install drivers
|
||||
InstallDrivers();
|
||||
|
||||
#if !EMULATED_PPC
|
||||
// Patch MakeExecutable()
|
||||
MakeExecutableTvec = (uint32 *)FindLibSymbol("\023PrivateInterfaceLib", "\016MakeExecutable");
|
||||
D(bug("MakeExecutable TVECT at %p\n", MakeExecutableTvec));
|
||||
#ifdef __BEOS__
|
||||
MakeExecutableTvec[0] = ((uint32 *)MakeExecutable)[0];
|
||||
#else
|
||||
MakeExecutableTvec[0] = (uint32)MakeExecutable;
|
||||
#endif
|
||||
MakeExecutableTvec[1] = (uint32)TOC;
|
||||
#endif
|
||||
|
||||
// Patch DebugStr()
|
||||
static const uint16 proc[] = {
|
||||
M68K_EMUL_OP_DEBUG_STR,
|
||||
0x4e74, // rtd #4
|
||||
0x0004
|
||||
};
|
||||
WriteMacInt32(0x1dfc, (uint32)proc);
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_NAME_REGISTRY: // Patch Name Registry and initialize CallUniversalProc
|
||||
r->d[0] = (uint32)-1;
|
||||
PatchNameRegistry();
|
||||
InitCallUniversalProc();
|
||||
break;
|
||||
|
||||
case OP_RESET: // Early in MacOS reset
|
||||
D(bug("*** RESET ***\n"));
|
||||
TimerReset();
|
||||
MacOSUtilReset();
|
||||
AudioReset();
|
||||
#if 0
|
||||
printf("DR activated\n");
|
||||
WriteMacInt32(KernelDataAddr + 0x17a0, 3); // Prepare for DR emulator activation
|
||||
WriteMacInt32(KernelDataAddr + 0x17c0, DR_CACHE_BASE);
|
||||
WriteMacInt32(KernelDataAddr + 0x17c4, DR_CACHE_SIZE);
|
||||
WriteMacInt32(KernelDataAddr + 0x1b00, DR_CACHE_BASE + 0x10000);
|
||||
memcpy((void *)(DR_CACHE_BASE + 0x10000), (void *)(ROM_BASE + 0x370000), 0x10000);
|
||||
clear_caches((void *)(DR_CACHE_BASE + 0x10000), 0x10000, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OP_IRQ: // Level 1 interrupt
|
||||
WriteMacInt16(ReadMacInt32(KernelDataAddr + 0x67c), 0); // Clear interrupt
|
||||
r->d[0] = 0;
|
||||
if (HasMacStarted()) {
|
||||
if (InterruptFlags & INTFLAG_VIA) {
|
||||
ClearInterruptFlag(INTFLAG_VIA);
|
||||
#if !PRECISE_TIMING
|
||||
TimerInterrupt();
|
||||
#endif
|
||||
ExecutePPC(VideoVBL);
|
||||
|
||||
static int tick_counter = 0;
|
||||
if (++tick_counter >= 60) {
|
||||
tick_counter = 0;
|
||||
SonyInterrupt();
|
||||
DiskInterrupt();
|
||||
CDROMInterrupt();
|
||||
}
|
||||
|
||||
r->d[0] = 1; // Flag: 68k interrupt routine executes VBLTasks etc.
|
||||
}
|
||||
if (InterruptFlags & INTFLAG_SERIAL) {
|
||||
ClearInterruptFlag(INTFLAG_SERIAL);
|
||||
SerialInterrupt();
|
||||
}
|
||||
if (InterruptFlags & INTFLAG_ETHER) {
|
||||
ClearInterruptFlag(INTFLAG_ETHER);
|
||||
ExecutePPC(EtherIRQ);
|
||||
}
|
||||
if (InterruptFlags & INTFLAG_TIMER) {
|
||||
ClearInterruptFlag(INTFLAG_TIMER);
|
||||
TimerInterrupt();
|
||||
}
|
||||
if (InterruptFlags & INTFLAG_AUDIO) {
|
||||
ClearInterruptFlag(INTFLAG_AUDIO);
|
||||
AudioInterrupt();
|
||||
}
|
||||
if (InterruptFlags & INTFLAG_ADB) {
|
||||
ClearInterruptFlag(INTFLAG_ADB);
|
||||
ADBInterrupt();
|
||||
}
|
||||
} else
|
||||
r->d[0] = 1;
|
||||
break;
|
||||
|
||||
case OP_SCSI_DISPATCH: { // SCSIDispatch() replacement
|
||||
uint32 ret = ReadMacInt32(r->a[7]);
|
||||
uint16 sel = ReadMacInt16(r->a[7] + 4);
|
||||
r->a[7] += 6;
|
||||
// D(bug("SCSIDispatch(%d)\n", sel));
|
||||
int stack;
|
||||
switch (sel) {
|
||||
case 0: // SCSIReset
|
||||
WriteMacInt16(r->a[7], SCSIReset());
|
||||
stack = 0;
|
||||
break;
|
||||
case 1: // SCSIGet
|
||||
WriteMacInt16(r->a[7], SCSIGet());
|
||||
stack = 0;
|
||||
break;
|
||||
case 2: // SCSISelect
|
||||
case 11: // SCSISelAtn
|
||||
WriteMacInt16(r->a[7] + 2, SCSISelect(ReadMacInt8(r->a[7] + 1)));
|
||||
stack = 2;
|
||||
break;
|
||||
case 3: // SCSICmd
|
||||
WriteMacInt16(r->a[7] + 6, SCSICmd(ReadMacInt16(r->a[7]), Mac2HostAddr(ReadMacInt32(r->a[7] + 2))));
|
||||
stack = 6;
|
||||
break;
|
||||
case 4: // SCSIComplete
|
||||
WriteMacInt16(r->a[7] + 12, SCSIComplete(ReadMacInt32(r->a[7]), ReadMacInt32(r->a[7] + 4), ReadMacInt32(r->a[7] + 8)));
|
||||
stack = 12;
|
||||
break;
|
||||
case 5: // SCSIRead
|
||||
case 8: // SCSIRBlind
|
||||
WriteMacInt16(r->a[7] + 4, SCSIRead(ReadMacInt32(r->a[7])));
|
||||
stack = 4;
|
||||
break;
|
||||
case 6: // SCSIWrite
|
||||
case 9: // SCSIWBlind
|
||||
WriteMacInt16(r->a[7] + 4, SCSIWrite(ReadMacInt32(r->a[7])));
|
||||
stack = 4;
|
||||
break;
|
||||
case 10: // SCSIStat
|
||||
WriteMacInt16(r->a[7], SCSIStat());
|
||||
stack = 0;
|
||||
break;
|
||||
case 12: // SCSIMsgIn
|
||||
WriteMacInt16(r->a[7] + 4, 0);
|
||||
stack = 4;
|
||||
break;
|
||||
case 13: // SCSIMsgOut
|
||||
WriteMacInt16(r->a[7] + 2, 0);
|
||||
stack = 2;
|
||||
break;
|
||||
case 14: // SCSIMgrBusy
|
||||
WriteMacInt16(r->a[7], SCSIMgrBusy());
|
||||
stack = 0;
|
||||
break;
|
||||
default:
|
||||
printf("FATAL: SCSIDispatch: illegal selector\n");
|
||||
stack = 0;
|
||||
//!! SysError(12)
|
||||
}
|
||||
r->a[0] = ret;
|
||||
r->a[7] += stack;
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_SCSI_ATOMIC: // SCSIAtomic() replacement
|
||||
D(bug("SCSIAtomic\n"));
|
||||
r->d[0] = (uint32)-7887;
|
||||
break;
|
||||
|
||||
case OP_NTRB_17_PATCH:
|
||||
r->a[2] = ReadMacInt32(r->a[7]);
|
||||
r->a[7] += 4;
|
||||
if (ReadMacInt16(r->a[2] + 6) == 17)
|
||||
PatchNativeResourceManager();
|
||||
break;
|
||||
|
||||
case OP_NTRB_17_PATCH2:
|
||||
r->a[7] += 8;
|
||||
PatchNativeResourceManager();
|
||||
break;
|
||||
|
||||
case OP_NTRB_17_PATCH3:
|
||||
r->a[2] = ReadMacInt32(r->a[7]);
|
||||
r->a[7] += 4;
|
||||
D(bug("%d %d\n", ReadMacInt16(r->a[2]), ReadMacInt16(r->a[2] + 6)));
|
||||
if (ReadMacInt16(r->a[2]) == 11 && ReadMacInt16(r->a[2] + 6) == 17)
|
||||
PatchNativeResourceManager();
|
||||
break;
|
||||
|
||||
case OP_CHECKLOAD: { // vCheckLoad() patch
|
||||
uint32 type = ReadMacInt32(r->a[7]);
|
||||
r->a[7] += 4;
|
||||
int16 id = ReadMacInt16(r->a[2]);
|
||||
if (r->a[0] == 0)
|
||||
break;
|
||||
uint32 adr = ReadMacInt32(r->a[0]);
|
||||
if (adr == 0)
|
||||
break;
|
||||
uint16 *p = (uint16 *)Mac2HostAddr(adr);
|
||||
uint32 size = ReadMacInt32(adr - 8) & 0xffffff;
|
||||
CheckLoad(type, id, p, size);
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_EXTFS_COMM: // External file system routines
|
||||
WriteMacInt16(r->a[7] + 14, ExtFSComm(ReadMacInt16(r->a[7] + 12), ReadMacInt32(r->a[7] + 8), ReadMacInt32(r->a[7] + 4)));
|
||||
break;
|
||||
|
||||
case OP_EXTFS_HFS:
|
||||
WriteMacInt16(r->a[7] + 20, ExtFSHFS(ReadMacInt32(r->a[7] + 16), ReadMacInt16(r->a[7] + 14), ReadMacInt32(r->a[7] + 10), ReadMacInt32(r->a[7] + 6), ReadMacInt16(r->a[7] + 4)));
|
||||
break;
|
||||
|
||||
case OP_IDLE_TIME:
|
||||
#if __BEOS__
|
||||
// Sleep if no events pending
|
||||
if (ReadMacInt32(0x14c) == 0) {
|
||||
sleep(16667);
|
||||
}
|
||||
#endif
|
||||
r->a[0] = ReadMacInt32(0x2b6);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("FATAL: EMUL_OP called with bogus selector %08x\n", selector);
|
||||
QuitEmulator();
|
||||
break;
|
||||
}
|
||||
}
|
1661
SheepShaver/src/emul_ppc/emul_ppc.cpp
Normal file
1632
SheepShaver/src/ether.cpp
Normal file
26
SheepShaver/src/include/about_window.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* about_window.h - "About" window
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 ABOUT_WINDOW_H
|
||||
#define ABOUT_WINDOW_H
|
||||
|
||||
extern void OpenAboutWindow(void);
|
||||
|
||||
#endif
|
73
SheepShaver/src/include/cpu_emulation.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* cpu_emulation.h - Definitions for CPU emulation and Mac memory access
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 CPU_EMULATION_H
|
||||
#define CPU_EMULATION_H
|
||||
|
||||
|
||||
/*
|
||||
* Memory system
|
||||
*/
|
||||
|
||||
// Constants
|
||||
const uint32 ROM_BASE = 0x40800000; // Base address of ROM
|
||||
const uint32 ROM_SIZE = 0x00400000; // Size of ROM file
|
||||
const uint32 DR_CACHE_BASE = 0x69000000; // Address of DR cache
|
||||
const uint32 DR_CACHE_SIZE = 0x80000; // Size of DR Cache
|
||||
|
||||
// RAM and ROM pointers (allocated and set by main_*.cpp)
|
||||
extern uint32 RAMBase; // Base address of Mac RAM
|
||||
extern uint32 RAMSize; // Size address of Mac RAM
|
||||
|
||||
// Mac memory access functions
|
||||
static inline uint32 ReadMacInt8(uint32 addr) {return *(uint8 *)addr;}
|
||||
static inline void WriteMacInt8(uint32 addr, uint32 b) {*(uint8 *)addr = b;}
|
||||
#ifdef __i386__
|
||||
static inline uint32 ReadMacInt16(uint32 addr) {uint32 retval; __asm__ ("movzwl %w1,%k0\n\tshll $16,%k0\n\tbswapl %k0\n" : "=&r" (retval) : "m" (*(uint16 *)addr) : "cc"); return retval;}
|
||||
static inline uint32 ReadMacInt32(uint32 addr) {uint32 retval; __asm__ ("bswap %0" : "=r" (retval) : "0" (*(uint32 *)addr) : "cc"); return retval;}
|
||||
static inline uint64 ReadMacInt64(uint32 addr) {return ((uint64)ReadMacInt32(addr) << 32) | ReadMacInt32(addr + 4);}
|
||||
static inline void WriteMacInt16(uint32 addr, uint32 w) {__asm__ ("bswapl %0" : "=&r" (w) : "0" (w << 16) : "cc"); *(uint16 *)addr = w;}
|
||||
static inline void WriteMacInt32(uint32 addr, uint32 l) {__asm__ ("bswap %0" : "=r" (l) : "0" (l) : "cc"); *(uint32 *)addr = l;}
|
||||
static inline void WriteMacInt64(uint32 addr, uint64 ll) {WriteMacInt32(addr, ll >> 32); WriteMacInt32(addr, ll);}
|
||||
#else
|
||||
static inline uint32 ReadMacInt16(uint32 addr) {return *(uint16 *)addr;}
|
||||
static inline uint32 ReadMacInt32(uint32 addr) {return *(uint32 *)addr;}
|
||||
static inline uint64 ReadMacInt64(uint32 addr) {return *(uint64 *)addr;}
|
||||
static inline void WriteMacInt16(uint32 addr, uint32 w) {*(uint16 *)addr = w;}
|
||||
static inline void WriteMacInt32(uint32 addr, uint32 l) {*(uint32 *)addr = l;}
|
||||
static inline void WriteMacInt64(uint32 addr, uint64 ll) {*(uint64 *)addr = ll;}
|
||||
#endif
|
||||
static inline uint8 *Mac2HostAddr(uint32 addr) {return (uint8 *)addr;}
|
||||
static inline void *Mac_memset(uint32 addr, int c, size_t n) {return memset(Mac2HostAddr(addr), c, n);}
|
||||
static inline void *Mac2Host_memcpy(void *dest, uint32 src, size_t n) {return memcpy(dest, Mac2HostAddr(src), n);}
|
||||
static inline void *Host2Mac_memcpy(uint32 dest, const void *src, size_t n) {return memcpy(Mac2HostAddr(dest), src, n);}
|
||||
static inline void *Mac2Mac_memcpy(uint32 dest, uint32 src, size_t n) {return memcpy(Mac2HostAddr(dest), Mac2HostAddr(src), n);}
|
||||
|
||||
|
||||
/*
|
||||
* 680x0 and PPC emulation
|
||||
*/
|
||||
|
||||
struct M68kRegisters;
|
||||
extern void Execute68k(uint32, M68kRegisters *r); // Execute 68k subroutine from EMUL_OP routine, must be ended with RTS
|
||||
extern void Execute68kTrap(uint16 trap, M68kRegisters *r); // Execute 68k A-Trap from EMUL_OP routine
|
||||
extern void ExecutePPC(void (*func)()); // Execute PPC code from EMUL_OP routine (real mode switch)
|
||||
|
||||
#endif
|
108
SheepShaver/src/include/emul_op.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* emul_op.h - 68k opcodes for ROM patches
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 EMUL_OP_H
|
||||
#define EMUL_OP_H
|
||||
|
||||
// PowerPC opcodes
|
||||
const uint32 POWERPC_NOP = 0x60000000;
|
||||
const uint32 POWERPC_ILLEGAL = 0x00000000;
|
||||
const uint32 POWERPC_BLR = 0x4e800020;
|
||||
const uint32 POWERPC_BCTR = 0x4e800420;
|
||||
const uint32 POWERPC_EMUL_OP = 0x18000000; // Base opcode for EMUL_OP opcodes (only used with PPC emulation)
|
||||
|
||||
// 68k opcodes
|
||||
const uint16 M68K_ILLEGAL = 0x4afc;
|
||||
const uint16 M68K_NOP = 0x4e71;
|
||||
const uint16 M68K_RTS = 0x4e75;
|
||||
const uint16 M68K_RTD = 0x4e74;
|
||||
const uint16 M68K_JMP = 0x4ef9;
|
||||
const uint16 M68K_JMP_A0 = 0x4ed0;
|
||||
const uint16 M68K_JSR = 0x4eb9;
|
||||
const uint16 M68K_JSR_A0 = 0x4e90;
|
||||
enum { // Selectors for EMUL_OP opcodes
|
||||
OP_BREAK, OP_XPRAM1, OP_XPRAM2, OP_XPRAM3, OP_NVRAM1, OP_NVRAM2, OP_NVRAM3,
|
||||
OP_FIX_MEMTOP, OP_FIX_MEMSIZE, OP_FIX_BOOTSTACK,
|
||||
OP_SONY_OPEN, OP_SONY_PRIME, OP_SONY_CONTROL, OP_SONY_STATUS,
|
||||
OP_DISK_OPEN, OP_DISK_PRIME, OP_DISK_CONTROL, OP_DISK_STATUS,
|
||||
OP_CDROM_OPEN, OP_CDROM_PRIME, OP_CDROM_CONTROL, OP_CDROM_STATUS,
|
||||
OP_AUDIO_DISPATCH, OP_SOUNDIN_OPEN, OP_SOUNDIN_PRIME, OP_SOUNDIN_CONTROL, OP_SOUNDIN_STATUS, OP_SOUNDIN_CLOSE,
|
||||
OP_ADBOP, OP_INSTIME, OP_RMVTIME, OP_PRIMETIME, OP_MICROSECONDS, OP_PUT_SCRAP, OP_GET_SCRAP,
|
||||
OP_DEBUG_STR, OP_INSTALL_DRIVERS, OP_NAME_REGISTRY, OP_RESET, OP_IRQ,
|
||||
OP_SCSI_DISPATCH, OP_SCSI_ATOMIC,
|
||||
OP_NTRB_17_PATCH, OP_NTRB_17_PATCH2, OP_NTRB_17_PATCH3, OP_CHECKLOAD,
|
||||
OP_EXTFS_COMM, OP_EXTFS_HFS, OP_IDLE_TIME,
|
||||
OP_MAX
|
||||
};
|
||||
const uint16 M68K_EMUL_RETURN = 0xfe40; // Extended opcodes
|
||||
const uint16 M68K_EXEC_RETURN = 0xfe41;
|
||||
const uint16 M68K_EMUL_BREAK = 0xfe42;
|
||||
const uint16 M68K_EMUL_OP_XPRAM1 = M68K_EMUL_BREAK + OP_XPRAM1;
|
||||
const uint16 M68K_EMUL_OP_XPRAM2 = M68K_EMUL_BREAK + OP_XPRAM2;
|
||||
const uint16 M68K_EMUL_OP_XPRAM3 = M68K_EMUL_BREAK + OP_XPRAM3;
|
||||
const uint16 M68K_EMUL_OP_NVRAM1 = M68K_EMUL_BREAK + OP_NVRAM1;
|
||||
const uint16 M68K_EMUL_OP_NVRAM2 = M68K_EMUL_BREAK + OP_NVRAM2;
|
||||
const uint16 M68K_EMUL_OP_NVRAM3 = M68K_EMUL_BREAK + OP_NVRAM3;
|
||||
const uint16 M68K_EMUL_OP_FIX_MEMTOP = M68K_EMUL_BREAK + OP_FIX_MEMTOP;
|
||||
const uint16 M68K_EMUL_OP_FIX_MEMSIZE = M68K_EMUL_BREAK + OP_FIX_MEMSIZE;
|
||||
const uint16 M68K_EMUL_OP_FIX_BOOTSTACK = M68K_EMUL_BREAK + OP_FIX_BOOTSTACK;
|
||||
const uint16 M68K_EMUL_OP_SONY_OPEN = M68K_EMUL_BREAK + OP_SONY_OPEN;
|
||||
const uint16 M68K_EMUL_OP_SONY_PRIME = M68K_EMUL_BREAK + OP_SONY_PRIME;
|
||||
const uint16 M68K_EMUL_OP_SONY_CONTROL = M68K_EMUL_BREAK + OP_SONY_CONTROL;
|
||||
const uint16 M68K_EMUL_OP_SONY_STATUS = M68K_EMUL_BREAK + OP_SONY_STATUS;
|
||||
const uint16 M68K_EMUL_OP_DISK_OPEN = M68K_EMUL_BREAK + OP_DISK_OPEN;
|
||||
const uint16 M68K_EMUL_OP_DISK_PRIME = M68K_EMUL_BREAK + OP_DISK_PRIME;
|
||||
const uint16 M68K_EMUL_OP_DISK_CONTROL = M68K_EMUL_BREAK + OP_DISK_CONTROL;
|
||||
const uint16 M68K_EMUL_OP_DISK_STATUS = M68K_EMUL_BREAK + OP_DISK_STATUS;
|
||||
const uint16 M68K_EMUL_OP_CDROM_OPEN = M68K_EMUL_BREAK + OP_CDROM_OPEN;
|
||||
const uint16 M68K_EMUL_OP_CDROM_PRIME = M68K_EMUL_BREAK + OP_CDROM_PRIME;
|
||||
const uint16 M68K_EMUL_OP_CDROM_CONTROL = M68K_EMUL_BREAK + OP_CDROM_CONTROL;
|
||||
const uint16 M68K_EMUL_OP_CDROM_STATUS = M68K_EMUL_BREAK + OP_CDROM_STATUS;
|
||||
const uint16 M68K_EMUL_OP_AUDIO_DISPATCH = M68K_EMUL_BREAK + OP_AUDIO_DISPATCH;
|
||||
const uint16 M68K_EMUL_OP_SOUNDIN_OPEN = M68K_EMUL_BREAK + OP_SOUNDIN_OPEN;
|
||||
const uint16 M68K_EMUL_OP_SOUNDIN_CLOSE = M68K_EMUL_BREAK + OP_SOUNDIN_CLOSE;
|
||||
const uint16 M68K_EMUL_OP_SOUNDIN_PRIME = M68K_EMUL_BREAK + OP_SOUNDIN_PRIME;
|
||||
const uint16 M68K_EMUL_OP_SOUNDIN_CONTROL = M68K_EMUL_BREAK + OP_SOUNDIN_CONTROL;
|
||||
const uint16 M68K_EMUL_OP_SOUNDIN_STATUS = M68K_EMUL_BREAK + OP_SOUNDIN_STATUS;
|
||||
const uint16 M68K_EMUL_OP_ADBOP = M68K_EMUL_BREAK + OP_ADBOP;
|
||||
const uint16 M68K_EMUL_OP_INSTIME = M68K_EMUL_BREAK + OP_INSTIME;
|
||||
const uint16 M68K_EMUL_OP_RMVTIME = M68K_EMUL_BREAK + OP_RMVTIME;
|
||||
const uint16 M68K_EMUL_OP_PRIMETIME = M68K_EMUL_BREAK + OP_PRIMETIME;
|
||||
const uint16 M68K_EMUL_OP_MICROSECONDS = M68K_EMUL_BREAK + OP_MICROSECONDS;
|
||||
const uint16 M68K_EMUL_OP_PUT_SCRAP = M68K_EMUL_BREAK + OP_PUT_SCRAP;
|
||||
const uint16 M68K_EMUL_OP_GET_SCRAP = M68K_EMUL_BREAK + OP_GET_SCRAP;
|
||||
const uint16 M68K_EMUL_OP_DEBUG_STR = M68K_EMUL_BREAK + OP_DEBUG_STR;
|
||||
const uint16 M68K_EMUL_OP_INSTALL_DRIVERS = M68K_EMUL_BREAK + OP_INSTALL_DRIVERS;
|
||||
const uint16 M68K_EMUL_OP_NAME_REGISTRY = M68K_EMUL_BREAK + OP_NAME_REGISTRY;
|
||||
const uint16 M68K_EMUL_OP_RESET = M68K_EMUL_BREAK + OP_RESET;
|
||||
const uint16 M68K_EMUL_OP_IRQ = M68K_EMUL_BREAK + OP_IRQ;
|
||||
const uint16 M68K_EMUL_OP_SCSI_DISPATCH = M68K_EMUL_BREAK + OP_SCSI_DISPATCH;
|
||||
const uint16 M68K_EMUL_OP_SCSI_ATOMIC = M68K_EMUL_BREAK + OP_SCSI_ATOMIC;
|
||||
const uint16 M68K_EMUL_OP_NTRB_17_PATCH = M68K_EMUL_BREAK + OP_NTRB_17_PATCH;
|
||||
const uint16 M68K_EMUL_OP_NTRB_17_PATCH2 = M68K_EMUL_BREAK + OP_NTRB_17_PATCH2;
|
||||
const uint16 M68K_EMUL_OP_NTRB_17_PATCH3 = M68K_EMUL_BREAK + OP_NTRB_17_PATCH3;
|
||||
const uint16 M68K_EMUL_OP_CHECKLOAD = M68K_EMUL_BREAK + OP_CHECKLOAD;
|
||||
const uint16 M68K_EMUL_OP_EXTFS_COMM = M68K_EMUL_BREAK + OP_EXTFS_COMM;
|
||||
const uint16 M68K_EMUL_OP_EXTFS_HFS = M68K_EMUL_BREAK + OP_EXTFS_HFS;
|
||||
const uint16 M68K_EMUL_OP_IDLE_TIME = M68K_EMUL_BREAK + OP_IDLE_TIME;
|
||||
|
||||
extern void EmulOp(M68kRegisters *r, uint32 pc, int selector);
|
||||
|
||||
#endif
|
70
SheepShaver/src/include/ether.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* ether.h - SheepShaver Ethernet Device Driver
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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 ETHER_H
|
||||
#define ETHER_H
|
||||
|
||||
struct queue;
|
||||
struct msgb;
|
||||
typedef struct queue queue_t;
|
||||
typedef struct msgb mblk_t;
|
||||
|
||||
extern uint8 InitStreamModule(void *theID);
|
||||
extern void TerminateStreamModule(void);
|
||||
extern int ether_open(queue_t *rdq, void *dev, int flag, int sflag, void *creds);
|
||||
extern int ether_close(queue_t *rdq, int flag, void *creds);
|
||||
extern int ether_wput(queue_t *q, mblk_t *mp);
|
||||
extern int ether_rsrv(queue_t *q);
|
||||
|
||||
// System specific and internal functions/data
|
||||
extern void EtherInit(void);
|
||||
extern void EtherExit(void);
|
||||
|
||||
extern void EtherIRQ(void);
|
||||
|
||||
extern void AO_get_ethernet_address(uint8 *addr);
|
||||
extern void AO_enable_multicast(uint8 *addr);
|
||||
extern void AO_disable_multicast(uint8 *addr);
|
||||
extern void AO_transmit_packet(mblk_t *mp);
|
||||
|
||||
extern mblk_t *allocb(size_t size, int pri);
|
||||
extern void OTEnterInterrupt(void);
|
||||
extern void OTLeaveInterrupt(void);
|
||||
|
||||
extern void ether_packet_received(mblk_t *mp);
|
||||
|
||||
extern bool ether_driver_opened;
|
||||
|
||||
extern int32 num_wput;
|
||||
extern int32 num_error_acks;
|
||||
extern int32 num_tx_packets;
|
||||
extern int32 num_tx_raw_packets;
|
||||
extern int32 num_tx_normal_packets;
|
||||
extern int32 num_tx_buffer_full;
|
||||
extern int32 num_rx_packets;
|
||||
extern int32 num_ether_irq;
|
||||
extern int32 num_unitdata_ind;
|
||||
extern int32 num_rx_fastpath;
|
||||
extern int32 num_rx_no_mem;
|
||||
extern int32 num_rx_dropped;
|
||||
extern int32 num_rx_stream_not_ready;
|
||||
extern int32 num_rx_no_unitdata_mem;
|
||||
|
||||
#endif
|
444
SheepShaver/src/include/ether_defs.h
Normal file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
* ether_defs.h - Definitions for DLPI Ethernet Driver
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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 ETHER_DEFS_H
|
||||
#define ETHER_DEFS_H
|
||||
|
||||
|
||||
#if __BEOS__ && __POWERPC__
|
||||
#define PRAGMA_ALIGN_SUPPORTED 1
|
||||
#define PACKED__
|
||||
#else
|
||||
#define PACKED__ __attribute__ ((packed))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Macros
|
||||
*/
|
||||
|
||||
// Get pointer to the read queue, assumes 'q' is a write queue ptr
|
||||
#define RD(q) (&q[-1])
|
||||
|
||||
// Get pointer to the write queue, assumes 'q' is a read queue ptr
|
||||
#define WR(q) (&q[1])
|
||||
|
||||
#define OTCompare48BitAddresses(p1, p2) \
|
||||
(*(const uint32*)((const uint8*)(p1)) == *(const uint32*)((const uint8*)(p2)) && \
|
||||
*(const uint16*)(((const uint8*)(p1))+4) == *(const uint16*)(((const uint8*)(p2))+4) )
|
||||
|
||||
#define OTCopy48BitAddress(p1, p2) \
|
||||
(*(uint32*)((uint8*)(p2)) = *(const uint32*)((const uint8*)(p1)), \
|
||||
*(uint16*)(((uint8*)(p2))+4) = *(const uint16*)(((const uint8*)(p1))+4) )
|
||||
|
||||
#define OTClear48BitAddress(p1) \
|
||||
(*(uint32*)((uint8*)(p1)) = 0, \
|
||||
*(uint16*)(((uint8*)(p1))+4) = 0 )
|
||||
|
||||
#define OTCompare8022SNAP(p1, p2) \
|
||||
(*(const uint32*)((const uint8*)(p1)) == *(const uint32*)((const uint8*)(p2)) && \
|
||||
*(((const uint8*)(p1))+4) == *(((const uint8*)(p2))+4) )
|
||||
|
||||
#define OTCopy8022SNAP(p1, p2) \
|
||||
(*(uint32*)((uint8*)(p2)) = *(const uint32*)((const uint8*)(p1)), \
|
||||
*(((uint8*)(p2))+4) = *(((const uint8*)(p1))+4) )
|
||||
|
||||
#define OTIs48BitBroadcastAddress(p1) \
|
||||
(*(uint32*)((uint8*)(p1)) == 0xffffffff && \
|
||||
*(uint16*)(((uint8*)(p1))+4) == 0xffff )
|
||||
|
||||
#define OTSet48BitBroadcastAddress(p1) \
|
||||
(*(uint32*)((uint8*)(p1)) = 0xffffffff, \
|
||||
*(uint16*)(((uint8*)(p1))+4) = 0xffff )
|
||||
|
||||
#define OTIs48BitZeroAddress(p1) \
|
||||
(*(uint32*)((uint8*)(p1)) == 0 && \
|
||||
*(uint16*)(((uint8*)(p1))+4) == 0 )
|
||||
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
enum {
|
||||
// Address and packet lengths
|
||||
kEnetPhysicalAddressLength = 6,
|
||||
k8022SAPLength = 1,
|
||||
k8022DLSAPLength = 2,
|
||||
k8022SNAPLength = 5,
|
||||
kMaxBoundAddrLength = 6 + 2 + 5, // addr/SAP/SNAP
|
||||
kEnetAndSAPAddressLength = kEnetPhysicalAddressLength + k8022DLSAPLength,
|
||||
kEnetPacketHeaderLength = (2 * kEnetPhysicalAddressLength) + k8022DLSAPLength,
|
||||
k8022BasicHeaderLength = 3, // SSAP/DSAP/Control
|
||||
k8022SNAPHeaderLength = k8022SNAPLength + k8022BasicHeaderLength,
|
||||
kMinDIXSAP = 1501,
|
||||
kEnetTSDU = 1514,
|
||||
|
||||
// Special addresses
|
||||
kSNAPSAP = 0xaa,
|
||||
kMax8022SAP = 0xfe,
|
||||
k8022GlobalSAP = 0xff,
|
||||
kIPXSAP = 0xff,
|
||||
|
||||
// DLPI interface states
|
||||
DL_UNBOUND = 0,
|
||||
|
||||
// Message types
|
||||
M_DATA = 0,
|
||||
M_PROTO = 1,
|
||||
M_IOCTL = 14,
|
||||
M_IOCACK = 129,
|
||||
M_IOCNAK = 130,
|
||||
M_PCPROTO = 131, // priority message
|
||||
M_FLUSH = 134,
|
||||
FLUSHDATA = 0,
|
||||
FLUSHALL = 1,
|
||||
FLUSHR = 1,
|
||||
FLUSHW = 2,
|
||||
FLUSHRW = 3,
|
||||
|
||||
// DLPI primitives
|
||||
DL_INFO_REQ = 0,
|
||||
DL_BIND_REQ = 1,
|
||||
DL_PEER_BIND = 1,
|
||||
DL_HIERARCHICAL_BIND = 2,
|
||||
DL_UNBIND_REQ = 2,
|
||||
DL_INFO_ACK = 3,
|
||||
DL_BIND_ACK = 4,
|
||||
DL_ERROR_ACK = 5,
|
||||
DL_OK_ACK = 6,
|
||||
DL_UNITDATA_REQ = 7,
|
||||
DL_UNITDATA_IND = 8,
|
||||
DL_UDERROR_IND = 9,
|
||||
DL_SUBS_UNBIND_REQ = 21,
|
||||
DL_SUBS_BIND_REQ = 27,
|
||||
DL_SUBS_BIND_ACK = 28,
|
||||
DL_ENABMULTI_REQ = 29,
|
||||
DL_DISABMULTI_REQ = 30,
|
||||
DL_PHYS_ADDR_REQ = 49,
|
||||
DL_PHYS_ADDR_ACK = 50,
|
||||
DL_FACT_PHYS_ADDR = 1,
|
||||
DL_CURR_PHYS_ADDR = 2,
|
||||
|
||||
// DLPI states
|
||||
DL_IDLE = 3,
|
||||
|
||||
// DLPI error codes
|
||||
DL_BADADDR = 1, // improper address format
|
||||
DL_OUTSTATE = 3, // improper state
|
||||
DL_SYSERR = 4, // UNIX system error
|
||||
DL_UNSUPPORTED = 7, // service unsupported
|
||||
DL_BADPRIM = 9, // primitive unknown
|
||||
DL_NOTSUPPORTED = 18, // primitive not implemented
|
||||
DL_TOOMANY = 19, // limit exceeded
|
||||
|
||||
// errnos
|
||||
MAC_ENXIO = 6,
|
||||
MAC_ENOMEM = 12,
|
||||
MAC_EINVAL = 22,
|
||||
|
||||
// Various DLPI constants
|
||||
DL_CLDLS = 2, // connectionless data link service
|
||||
DL_STYLE1 = 0x500,
|
||||
DL_VERSION_2 = 2,
|
||||
DL_CSMACD = 0,
|
||||
DL_ETHER = 4,
|
||||
DL_UNKNOWN = -1,
|
||||
|
||||
// ioctl() codes
|
||||
I_OTSetFramingType = (('O' << 8) | 2),
|
||||
kOTGetFramingValue = -1,
|
||||
kOTFramingEthernet = 1,
|
||||
kOTFramingEthernetIPX = 2,
|
||||
kOTFramingEthernet8023 = 4,
|
||||
kOTFraming8022 = 8,
|
||||
I_OTSetRawMode = (('O' << 8) | 3),
|
||||
DL_IOC_HDR_INFO = (('l' << 8) | 10),
|
||||
|
||||
// Buffer allocation priority
|
||||
BPRI_LO = 1,
|
||||
BPRI_HI = 3,
|
||||
|
||||
// Misc constants
|
||||
kEnetModuleID = 7101
|
||||
};
|
||||
|
||||
enum EAddrType {
|
||||
keaStandardAddress = 0,
|
||||
keaMulticast,
|
||||
keaBroadcast,
|
||||
keaBadAddress
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Structures
|
||||
*/
|
||||
|
||||
// Data block
|
||||
struct datab {
|
||||
datab *db_freep;
|
||||
uint8 *db_base;
|
||||
uint8 *db_lim;
|
||||
uint8 db_ref;
|
||||
uint8 db_type;
|
||||
// ...
|
||||
};
|
||||
|
||||
// Message block
|
||||
struct msgb {
|
||||
msgb *b_next;
|
||||
msgb *b_prev;
|
||||
msgb *b_cont;
|
||||
uint8 *b_rptr;
|
||||
uint8 *b_wptr;
|
||||
datab *b_datap;
|
||||
// ...
|
||||
};
|
||||
|
||||
// Queue (full structure required because of size)
|
||||
struct queue {
|
||||
void *q_qinfo;
|
||||
msgb *q_first;
|
||||
msgb *q_last;
|
||||
queue *q_next;
|
||||
queue *q_link;
|
||||
void *q_ptr;
|
||||
uint32 q_count;
|
||||
int32 q_minpsz;
|
||||
int32 q_maxpsz;
|
||||
uint32 q_hiwat;
|
||||
uint32 q_lowat;
|
||||
void *q_bandp;
|
||||
uint16 q_flag;
|
||||
uint8 q_nband;
|
||||
uint8 q_pad1[1];
|
||||
void *q_osx;
|
||||
queue *q_ffcp;
|
||||
queue *q_bfcp;
|
||||
};
|
||||
typedef struct queue queue_t;
|
||||
|
||||
// M_IOCTL parameters
|
||||
struct iocblk {
|
||||
int32 ioc_cmd;
|
||||
void *ioc_cr;
|
||||
uint32 ioc_id;
|
||||
uint32 ioc_count;
|
||||
int32 ioc_error;
|
||||
int32 ioc_rval;
|
||||
int32 ioc_filler[4];
|
||||
};
|
||||
|
||||
// Priority specification
|
||||
struct dl_priority_t {
|
||||
int32 dl_min, dl_max;
|
||||
};
|
||||
|
||||
// DPLI primitives
|
||||
struct dl_info_req_t {
|
||||
uint32 dl_primitive; // DL_INFO_REQ
|
||||
};
|
||||
|
||||
struct dl_info_ack_t {
|
||||
uint32 dl_primitive; // DL_INFO_ACK
|
||||
uint32 dl_max_sdu;
|
||||
uint32 dl_min_sdu;
|
||||
uint32 dl_addr_length;
|
||||
uint32 dl_mac_type;
|
||||
uint32 dl_reserved;
|
||||
uint32 dl_current_state;
|
||||
int32 dl_sap_length;
|
||||
uint32 dl_service_mode;
|
||||
uint32 dl_qos_length;
|
||||
uint32 dl_qos_offset;
|
||||
uint32 dl_qos_range_length;
|
||||
uint32 dl_qos_range_offset;
|
||||
uint32 dl_provider_style;
|
||||
uint32 dl_addr_offset;
|
||||
uint32 dl_version;
|
||||
uint32 dl_brdcst_addr_length;
|
||||
uint32 dl_brdcst_addr_offset;
|
||||
uint32 dl_growth;
|
||||
};
|
||||
|
||||
struct dl_bind_req_t {
|
||||
uint32 dl_primitive; // DL_BIND_REQ
|
||||
uint32 dl_sap;
|
||||
uint32 dl_max_conind;
|
||||
uint16 dl_service_mode;
|
||||
uint16 dl_conn_mgmt;
|
||||
uint32 dl_xidtest_flg;
|
||||
};
|
||||
|
||||
struct dl_bind_ack_t {
|
||||
uint32 dl_primitive; // DL_BIND_ACK
|
||||
uint32 dl_sap;
|
||||
uint32 dl_addr_length;
|
||||
uint32 dl_addr_offset;
|
||||
uint32 dl_max_conind;
|
||||
uint32 dl_xidtest_flg;
|
||||
};
|
||||
|
||||
struct dl_error_ack_t {
|
||||
uint32 dl_primitive; // DL_ERROR_ACK
|
||||
uint32 dl_error_primitive;
|
||||
uint32 dl_errno;
|
||||
uint32 dl_unix_errno;
|
||||
};
|
||||
|
||||
struct dl_ok_ack_t {
|
||||
uint32 dl_primitive; // DL_ERROR_ACK
|
||||
uint32 dl_correct_primitive;
|
||||
};
|
||||
|
||||
struct dl_unitdata_req_t {
|
||||
uint32 dl_primitive; // DL_UNITDATA_REQ
|
||||
uint32 dl_dest_addr_length;
|
||||
uint32 dl_dest_addr_offset;
|
||||
dl_priority_t dl_priority;
|
||||
};
|
||||
|
||||
struct dl_unitdata_ind_t {
|
||||
uint32 dl_primitive; // DL_UNITDATA_IND
|
||||
uint32 dl_dest_addr_length;
|
||||
uint32 dl_dest_addr_offset;
|
||||
uint32 dl_src_addr_length;
|
||||
uint32 dl_src_addr_offset;
|
||||
uint32 dl_group_address;
|
||||
};
|
||||
|
||||
struct dl_uderror_ind_t {
|
||||
uint32 dl_primitive; // DL_UDERROR_IND
|
||||
uint32 dl_dest_addr_length;
|
||||
uint32 dl_dest_addr_offset;
|
||||
uint32 dl_unix_errno;
|
||||
uint32 dl_errno;
|
||||
};
|
||||
|
||||
struct dl_subs_bind_req_t {
|
||||
uint32 dl_primitive; // DL_SUBS_BIND_REQ
|
||||
uint32 dl_subs_sap_offset;
|
||||
uint32 dl_subs_sap_length;
|
||||
uint32 dl_subs_bind_class;
|
||||
};
|
||||
|
||||
struct dl_subs_bind_ack_t {
|
||||
uint32 dl_primitive; // DL_SUBS_BIND_ACK
|
||||
uint32 dl_subs_sap_offset;
|
||||
uint32 dl_subs_sap_length;
|
||||
};
|
||||
|
||||
struct dl_subs_unbind_req_t {
|
||||
uint32 dl_primitive; // DL_SUBS_UNBIND_REQ
|
||||
uint32 dl_subs_sap_offset;
|
||||
uint32 dl_subs_sap_length;
|
||||
};
|
||||
|
||||
struct dl_enabmulti_req_t {
|
||||
uint32 dl_primitive; // DL_ENABMULTI_REQ
|
||||
uint32 dl_addr_length;
|
||||
uint32 dl_addr_offset;
|
||||
};
|
||||
|
||||
struct dl_disabmulti_req_t {
|
||||
uint32 dl_primitive; // DL_DISABMULTI_REQ
|
||||
uint32 dl_addr_length;
|
||||
uint32 dl_addr_offset;
|
||||
};
|
||||
|
||||
struct dl_phys_addr_req_t {
|
||||
uint32 dl_primitive; // DL_PHYS_ADDR_REQ
|
||||
uint32 dl_addr_type;
|
||||
};
|
||||
|
||||
struct dl_phys_addr_ack_t {
|
||||
uint32 dl_primitive; // DL_PHYS_ADDR_ACK
|
||||
uint32 dl_addr_length;
|
||||
uint32 dl_addr_offset;
|
||||
};
|
||||
|
||||
// Parameters for I_OTSetRawMode/kOTSetRecvMode ioctl()
|
||||
struct dl_recv_control_t {
|
||||
uint32 dl_primitive;
|
||||
uint32 dl_flags;
|
||||
uint32 dl_truncation_length;
|
||||
};
|
||||
|
||||
union DL_primitives {
|
||||
uint32 dl_primitive;
|
||||
dl_info_req_t info_req;
|
||||
dl_info_ack_t info_ack;
|
||||
dl_bind_req_t bind_req;
|
||||
dl_bind_ack_t bind_ack;
|
||||
dl_error_ack_t error_ack;
|
||||
dl_ok_ack_t ok_ack;
|
||||
dl_unitdata_req_t unitdata_req;
|
||||
dl_unitdata_ind_t unitdata_ind;
|
||||
dl_uderror_ind_t uderror_ind;
|
||||
dl_subs_bind_req_t subs_bind_req;
|
||||
dl_subs_bind_ack_t subs_bind_ack;
|
||||
dl_subs_unbind_req_t subs_unbind_req;
|
||||
dl_enabmulti_req_t enabmulti_req;
|
||||
dl_disabmulti_req_t disabmulti_req;
|
||||
dl_phys_addr_req_t phys_addr_req;
|
||||
dl_phys_addr_ack_t phys_addr_ack;
|
||||
};
|
||||
|
||||
#ifdef PRAGMA_ALIGN_SUPPORTED
|
||||
#pragma options align=mac68k
|
||||
#endif
|
||||
|
||||
// Packet headers
|
||||
struct EnetPacketHeader {
|
||||
uint8 fDestAddr[6];
|
||||
uint8 fSourceAddr[6];
|
||||
uint16 fProto;
|
||||
} PACKED__;
|
||||
|
||||
struct T8022Header {
|
||||
uint8 fDSAP;
|
||||
uint8 fSSAP;
|
||||
uint8 fCtrl;
|
||||
} PACKED__;
|
||||
|
||||
struct T8022SNAPHeader {
|
||||
uint8 fDSAP;
|
||||
uint8 fSSAP;
|
||||
uint8 fCtrl;
|
||||
uint8 fSNAP[k8022SNAPLength];
|
||||
} PACKED__;
|
||||
|
||||
struct T8022FullPacketHeader {
|
||||
EnetPacketHeader fEnetPart;
|
||||
T8022SNAPHeader f8022Part;
|
||||
} PACKED__;
|
||||
|
||||
struct T8022AddressStruct {
|
||||
uint8 fHWAddr[6];
|
||||
uint16 fSAP;
|
||||
uint8 fSNAP[k8022SNAPLength];
|
||||
} PACKED__;
|
||||
|
||||
#ifdef PRAGMA_ALIGN_SUPPORTED
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
#endif
|
379
SheepShaver/src/include/macos_util.h
Normal file
@ -0,0 +1,379 @@
|
||||
/*
|
||||
* macos_util.h - MacOS definitions/utility functions
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 MACOS_UTIL_H
|
||||
#define MACOS_UTIL_H
|
||||
|
||||
#include "cpu_emulation.h"
|
||||
|
||||
|
||||
/*
|
||||
* General definitions
|
||||
*/
|
||||
|
||||
struct Point {
|
||||
int16 v;
|
||||
int16 h;
|
||||
};
|
||||
|
||||
struct Rect {
|
||||
int16 top;
|
||||
int16 left;
|
||||
int16 bottom;
|
||||
int16 right;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Queues
|
||||
*/
|
||||
|
||||
enum { // Queue types
|
||||
dummyType = 0,
|
||||
vType = 1,
|
||||
ioQType = 2,
|
||||
drvQType = 3,
|
||||
evType = 4,
|
||||
fsQType = 5,
|
||||
sIQType = 6,
|
||||
dtQType = 7,
|
||||
nmType = 8
|
||||
};
|
||||
|
||||
enum { // QElem struct
|
||||
qLink = 0,
|
||||
qType = 4,
|
||||
qData = 6
|
||||
};
|
||||
|
||||
enum { // QHdr struct
|
||||
qFlags = 0,
|
||||
qHead = 2,
|
||||
qTail = 6
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for Deferred Task Manager
|
||||
*/
|
||||
|
||||
enum { // DeferredTask struct
|
||||
dtFlags = 6,
|
||||
dtAddr = 8,
|
||||
dtParam = 12,
|
||||
dtReserved = 16
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for Device Manager
|
||||
*/
|
||||
|
||||
// Error codes
|
||||
enum {
|
||||
noErr = 0,
|
||||
controlErr = -17, /* I/O System Errors */
|
||||
statusErr = -18, /* I/O System Errors */
|
||||
readErr = -19, /* I/O System Errors */
|
||||
writErr = -20, /* I/O System Errors */
|
||||
badUnitErr = -21, /* I/O System Errors */
|
||||
unitEmptyErr = -22, /* I/O System Errors */
|
||||
openErr = -23, /* I/O System Errors */
|
||||
closErr = -24, /* I/O System Errors */
|
||||
abortErr = -27, /* IO call aborted by KillIO */
|
||||
notOpenErr = -28, /* Driver not open */
|
||||
dskFulErr = -34, /* disk full */
|
||||
nsvErr = -35, /* no such volume */
|
||||
ioErr = -36, /* I/O error (bummers) */
|
||||
bdNamErr = -37, /* bad name */
|
||||
fnOpnErr = -38, /* file not open */
|
||||
eofErr = -39, /* End-of-file encountered */
|
||||
posErr = -40, /* tried to position to before start of file (r/w) */
|
||||
tmfoErr = -42, /* too many files open */
|
||||
fnfErr = -43, /* file not found */
|
||||
wPrErr = -44, /* diskette is write protected. */
|
||||
fLckdErr = -45, /* file is locked */
|
||||
fBsyErr = -47, /* file busy, dir not empty */
|
||||
dupFNErr = -48, /* duplicate filename already exists */
|
||||
paramErr = -50, /* error in user parameter list */
|
||||
rfNumErr = -51, /* bad ioRefNum */
|
||||
permErr = -54, /* permission error */
|
||||
nsDrvErr = -56, /* no such driver number */
|
||||
extFSErr = -58, /* external file system */
|
||||
noDriveErr = -64, /* drive not installed */
|
||||
offLinErr = -65, /* r/w requested for an off-line drive */
|
||||
noNybErr = -66, /* couldn't find 5 nybbles in 200 tries */
|
||||
noAdrMkErr = -67, /* couldn't find valid addr mark */
|
||||
dataVerErr = -68, /* read verify compare failed */
|
||||
badCksmErr = -69, /* addr mark checksum didn't check */
|
||||
badBtSlpErr = -70, /* bad addr mark bit slip nibbles */
|
||||
noDtaMkErr = -71, /* couldn't find a data mark header */
|
||||
badDCksum = -72, /* bad data mark checksum */
|
||||
badDBtSlp = -73, /* bad data mark bit slip nibbles */
|
||||
wrUnderrun = -74, /* write underrun occurred */
|
||||
cantStepErr = -75, /* step handshake failed */
|
||||
tk0BadErr = -76, /* track 0 detect doesn't change */
|
||||
initIWMErr = -77, /* unable to initialize IWM */
|
||||
twoSideErr = -78, /* tried to read 2nd side on a 1-sided drive */
|
||||
spdAdjErr = -79, /* unable to correctly adjust disk speed */
|
||||
seekErr = -80, /* track number wrong on address mark */
|
||||
sectNFErr = -81, /* sector number never found on a track */
|
||||
fmt1Err = -82, /* can't find sector 0 after track format */
|
||||
fmt2Err = -83, /* can't get enough sync */
|
||||
verErr = -84, /* track failed to verify */
|
||||
memFullErr = -108,
|
||||
dirNFErr = -120 /* directory not found */
|
||||
};
|
||||
|
||||
// Misc constants
|
||||
enum {
|
||||
goodbye = -1, /* heap being reinitialized */
|
||||
|
||||
ioInProgress = 1, /* predefined value of ioResult while I/O is pending */
|
||||
aRdCmd = 2, /* low byte of ioTrap for Read calls */
|
||||
aWrCmd = 3, /* low byte of ioTrap for Write calls */
|
||||
asyncTrpBit = 10, /* trap word modifier */
|
||||
noQueueBit = 9, /* trap word modifier */
|
||||
|
||||
dReadEnable = 0, /* set if driver responds to read requests */
|
||||
dWritEnable = 1, /* set if driver responds to write requests */
|
||||
dCtlEnable = 2, /* set if driver responds to control requests */
|
||||
dStatEnable = 3, /* set if driver responds to status requests */
|
||||
dNeedGoodBye = 4, /* set if driver needs time for performing periodic tasks */
|
||||
dNeedTime = 5, /* set if driver needs time for performing periodic tasks */
|
||||
dNeedLock = 6, /* set if driver must be locked in memory as soon as it is opened */
|
||||
|
||||
dOpened = 5, /* driver is open */
|
||||
dRAMBased = 6, /* dCtlDriver is a handle (1) or pointer (0) */
|
||||
drvrActive = 7, /* driver is currently processing a request */
|
||||
|
||||
rdVerify = 64,
|
||||
|
||||
fsCurPerm = 0, // Whatever is currently allowed
|
||||
fsRdPerm = 1, // Exclusive read
|
||||
fsWrPerm = 2, // Exclusive write
|
||||
fsRdWrPerm = 3, // Exclusive read/write
|
||||
fsRdWrShPerm = 4, // Shared read/write
|
||||
|
||||
fsAtMark = 0, // At current mark
|
||||
fsFromStart = 1, // Set mark rel to BOF
|
||||
fsFromLEOF = 2, // Set mark rel to logical EOF
|
||||
fsFromMark = 3, // Set mark rel to current mark
|
||||
|
||||
sony = 0,
|
||||
hard20 = 1
|
||||
};
|
||||
|
||||
enum { /* Large Volume Constants */
|
||||
kWidePosOffsetBit = 8,
|
||||
kMaximumBlocksIn4GB = 0x007FFFFF
|
||||
};
|
||||
|
||||
enum { // IOParam struct
|
||||
ioTrap = 6,
|
||||
ioCmdAddr = 8,
|
||||
ioCompletion = 12,
|
||||
ioResult = 16,
|
||||
ioNamePtr = 18,
|
||||
ioVRefNum = 22,
|
||||
ioRefNum = 24,
|
||||
ioVersNum = 26,
|
||||
ioPermssn = 27,
|
||||
ioMisc = 28,
|
||||
ioBuffer = 32,
|
||||
ioReqCount = 36,
|
||||
ioActCount = 40,
|
||||
ioPosMode = 44,
|
||||
ioPosOffset = 46,
|
||||
ioWPosOffset = 46, // Wide positioning offset when ioPosMode has kWidePosOffsetBit set
|
||||
SIZEOF_IOParam = 50
|
||||
};
|
||||
|
||||
enum { // CntrlParam struct
|
||||
csCode = 26,
|
||||
csParam = 28
|
||||
};
|
||||
|
||||
enum { // DrvSts struct
|
||||
dsTrack = 0,
|
||||
dsWriteProt = 2,
|
||||
dsDiskInPlace = 3,
|
||||
dsInstalled = 4,
|
||||
dsSides = 5,
|
||||
dsQLink = 6,
|
||||
dsQType = 10,
|
||||
dsQDrive = 12,
|
||||
dsQRefNum = 14,
|
||||
dsQFSID = 16,
|
||||
dsTwoSideFmt = 18,
|
||||
dsNewIntf = 19,
|
||||
dsDiskErrs = 20,
|
||||
dsMFMDrive = 22,
|
||||
dsMFMDisk = 23,
|
||||
dsTwoMegFmt = 24
|
||||
};
|
||||
|
||||
enum { // DrvSts2 struct
|
||||
dsDriveSize = 18,
|
||||
dsDriveS1 = 20,
|
||||
dsDriveType = 22,
|
||||
dsDriveManf = 24,
|
||||
dsDriveChar = 26,
|
||||
dsDriveMisc = 28,
|
||||
SIZEOF_DrvSts = 30
|
||||
};
|
||||
|
||||
enum { // DCtlEntry struct
|
||||
dCtlDriver = 0,
|
||||
dCtlFlags = 4,
|
||||
dCtlQHdr = 6,
|
||||
dCtlPosition = 16,
|
||||
dCtlStorage = 20,
|
||||
dCtlRefNum = 24,
|
||||
dCtlCurTicks = 26,
|
||||
dCtlWindow = 30,
|
||||
dCtlDelay = 34,
|
||||
dCtlEMask = 36,
|
||||
dCtlMenu = 38,
|
||||
dCtlSlot = 40,
|
||||
dCtlSlotId = 41,
|
||||
dCtlDevBase = 42,
|
||||
dCtlOwner = 46,
|
||||
dCtlExtDev = 50,
|
||||
dCtlFillByte = 51,
|
||||
dCtlNodeID = 52
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for native Device Manager
|
||||
*/
|
||||
|
||||
// Registry EntryID
|
||||
struct RegEntryID {
|
||||
uint32 contents[4];
|
||||
};
|
||||
|
||||
// Command codes
|
||||
enum {
|
||||
kOpenCommand = 0,
|
||||
kCloseCommand = 1,
|
||||
kReadCommand = 2,
|
||||
kWriteCommand = 3,
|
||||
kControlCommand = 4,
|
||||
kStatusCommand = 5,
|
||||
kKillIOCommand = 6,
|
||||
kInitializeCommand = 7, /* init driver and device*/
|
||||
kFinalizeCommand = 8, /* shutdown driver and device*/
|
||||
kReplaceCommand = 9, /* replace an old driver*/
|
||||
kSupersededCommand = 10, /* prepare to be replaced by a new driver*/
|
||||
kSuspendCommand = 11, /* prepare driver to go to sleep*/
|
||||
kResumeCommand = 12 /* wake up sleeping driver*/
|
||||
};
|
||||
|
||||
// Command kinds
|
||||
enum {
|
||||
kSynchronousIOCommandKind = 0x00000001,
|
||||
kAsynchronousIOCommandKind = 0x00000002,
|
||||
kImmediateIOCommandKind = 0x00000004
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for Mixed Mode Manager
|
||||
*/
|
||||
|
||||
typedef uint32 ProcInfoType;
|
||||
typedef int8 ISAType;
|
||||
typedef uint16 RoutineFlagsType;
|
||||
typedef long (*ProcPtr)();
|
||||
typedef uint8 RDFlagsType;
|
||||
|
||||
struct RoutineRecord {
|
||||
ProcInfoType procInfo; /* calling conventions */
|
||||
int8 reserved1; /* Must be 0 */
|
||||
ISAType ISA; /* Instruction Set Architecture */
|
||||
RoutineFlagsType routineFlags; /* Flags for each routine */
|
||||
ProcPtr procDescriptor; /* Where is the thing weÕre calling? */
|
||||
uint32 reserved2; /* Must be 0 */
|
||||
uint32 selector; /* For dispatched routines, the selector */
|
||||
};
|
||||
|
||||
struct RoutineDescriptor {
|
||||
uint16 goMixedModeTrap; /* Our A-Trap */
|
||||
int8 version; /* Current Routine Descriptor version */
|
||||
RDFlagsType routineDescriptorFlags; /* Routine Descriptor Flags */
|
||||
uint32 reserved1; /* Unused, must be zero */
|
||||
uint8 reserved2; /* Unused, must be zero */
|
||||
uint8 selectorInfo; /* If a dispatched routine, calling convention, else 0 */
|
||||
uint16 routineCount; /* Number of routines in this RD */
|
||||
RoutineRecord routineRecords[1]; /* The individual routines */
|
||||
};
|
||||
|
||||
#define BUILD_PPC_ROUTINE_DESCRIPTOR(procInfo, procedure) \
|
||||
{ \
|
||||
0xAAFE, /* Mixed Mode A-Trap */ \
|
||||
7, /* version */ \
|
||||
0, /* RD Flags - not dispatched */ \
|
||||
0, /* reserved 1 */ \
|
||||
0, /* reserved 2 */ \
|
||||
0, /* selector info */ \
|
||||
0, /* number of routines */ \
|
||||
{ /* It's an array */ \
|
||||
{ /* It's a struct */ \
|
||||
(procInfo), /* the ProcInfo */ \
|
||||
0, /* reserved */ \
|
||||
1, /* ISA and RTA */ \
|
||||
0 | /* Flags - it's absolute addr */\
|
||||
0 | /* It's prepared */ \
|
||||
4, /* Always use native ISA */ \
|
||||
(ProcPtr)(procedure), /* the procedure */ \
|
||||
0, /* reserved */ \
|
||||
0 /* Not dispatched */ \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
// Functions
|
||||
extern void MacOSUtilReset(void);
|
||||
extern void Enqueue(uint32 elem, uint32 list); // Enqueue QElem to list
|
||||
extern int FindFreeDriveNumber(int num); // Find first free drive number, starting at "num"
|
||||
extern void MountVolume(void *fh); // Mount volume with given file handle (see sys.h)
|
||||
extern void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size); // Calculate disk image file layout given file size and first 256 data bytes
|
||||
extern void *FindLibSymbol(char *lib, char *sym); // Find symbol in shared library
|
||||
extern void InitCallUniversalProc(void); // Init CallUniversalProc()
|
||||
extern long CallUniversalProc(void *upp, uint32 info); // CallUniversalProc()
|
||||
extern uint32 TimeToMacTime(time_t t); // Convert time_t value to MacOS time
|
||||
|
||||
// Construct four-character-code from string
|
||||
#define FOURCC(a,b,c,d) (((uint32)(a) << 24) | ((uint32)(b) << 16) | ((uint32)(c) << 8) | (uint32)(d))
|
||||
|
||||
// Emulator identification codes (4 and 2 characters)
|
||||
const uint32 EMULATOR_ID_4 = 0x62616168; // 'baah'
|
||||
const uint16 EMULATOR_ID_2 = 0x6261; // 'ba'
|
||||
|
||||
// Test if basic MacOS initializations (of the ROM) are done
|
||||
static inline bool HasMacStarted(void)
|
||||
{
|
||||
return ReadMacInt32(0xcfc) == FOURCC('W','L','S','C'); // Mac warm start flag
|
||||
}
|
||||
|
||||
#endif
|
76
SheepShaver/src/include/main.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* main.h - Emulation core
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
// Global variables
|
||||
extern void *TOC; // TOC pointer
|
||||
extern uint32 KernelDataAddr; // Address of Kernel Data
|
||||
extern uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM
|
||||
extern uint32 PVR; // Theoretical PVR
|
||||
extern int64 CPUClockSpeed; // Processor clock speed (Hz)
|
||||
extern int64 BusClockSpeed; // Bus clock speed (Hz)
|
||||
|
||||
#ifdef __BEOS__
|
||||
extern system_info SysInfo; // System information
|
||||
#endif
|
||||
|
||||
// 68k register structure (for Execute68k())
|
||||
struct M68kRegisters {
|
||||
uint32 d[8];
|
||||
uint32 a[8];
|
||||
};
|
||||
|
||||
|
||||
// Functions
|
||||
extern void Dump68kRegs(M68kRegisters *r); // Dump 68k registers
|
||||
extern void MakeExecutable(int dummy, void *start, uint32 length); // Make code executable
|
||||
extern void PatchAfterStartup(void); // Patches after system startup
|
||||
extern void QuitEmulator(void); // Quit emulator (must only be called from main thread)
|
||||
extern void ErrorAlert(const char *text); // Display error alert
|
||||
extern void WarningAlert(const char *text); // Display warning alert
|
||||
extern bool ChoiceAlert(const char *text, const char *pos, const char *neg); // Display choice alert
|
||||
|
||||
// Mutexes (non-recursive)
|
||||
struct B2_mutex;
|
||||
extern B2_mutex *B2_create_mutex(void);
|
||||
extern void B2_lock_mutex(B2_mutex *mutex);
|
||||
extern void B2_unlock_mutex(B2_mutex *mutex);
|
||||
extern void B2_delete_mutex(B2_mutex *mutex);
|
||||
|
||||
// Interrupt flags
|
||||
enum {
|
||||
INTFLAG_VIA = 1, // 60.15Hz VBL
|
||||
INTFLAG_SERIAL = 2, // Serial driver
|
||||
INTFLAG_ETHER = 4, // Ethernet driver
|
||||
INTFLAG_AUDIO = 16, // Audio block read
|
||||
INTFLAG_TIMER = 32, // Time Manager
|
||||
INTFLAG_ADB = 64 // ADB
|
||||
};
|
||||
|
||||
extern volatile uint32 InterruptFlags; // Currently pending interrupts
|
||||
extern void SetInterruptFlag(uint32);
|
||||
extern void ClearInterruptFlag(uint32);
|
||||
extern void TriggerInterrupt(void); // Trigger SIGUSR1 interrupt in emulator thread
|
||||
extern void DisableInterrupt(void); // Disable SIGUSR1 interrupt (can be nested)
|
||||
extern void EnableInterrupt(void); // Enable SIGUSR1 interrupt (can be nested)
|
||||
|
||||
#endif
|
26
SheepShaver/src/include/name_registry.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* name_registry.h - Name Registry handling
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 NAME_REGISTRY_H
|
||||
#define NAME_REGISTRY_H
|
||||
|
||||
extern void PatchNameRegistry(void);
|
||||
|
||||
#endif
|
30
SheepShaver/src/include/prefs_editor.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* prefs_editor.h - Preferences editor
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 PREFS_EDITOR_H
|
||||
#define PREFS_EDITOR_H
|
||||
|
||||
#ifdef __BEOS__
|
||||
extern void PrefsEditor(uint32 msg);
|
||||
#else
|
||||
extern bool PrefsEditor(void);
|
||||
#endif
|
||||
|
||||
#endif
|
40
SheepShaver/src/include/rom_patches.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* rom_patches.h - ROM patches
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 ROM_PATCHES_H
|
||||
#define ROM_PATCHES_H
|
||||
|
||||
// ROM types
|
||||
enum {
|
||||
ROMTYPE_TNT,
|
||||
ROMTYPE_ALCHEMY,
|
||||
ROMTYPE_ZANZIBAR,
|
||||
ROMTYPE_GAZELLE,
|
||||
ROMTYPE_NEWWORLD
|
||||
};
|
||||
extern int ROMType;
|
||||
|
||||
extern bool PatchROM(void);
|
||||
extern void InstallDrivers(void);
|
||||
|
||||
extern void AddSifter(uint32 type, int16 id);
|
||||
extern bool FindSifter(uint32 type, int16 id);
|
||||
|
||||
#endif
|
27
SheepShaver/src/include/rsrc_patches.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* rsrc_patches.h - Resource patches
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 RSRC_PATCHES_H
|
||||
#define RSRC_PATCHES_H
|
||||
|
||||
extern void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size);
|
||||
extern void PatchNativeResourceManager(void);
|
||||
|
||||
#endif
|
161
SheepShaver/src/include/user_strings.h
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* user_strings.h - Localizable strings
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 USER_STRINGS_H
|
||||
#define USER_STRINGS_H
|
||||
|
||||
// Common string numbers
|
||||
enum {
|
||||
// General messages
|
||||
STR_ABOUT_TEXT1 = 0,
|
||||
STR_ABOUT_TEXT2,
|
||||
STR_READING_ROM_FILE,
|
||||
STR_SHELL_ERROR_PREFIX,
|
||||
STR_GUI_ERROR_PREFIX,
|
||||
STR_ERROR_ALERT_TITLE,
|
||||
STR_SHELL_WARNING_PREFIX,
|
||||
STR_GUI_WARNING_PREFIX,
|
||||
STR_WARNING_ALERT_TITLE,
|
||||
STR_NOTICE_ALERT_TITLE,
|
||||
STR_ABOUT_TITLE,
|
||||
STR_OK_BUTTON,
|
||||
STR_START_BUTTON,
|
||||
STR_QUIT_BUTTON,
|
||||
STR_CANCEL_BUTTON,
|
||||
STR_IGNORE_BUTTON,
|
||||
|
||||
// Error messages
|
||||
STR_NOT_ENOUGH_MEMORY_ERR = 1000,
|
||||
STR_NO_KERNEL_DATA_ERR,
|
||||
STR_NO_RAM_AREA_ERR,
|
||||
STR_NO_ROM_FILE_ERR,
|
||||
STR_RAM_HIGHER_THAN_ROM_ERR,
|
||||
STR_ROM_FILE_READ_ERR,
|
||||
STR_ROM_SIZE_ERR,
|
||||
STR_UNSUPPORTED_ROM_TYPE_ERR,
|
||||
STR_POWER_INSTRUCTION_ERR,
|
||||
STR_MEM_ACCESS_ERR,
|
||||
STR_MEM_ACCESS_READ,
|
||||
STR_MEM_ACCESS_WRITE,
|
||||
STR_UNKNOWN_SEGV_ERR,
|
||||
STR_NO_NAME_REGISTRY_ERR,
|
||||
STR_FULL_SCREEN_ERR,
|
||||
STR_SCSI_BUFFER_ERR,
|
||||
STR_SCSI_SG_FULL_ERR,
|
||||
|
||||
// Warning messages
|
||||
STR_SMALL_RAM_WARN = 2000,
|
||||
STR_VOLUME_IS_MOUNTED_WARN,
|
||||
STR_CANNOT_UNMOUNT_WARN,
|
||||
STR_CREATE_VOLUME_WARN,
|
||||
|
||||
// Preferences window
|
||||
STR_PREFS_TITLE = 3000,
|
||||
STR_PREFS_MENU = 3020,
|
||||
STR_PREFS_ITEM_ABOUT,
|
||||
STR_PREFS_ITEM_START,
|
||||
STR_PREFS_ITEM_ZAP_PRAM,
|
||||
STR_PREFS_ITEM_QUIT,
|
||||
|
||||
// Volumes pane
|
||||
STR_VOLUMES_PANE_TITLE = 3200,
|
||||
STR_ADD_VOLUME_BUTTON,
|
||||
STR_CREATE_VOLUME_BUTTON,
|
||||
STR_REMOVE_VOLUME_BUTTON,
|
||||
STR_ADD_VOLUME_PANEL_BUTTON,
|
||||
STR_CREATE_VOLUME_PANEL_BUTTON,
|
||||
STR_BOOTDRIVER_CTRL,
|
||||
STR_BOOT_ANY_LAB,
|
||||
STR_BOOT_CDROM_LAB,
|
||||
STR_NOCDROM_CTRL,
|
||||
STR_EXTFS_CTRL,
|
||||
STR_ADD_VOLUME_TITLE,
|
||||
STR_CREATE_VOLUME_TITLE,
|
||||
STR_HARDFILE_SIZE_CTRL,
|
||||
|
||||
// Graphics pane
|
||||
STR_GRAPHICS_SOUND_PANE_TITLE = 3300,
|
||||
STR_FRAMESKIP_CTRL,
|
||||
STR_REF_5HZ_LAB,
|
||||
STR_REF_7_5HZ_LAB,
|
||||
STR_REF_10HZ_LAB,
|
||||
STR_REF_15HZ_LAB,
|
||||
STR_REF_30HZ_LAB,
|
||||
STR_REF_60HZ_LAB,
|
||||
STR_GFXACCEL_CTRL,
|
||||
STR_8_BIT_CTRL,
|
||||
STR_16_BIT_CTRL,
|
||||
STR_32_BIT_CTRL,
|
||||
STR_W_640x480_CTRL,
|
||||
STR_W_800x600_CTRL,
|
||||
STR_640x480_CTRL,
|
||||
STR_800x600_CTRL,
|
||||
STR_1024x768_CTRL,
|
||||
STR_1152x900_CTRL,
|
||||
STR_1280x1024_CTRL,
|
||||
STR_1600x1200_CTRL,
|
||||
STR_VIDEO_MODE_CTRL,
|
||||
STR_FULLSCREEN_CTRL,
|
||||
STR_NOSOUND_CTRL,
|
||||
|
||||
// Serial/Network pane
|
||||
STR_SERIAL_NETWORK_PANE_TITLE = 3400,
|
||||
STR_SERPORTA_CTRL,
|
||||
STR_SERPORTB_CTRL,
|
||||
STR_NONET_CTRL,
|
||||
STR_ETHERNET_IF_CTRL,
|
||||
|
||||
// Memory/Misc pane
|
||||
STR_MEMORY_MISC_PANE_TITLE = 3500,
|
||||
STR_RAMSIZE_SLIDER,
|
||||
STR_RAMSIZE_FMT,
|
||||
STR_IGNORESEGV_CTRL,
|
||||
STR_IDLEWAIT_CTRL,
|
||||
STR_ROM_FILE_CTRL,
|
||||
|
||||
// Mac window
|
||||
STR_WINDOW_TITLE = 4000,
|
||||
STR_WINDOW_TITLE_FROZEN,
|
||||
STR_WINDOW_MENU = 4050,
|
||||
STR_WINDOW_ITEM_ABOUT,
|
||||
STR_WINDOW_ITEM_REFRESH,
|
||||
STR_WINDOW_ITEM_MOUNT,
|
||||
|
||||
// Audio
|
||||
STR_SOUND_IN_NAME = 6000,
|
||||
|
||||
// External file system
|
||||
STR_EXTFS_NAME = 7000,
|
||||
STR_EXTFS_VOLUME_NAME
|
||||
};
|
||||
|
||||
// Common and platform-specific string definitions
|
||||
struct user_string_def {
|
||||
int num;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
extern user_string_def common_strings[];
|
||||
extern user_string_def platform_strings[];
|
||||
|
||||
// Fetch pointer to string, given the string number
|
||||
extern const char *GetString(int num);
|
||||
|
||||
#endif
|
27
SheepShaver/src/include/version.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* version.h - Version information
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
const int VERSION_MAJOR = 2;
|
||||
const int VERSION_MINOR = 2;
|
||||
|
||||
#endif
|
113
SheepShaver/src/include/video.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* video.h - Video/graphics emulation
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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 VIDEO_H
|
||||
#define VIDEO_H
|
||||
|
||||
extern bool VideoActivated(void);
|
||||
extern bool VideoSnapshot(int xsize, int ysize, uint8 *p);
|
||||
|
||||
extern int16 VideoDoDriverIO(void *spaceID, void *commandID, void *commandContents, uint32 commandCode, uint32 commandKind);
|
||||
|
||||
// System specific and internal functions/data
|
||||
struct VideoInfo {
|
||||
int viType; // Screen/Window
|
||||
uint32 viRowBytes; // width of each row in memory
|
||||
uint16 viXsize,viYsize; // Window
|
||||
uint32 viAppleMode; // Screen Color Depth
|
||||
uint32 viAppleID; // Screen DisplayID
|
||||
};
|
||||
|
||||
extern struct VideoInfo VModes[]; // List of available video modes
|
||||
|
||||
enum { // viAppleMode
|
||||
APPLE_1_BIT = 0x80,
|
||||
APPLE_2_BIT,
|
||||
APPLE_4_BIT,
|
||||
APPLE_8_BIT,
|
||||
APPLE_16_BIT,
|
||||
APPLE_32_BIT
|
||||
};
|
||||
|
||||
enum { // viAppleID
|
||||
APPLE_640x480 = 0x81,
|
||||
APPLE_W_640x480,
|
||||
APPLE_800x600,
|
||||
APPLE_W_800x600,
|
||||
APPLE_1024x768,
|
||||
APPLE_1152x900,
|
||||
APPLE_1280x1024,
|
||||
APPLE_1600x1200,
|
||||
APPLE_ID_MIN = APPLE_640x480,
|
||||
APPLE_ID_MAX = APPLE_1600x1200
|
||||
};
|
||||
|
||||
enum { // Display type
|
||||
DIS_INVALID,
|
||||
DIS_SCREEN,
|
||||
DIS_WINDOW
|
||||
};
|
||||
|
||||
extern bool video_activated; // Flag: video display activated, mouse and keyboard data valid
|
||||
extern uint32 screen_base; // Frame buffer base address
|
||||
extern int cur_mode; // Number of current video mode (index in VModes array)
|
||||
extern int display_type; // Current display type (see above)
|
||||
extern rgb_color mac_pal[256];
|
||||
extern uint8 remap_mac_be[256];
|
||||
extern uint8 MacCursor[68];
|
||||
|
||||
struct GammaTbl;
|
||||
|
||||
struct VidLocals{
|
||||
uint16 saveMode;
|
||||
uint32 saveData;
|
||||
uint16 savePage;
|
||||
uint32 saveBaseAddr;
|
||||
GammaTbl *gammaTable; // Current gamma table
|
||||
uint32 maxGammaTableSize; // Biggest gamma table allocated
|
||||
uint32 saveVidParms;
|
||||
bool luminanceMapping; // Luminance mapping on/off
|
||||
int32 cursorX; // Hardware cursor state. Unused, but must be remembered
|
||||
int32 cursorY;
|
||||
uint32 cursorVisible;
|
||||
uint32 cursorSet;
|
||||
uint32 vslServiceID; // VSL interrupt service ID
|
||||
bool interruptsEnabled; // VBL interrupts on/off
|
||||
uint32 regEntryID[4];
|
||||
};
|
||||
|
||||
extern VidLocals *private_data; // Pointer to driver local variables (there is only one display, so this is ok)
|
||||
|
||||
extern bool VideoInit(void);
|
||||
extern void VideoExit(void);
|
||||
extern void VideoVBL(void);
|
||||
extern void VideoInstallAccel(void);
|
||||
extern void VideoQuitFullScreen(void);
|
||||
|
||||
extern void video_set_palette(void);
|
||||
extern void video_set_cursor(void);
|
||||
extern int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr);
|
||||
|
||||
extern int16 VSLDoInterruptService(uint32 arg1);
|
||||
extern void NQDMisc(uint32 arg1, void *arg2);
|
||||
|
||||
extern bool keyfile_valid;
|
||||
|
||||
#endif
|
381
SheepShaver/src/include/video_defs.h
Normal file
@ -0,0 +1,381 @@
|
||||
/*
|
||||
* video_defs.h - MacOS types and structures for video
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer
|
||||
*
|
||||
* 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 VIDEO_DEFS_H
|
||||
#define VIDEO_DEFS_H
|
||||
|
||||
#include "macos_util.h"
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for Display Manager
|
||||
*/
|
||||
|
||||
/* csMode values describing pixel depth in VDSwitchInfo */
|
||||
enum {
|
||||
firstVidMode=128, // first depth mode, representing lowest supported
|
||||
// pixel depth
|
||||
secondVidMode, thirdVidMode, fourthVidMode, fifthVidMode, sixthVidMode
|
||||
// following modes represent pixel depths in ascending
|
||||
// order
|
||||
};
|
||||
|
||||
/* csDisplayType values in VDDisplayConnectInfoRec */
|
||||
enum {
|
||||
kUnknownConnect=1, // reserved
|
||||
kPanelTFTConnect, // fixed-in-place LCS (TFT, aka "active matrix") panels
|
||||
kFixedModeCRTConnect, // very limited displays
|
||||
kMultiModeCRT1Connect, // 12" optional, 13" default, 16" required
|
||||
kMultiModeCRT2Connect, // 12" optional, 13" req., 16" def., 19" req.
|
||||
kMultiModeCRT3Connect, // 12" optional, 13" req., 16" req., 19" req.,21" def.
|
||||
kMultiModeCRT4Connect, // expansion to large multimode (not yet implemented)
|
||||
kModelessConnect, // expansion to modeless model (not yet implemented)
|
||||
kFullPageConnect, // 640x818 (to get 8bpp in 512K case) and
|
||||
// 640x870 (nothing else supported)
|
||||
kVGAConnect, // 640x480 VGA default -- nothing else req.
|
||||
kNTSCConnect, // NTSC ST(default), FF, STconv, FFconv
|
||||
kPALConnect, // PAL ST(default), FF, STconv, FFconv
|
||||
kHRConnect, // 640x400 (to get 8bpp in 256K case) and
|
||||
// 640x480 (nothing else supported)
|
||||
kPanelFSTNConnect // fixed-in-place LCD FSTN (aka "supertwist") panels
|
||||
};
|
||||
|
||||
/* csConnectFlags values in VDDisplayConnectInfoRec */
|
||||
enum {
|
||||
kAllModesValid=0, // all display modes not deleted by PrimaryInit code
|
||||
// are optional
|
||||
kAllModesSafe, // all display modes not deleted by PrimaryInit code
|
||||
// are required; is you set this bit, set the
|
||||
// kAllModesValid bit, too
|
||||
kHasDirectConnect=3, // for future expansions, setting this bit means that
|
||||
// your driver can talk directly to the display
|
||||
// (e.g. there is a serial data link via sense lines)
|
||||
kIsMonoDev, // this display does not support color
|
||||
kUncertainConnect // there may not be a display; Monitors control panel
|
||||
// makes the user confirm some operations--like moving
|
||||
// the menu bar-- when this bit is set
|
||||
};
|
||||
|
||||
/* csTimingFormat value in VDTimingInfoRec */
|
||||
#define kDeclROMtables FOURCC('d','e','c','l') // use information in this record instead of looking
|
||||
// in the decl. ROM for timing info; used for patching
|
||||
// existing card without updating declaration ROM
|
||||
|
||||
/* csTimingData values in VDTimingInfoRec */
|
||||
enum {
|
||||
timingUnknown = 0, // unknown timing
|
||||
timingApple_512x384_60hz = 130, /* 512x384 (60 Hz) Rubik timing. */
|
||||
timingApple_560x384_60hz = 135, /* 560x384 (60 Hz) Rubik-560 timing. */
|
||||
timingApple_640x480_67hz = 140, /* 640x480 (67 Hz) HR timing. */
|
||||
timingApple_640x400_67hz = 145, /* 640x400 (67 Hz) HR-400 timing. */
|
||||
timingVESA_640x480_60hz = 150, /* 640x480 (60 Hz) VGA timing. */
|
||||
timingVESA_640x480_72hz = 152, /* 640x480 (72 Hz) VGA timing. */
|
||||
timingVESA_640x480_75hz = 154, /* 640x480 (75 Hz) VGA timing. */
|
||||
timingVESA_640x480_85hz = 158, /* 640x480 (85 Hz) VGA timing. */
|
||||
timingGTF_640x480_120hz = 159, /* 640x480 (120 Hz) VESA Generalized Timing Formula */
|
||||
timingApple_640x870_75hz = 160, /* 640x870 (75 Hz) FPD timing.*/
|
||||
timingApple_640x818_75hz = 165, /* 640x818 (75 Hz) FPD-818 timing.*/
|
||||
timingApple_832x624_75hz = 170, /* 832x624 (75 Hz) GoldFish timing.*/
|
||||
timingVESA_800x600_56hz = 180, /* 800x600 (56 Hz) SVGA timing. */
|
||||
timingVESA_800x600_60hz = 182, /* 800x600 (60 Hz) SVGA timing. */
|
||||
timingVESA_800x600_72hz = 184, /* 800x600 (72 Hz) SVGA timing. */
|
||||
timingVESA_800x600_75hz = 186, /* 800x600 (75 Hz) SVGA timing. */
|
||||
timingVESA_800x600_85hz = 188, /* 800x600 (85 Hz) SVGA timing. */
|
||||
timingVESA_1024x768_60hz = 190, /* 1024x768 (60 Hz) VESA 1K-60Hz timing. */
|
||||
timingVESA_1024x768_70hz = 200, /* 1024x768 (70 Hz) VESA 1K-70Hz timing. */
|
||||
timingVESA_1024x768_75hz = 204, /* 1024x768 (75 Hz) VESA 1K-75Hz timing (very similar to timingApple_1024x768_75hz). */
|
||||
timingVESA_1024x768_85hz = 208, /* 1024x768 (85 Hz) VESA timing. */
|
||||
timingApple_1024x768_75hz = 210, /* 1024x768 (75 Hz) Apple 19" RGB. */
|
||||
timingApple_1152x870_75hz = 220, /* 1152x870 (75 Hz) Apple 21" RGB. */
|
||||
timingVESA_1280x960_75hz = 250, /* 1280x960 (75 Hz) */
|
||||
timingVESA_1280x960_60hz = 252, /* 1280x960 (60 Hz) */
|
||||
timingVESA_1280x960_85hz = 254, /* 1280x960 (85 Hz) */
|
||||
timingVESA_1280x1024_60hz = 260, /* 1280x1024 (60 Hz) */
|
||||
timingVESA_1280x1024_75hz = 262, /* 1280x1024 (75 Hz) */
|
||||
timingVESA_1280x1024_85hz = 268, /* 1280x1024 (85 Hz) */
|
||||
timingVESA_1600x1200_60hz = 280, /* 1600x1200 (60 Hz) VESA proposed timing. */
|
||||
timingVESA_1600x1200_65hz = 282, /* 1600x1200 (65 Hz) VESA proposed timing. */
|
||||
timingVESA_1600x1200_70hz = 284, /* 1600x1200 (70 Hz) VESA proposed timing. */
|
||||
timingVESA_1600x1200_75hz = 286, /* 1600x1200 (75 Hz) VESA proposed timing. */
|
||||
timingVESA_1600x1200_80hz = 288, /* 1600x1200 (80 Hz) VESA proposed timing (pixel clock is 216 Mhz dot clock). */
|
||||
timingSMPTE240M_60hz = 400, /* 60Hz V, 33.75KHz H, interlaced timing, 16:9 aspect, typical resolution of 1920x1035. */
|
||||
timingFilmRate_48hz = 410 /* 48Hz V, 25.20KHz H, non-interlaced timing, typical resolution of 640x480. */
|
||||
};
|
||||
|
||||
/* csTimingFlags values in VDTimingInfoRec */
|
||||
enum {
|
||||
kModeValid=0, // this display mode is optional
|
||||
kModeSafe, // this display mode is required; if you set this
|
||||
// bit, you should also set the kModeValid bit
|
||||
kModeDefault, // this display mode is the default for the attached
|
||||
// display; if you set this bit, you should also set
|
||||
// the kModeSafe and kModeValid bits
|
||||
kShowModeNow, // show this mode in Monitors control panel; useful
|
||||
// for SVGA modes
|
||||
kModeNotResize,
|
||||
kModeRequiresPan
|
||||
};
|
||||
|
||||
/* code for Display Manager control request */
|
||||
enum {
|
||||
cscReset=0,
|
||||
cscKillIO,
|
||||
cscSetMode,
|
||||
cscSetEntries,
|
||||
cscSetGamma,
|
||||
cscGrayPage,
|
||||
cscGrayScreen=5,
|
||||
cscSetGray,
|
||||
cscSetInterrupt,
|
||||
cscDirectSetEntries,
|
||||
cscSetDefaultMode,
|
||||
cscSwitchMode, // switch to another display mode
|
||||
cscSetSync,
|
||||
cscSavePreferredConfiguration=16,
|
||||
cscSetHardwareCursor=22,
|
||||
cscDrawHardwareCursor,
|
||||
cscSetConvolution,
|
||||
cscSetPowerState,
|
||||
cscPrivateControlCall, // Takes a VDPrivateSelectorDataRec
|
||||
cscSetMultiConnect, // From a GDI point of view, this call should be implemented completely in the HAL and not at all in the core.
|
||||
cscSetClutBehavior, // Takes a VDClutBehavior
|
||||
cscUnusedCall=127 // This call used to expend the scrn resource. Its imbedded data contains more control info
|
||||
};
|
||||
|
||||
/* Constants for the GetNextResolution call */
|
||||
|
||||
enum {
|
||||
kDisplayModeIDCurrent = 0x00, /* Reference the Current DisplayModeID */
|
||||
kDisplayModeIDInvalid = (long)0xFFFFFFFF, /* A bogus DisplayModeID in all cases */
|
||||
kDisplayModeIDFindFirstResolution = (long)0xFFFFFFFE, /* Used in cscGetNextResolution to reset iterator */
|
||||
kDisplayModeIDNoMoreResolutions = (long)0xFFFFFFFD /* Used in cscGetNextResolution to indicate End Of List */
|
||||
};
|
||||
|
||||
/* codes for Display Manager status requests */
|
||||
enum {
|
||||
cscGetMode=2,
|
||||
cscGetEntries,
|
||||
cscGetPageCnt,
|
||||
cscGetPages=4, // This is what C&D 2 calls it.
|
||||
cscGetPageBase,
|
||||
cscGetBaseAddr=5, // This is what C&D 2 calls it.
|
||||
cscGetGray,
|
||||
cscGetInterrupt,
|
||||
cscGetGamma,
|
||||
cscGetDefaultMode,
|
||||
cscGetCurMode, // save the current display mode
|
||||
cscGetSync,
|
||||
cscGetConnection, // return information about display capabilities of
|
||||
// connected display
|
||||
cscGetModeTiming, // return scan timings data for a display mode
|
||||
cscGetModeBaseAddress, // Return base address information about a particular mode
|
||||
cscGetScanProc, // QuickTime scan chasing routine
|
||||
cscGetPreferredConfiguration,
|
||||
cscGetNextResolution,
|
||||
cscGetVideoParameters,
|
||||
cscGetGammaInfoList =20,
|
||||
cscRetrieveGammaTable,
|
||||
cscSupportsHardwareCursor,
|
||||
cscGetHardwareCursorDrawState,
|
||||
cscGetConvolution,
|
||||
cscGetPowerState,
|
||||
cscPrivateStatusCall, // Takes a VDPrivateSelectorDataRec
|
||||
cscGetDDCBlock, // Takes a VDDDCBlockRec
|
||||
cscGetMultiConnect, // From a GDI point of view, this call should be implemented completely in the HAL and not at all in the core.
|
||||
cscGetClutBehavior // Takes a VDClutBehavior
|
||||
};
|
||||
|
||||
enum { // VDSwitchInfo struct
|
||||
csMode = 0,
|
||||
csData = 2,
|
||||
csPage = 6,
|
||||
csBaseAddr = 8
|
||||
};
|
||||
|
||||
enum { // VDSetEntry struct
|
||||
csTable = 0, // Pointer to ColorSpec[]
|
||||
csStart = 4,
|
||||
csCount = 6
|
||||
};
|
||||
|
||||
struct ColorSpec {
|
||||
uint16 value;
|
||||
uint16 red;
|
||||
uint16 green;
|
||||
uint16 blue;
|
||||
};
|
||||
|
||||
enum { // VDVideoParametersInfo struct
|
||||
csDisplayModeID = 0,
|
||||
csDepthMode = 4,
|
||||
csVPBlockPtr = 6,
|
||||
csPageCount = 10,
|
||||
csDeviceType = 14
|
||||
};
|
||||
|
||||
enum { // VPBlock struct
|
||||
vpBaseOffset = 0,
|
||||
vpRowBytes = 4,
|
||||
vpBounds = 6,
|
||||
vpVersion = 14,
|
||||
vpPackType = 16,
|
||||
vpPackSize = 18,
|
||||
vpHRes = 22,
|
||||
vpVRes = 26,
|
||||
vpPixelType = 30,
|
||||
vpPixelSize = 32,
|
||||
vpCmpCount = 34,
|
||||
vpCmpSize = 36,
|
||||
vpPlaneBytes = 38
|
||||
};
|
||||
|
||||
enum { // VDDisplayConnectInfo struct
|
||||
csDisplayType = 0,
|
||||
csConnectTaggedType = 2,
|
||||
csConnectTaggedData = 3,
|
||||
csConnectFlags = 4,
|
||||
csDisplayComponent = 8,
|
||||
csConnectReserved = 12
|
||||
};
|
||||
|
||||
enum { // VDTimingInfo struct
|
||||
csTimingMode = 0,
|
||||
csTimingReserved = 4,
|
||||
csTimingFormat = 8,
|
||||
csTimingData = 12,
|
||||
csTimingFlags = 16
|
||||
};
|
||||
|
||||
enum { // VDResolutionInfo struct
|
||||
csPreviousDisplayModeID = 0,
|
||||
csRIDisplayModeID = 4,
|
||||
csHorizontalPixels = 8,
|
||||
csVerticalLines = 12,
|
||||
csRefreshRate = 16,
|
||||
csMaxDepthMode = 20,
|
||||
csResolutionFlags = 22
|
||||
};
|
||||
|
||||
enum { // VDDrawHardwareCursor/VDHardwareCursorDrawState struct
|
||||
csCursorX = 0,
|
||||
csCursorY = 4,
|
||||
csCursorVisible = 8,
|
||||
csCursorSet = 12
|
||||
};
|
||||
|
||||
struct GammaTbl {
|
||||
uint16 gVersion;
|
||||
uint16 gType;
|
||||
uint16 gFormulaSize;
|
||||
uint16 gChanCnt;
|
||||
uint16 gDataCnt;
|
||||
uint16 gDataWidth;
|
||||
uint16 gFormulaData[1];
|
||||
};
|
||||
|
||||
enum {
|
||||
kCursorImageMajorVersion = 0x0001,
|
||||
kCursorImageMinorVersion = 0x0000
|
||||
};
|
||||
|
||||
enum { // CursorImage struct
|
||||
ciMajorVersion = 0,
|
||||
ciMinorVersion = 2,
|
||||
ciCursorPixMap = 4, // Handle to PixMap
|
||||
ciCursorBitMask = 8 // Handle to BitMap
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Structures for graphics acceleration
|
||||
*/
|
||||
|
||||
typedef void *CTabHandle;
|
||||
|
||||
// Parameter block passed to acceleration hooks
|
||||
struct accl_params {
|
||||
uint32 unknown0[3];
|
||||
|
||||
uint32 transfer_mode;
|
||||
uint32 pen_mode;
|
||||
|
||||
uint32 unknown1[2];
|
||||
|
||||
uint32 fore_pen;
|
||||
uint32 back_pen;
|
||||
|
||||
uint32 unknown2[3];
|
||||
|
||||
uint32 src_base_addr;
|
||||
uint32 src_row_bytes;
|
||||
int16 src_bounds[4];
|
||||
uint32 src_unknown1;
|
||||
uint32 src_pixel_type;
|
||||
uint32 src_pixel_size;
|
||||
uint32 src_cmp_count;
|
||||
uint32 src_cmp_size;
|
||||
CTabHandle src_pm_table;
|
||||
uint32 src_unknown2;
|
||||
uint32 src_unknown3;
|
||||
uint32 src_unknown4;
|
||||
|
||||
uint32 dest_base_addr;
|
||||
uint32 dest_row_bytes;
|
||||
int16 dest_bounds[4];
|
||||
uint32 dest_unknown1;
|
||||
uint32 dest_pixel_type;
|
||||
uint32 dest_pixel_size;
|
||||
uint32 dest_cmp_count;
|
||||
uint32 dest_cmp_size;
|
||||
CTabHandle dest_pm_table;
|
||||
uint32 dest_unknown2;
|
||||
uint32 dest_unknown3;
|
||||
uint32 dest_unknown4;
|
||||
|
||||
uint32 unknown3[13];
|
||||
|
||||
int16 src_rect[4];
|
||||
int16 dest_rect[4];
|
||||
|
||||
uint32 unknown4[38];
|
||||
|
||||
void (*draw_proc)(accl_params *);
|
||||
// Argument for accl_sync_hook at offset 0x4f8
|
||||
};
|
||||
|
||||
// Hook info for NQDMisc
|
||||
struct accl_hook_info {
|
||||
bool (*draw_func)(accl_params *);
|
||||
bool (*sync_func)(void *);
|
||||
uint32 code;
|
||||
};
|
||||
|
||||
// Hook function index
|
||||
enum {
|
||||
ACCL_BITBLT,
|
||||
ACCL_BLTMASK,
|
||||
ACCL_FILLRECT,
|
||||
ACCL_FILLMASK
|
||||
// 4: bitblt
|
||||
// 5: lines
|
||||
// 6: fill
|
||||
};
|
||||
|
||||
#endif
|
58
SheepShaver/src/include/xlowmem.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* xlowmem.h - Definitions for extra Low Memory globals (0x2800..)
|
||||
*
|
||||
* SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* 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 XLOWMEM_H
|
||||
#define XLOWMEM_H
|
||||
|
||||
// Modes for XLM_RUN_MODE
|
||||
#define MODE_68K 0 // 68k emulator active
|
||||
#define MODE_NATIVE 1 // Switched to native mode
|
||||
#define MODE_EMUL_OP 2 // 68k emulator active, within EMUL_OP routine
|
||||
|
||||
#define XLM_SIGNATURE 0x2800 // SheepShaver signature
|
||||
#define XLM_KERNEL_DATA 0x2804 // Pointer to Kernel Data
|
||||
#define XLM_TOC 0x2808 // TOC pointer of emulator
|
||||
#define XLM_SHEEP_OBJ 0x280c // Pointer to SheepShaver object
|
||||
#define XLM_RUN_MODE 0x2810 // Current run mode, see enum above
|
||||
#define XLM_68K_R25 0x2814 // Contents of the 68k emulator's r25 (which contains the interrupt level), saved upon entering EMUL_OP mode, used by Execute68k() and the USR1 signal handler
|
||||
#define XLM_IRQ_NEST 0x2818 // Interrupt disable nesting counter (>0: disabled)
|
||||
#define XLM_PVR 0x281c // Theoretical PVR
|
||||
#define XLM_BUS_CLOCK 0x2820 // Bus clock speed in Hz (for DriverServicesLib patch)
|
||||
#define XLM_EMUL_RETURN_PROC 0x2824 // Pointer to EMUL_RETURN routine
|
||||
#define XLM_EXEC_RETURN_PROC 0x2828 // Pointer to EXEC_RETURN routine
|
||||
#define XLM_EMUL_OP_PROC 0x282c // Pointer to EMUL_OP routine
|
||||
#define XLM_EMUL_RETURN_STACK 0x2830 // Stack pointer for EMUL_RETURN
|
||||
#define XLM_RES_LIB_TOC 0x2834 // TOC pointer of Resources library
|
||||
#define XLM_GET_RESOURCE 0x2838 // Pointer to native GetResource() routine
|
||||
#define XLM_GET_1_RESOURCE 0x283c // Pointer to native Get1Resource() routine
|
||||
#define XLM_GET_IND_RESOURCE 0x2840 // Pointer to native GetIndResource() routine
|
||||
#define XLM_GET_1_IND_RESOURCE 0x2844 // Pointer to native Get1IndResource() routine
|
||||
#define XLM_R_GET_RESOURCE 0x2848 // Pointer to native RGetResource() routine
|
||||
#define XLM_EXEC_RETURN_OPCODE 0x284c // EXEC_RETURN opcode for Execute68k()
|
||||
|
||||
#define XLM_ETHER_INIT 0x28c0 // Pointer to ethernet InitStreamModule() function
|
||||
#define XLM_ETHER_TERM 0x28c4 // Pointer to ethernet TerminateStreamModule() function
|
||||
#define XLM_ETHER_OPEN 0x28c8 // Pointer to ethernet ether_open() function
|
||||
#define XLM_ETHER_CLOSE 0x28cc // Pointer to ethernet ether_close() function
|
||||
#define XLM_ETHER_WPUT 0x28d0 // Pointer to ethernet ether_wput() function
|
||||
#define XLM_ETHER_RSRV 0x28d4 // Pointer to ethernet ether_rsrv() function
|
||||
#define XLM_VIDEO_DOIO 0x28d8 // Pointer to video DoDriverIO() function
|
||||
|
||||
#endif
|