Imported sources

This commit is contained in:
cebix 2002-02-04 16:58:13 +00:00
parent dc4d9a56c7
commit 8e4d5e5f40
109 changed files with 26616 additions and 0 deletions

340
SheepShaver/COPYING Normal file
View 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
View 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;

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

View 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>&copy; 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

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

View 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 &gt;=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>

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

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

View 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>&copy; 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

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

View 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 &gt;=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>

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View 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
}

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

View 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
}

View 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;
}

View 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

View 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

View 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;
}

View 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

View 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.

View 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);
}

Binary file not shown.

Binary file not shown.

View 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;
}

View 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;
}
}

View 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();
}

File diff suppressed because it is too large Load Diff

View 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);
}

View 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);
}
}

View 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

View 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;
}

View 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

View 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)
}

View 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;
}

View 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;
}
}

View 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,

View 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

View 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(&ether_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);
}

View 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;
}
}

View 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;
}

View 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.

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

View 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)
{
}

View 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
View 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 "$@"

View 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;
}
}

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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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();
}

View 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);
}

View 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

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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
View 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;
}
}

File diff suppressed because it is too large Load Diff

1632
SheepShaver/src/ether.cpp Normal file

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

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