mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-02-21 20:29:15 +00:00
initial source drop, apple2-emul-0.7.4.tar.gz
This commit is contained in:
parent
5e4d640afd
commit
e71efa3acd
11
.apple2
Normal file
11
.apple2
Normal file
@ -0,0 +1,11 @@
|
||||
speed = 100
|
||||
mode = ][+ undocumented
|
||||
disk path = /usr/local/games/apple2/disks
|
||||
color = interpolated
|
||||
sound = pc speaker
|
||||
joystick = pc joystick
|
||||
joystick range = 256
|
||||
origin_x = 128
|
||||
origin_y = 128
|
||||
sensitivity = 3%
|
||||
system path = /usr/local/games/apple2/rom
|
15
ASM
Normal file
15
ASM
Normal file
@ -0,0 +1,15 @@
|
||||
Begin3
|
||||
Title: Apple // emulator for Linux
|
||||
Author: alexb@csd.uu.se (Alexander Jean-Claude Bottema)
|
||||
sl14@cornell.edu (Stephen Lee)
|
||||
asc@mhpcc.edu (Aaron Culliney)
|
||||
michael@talamasca.ocis.net (Michael Deutschmann)
|
||||
Version: 0.7.4
|
||||
Entered-date: 2000-03-24
|
||||
Description: Apple II+, //e emulator. Uses svgalib or X.
|
||||
Keywords: emulator, linux
|
||||
Uploader: michael@talamasca.ocis.net (Michael Deutschmann)
|
||||
Primary-site: ftp.ocis.net /pub/users/ldeutsch/release/
|
||||
257k apple2-emul-0.7.4.tar.gz
|
||||
Platform: Linux i386
|
||||
End
|
11
AUTHORS
Normal file
11
AUTHORS
Normal file
@ -0,0 +1,11 @@
|
||||
Alexander Jean-Claude Bottema <alexb@csd.uu.se> made the original
|
||||
version of the emulator in 1994.
|
||||
|
||||
Stephen Lee <sl14@cornell.edu> and particularly Aaron Culliney
|
||||
<asc@mhpcc.edu> have done much work on the emulator since.
|
||||
|
||||
Michael Deutschmann <michael@talamasca.ocis.net> cleaned up the
|
||||
build sequence to use standard GNU tools, and is the present coordinator.
|
||||
|
||||
Tom Lear <tom@trap.mtview.ca.us> maintains the Debian package of
|
||||
this program, and has contributed some fixes.
|
339
COPYING
Normal file
339
COPYING
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
182
INSTALL
Normal file
182
INSTALL
Normal file
@ -0,0 +1,182 @@
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
16
LSM
Normal file
16
LSM
Normal file
@ -0,0 +1,16 @@
|
||||
Begin4
|
||||
Title: Apple2/Linux
|
||||
Version: 0.7.4
|
||||
Entered-date: 2000-03-24
|
||||
Description: Apple II+, //e emulator. Uses svgalib or X
|
||||
Keywords: apple2, emulator
|
||||
Author: alexb@csd.uu.se (Alexander Jean-Claude Bottema)
|
||||
sl14@cornell.edu (Stephen Lee)
|
||||
asc@mhpcc.edu (Aaron Culliney)
|
||||
Maintained-by: michael@talamasca.ocis.net (Michael Deutschmann)
|
||||
Primary-site: ftp.ocis.net /pub/users/ldeutsch/release/
|
||||
257k apple2-emul-0.7.4.tar.gz
|
||||
Alternate-site: metalab.unc.edu /pub/Linux/system/emulators/
|
||||
Copying-policy: GPL
|
||||
Platforms: x86 CPU, either svgalib or X-windows
|
||||
End
|
3
Makefile.am
Normal file
3
Makefile.am
Normal file
@ -0,0 +1,3 @@
|
||||
SUBDIRS = disks src
|
||||
|
||||
EXTRA_DIST = README.debugger TODO LSM ASM PROBLEMS .apple2
|
320
Makefile.in
Normal file
320
Makefile.in
Normal file
@ -0,0 +1,320 @@
|
||||
# Makefile.in generated automatically by automake 1.4 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = .
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
CC = @CC@
|
||||
DEBUGGER_O = @DEBUGGER_O@
|
||||
JOYSTICK_O = @JOYSTICK_O@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
PACKAGE = @PACKAGE@
|
||||
PROGS = @PROGS@
|
||||
VERSION = @VERSION@
|
||||
|
||||
SUBDIRS = disks src
|
||||
|
||||
EXTRA_DIST = README.debugger TODO LSM ASM PROBLEMS .apple2
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_CLEAN_FILES =
|
||||
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
|
||||
Makefile.in NEWS TODO acinclude.m4 aclocal.m4 configure configure.in \
|
||||
install-sh missing mkinstalldirs
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
$(ACLOCAL_M4): configure.in acinclude.m4
|
||||
cd $(srcdir) && $(ACLOCAL)
|
||||
|
||||
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
|
||||
cd $(srcdir) && $(AUTOCONF)
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run `make' without going through this Makefile.
|
||||
# To change the values of `make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in `config.status', edit `config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||
# (2) otherwise, pass the desired values on the `make' command line.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
all-recursive install-data-recursive install-exec-recursive \
|
||||
installdirs-recursive install-recursive uninstall-recursive \
|
||||
check-recursive installcheck-recursive info-recursive dvi-recursive:
|
||||
@set fnord $(MAKEFLAGS); amf=$$2; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||
maintainer-clean-recursive:
|
||||
@set fnord $(MAKEFLAGS); amf=$$2; \
|
||||
dot_seen=no; \
|
||||
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
rev="$$subdir $$rev"; \
|
||||
test "$$subdir" = "." && dot_seen=yes; \
|
||||
done; \
|
||||
test "$$dot_seen" = "no" && rev=". $$rev"; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
for subdir in $$rev; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done && test -z "$$fail"
|
||||
tags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||
done
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
here=`pwd` && cd $(srcdir) \
|
||||
&& mkid -f$$here/ID $$unique $(LISP)
|
||||
|
||||
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|
||||
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
|
||||
# This target untars the dist file and tries a VPATH configuration. Then
|
||||
# it guarantees that the distribution is self-contained by making another
|
||||
# tarfile.
|
||||
distcheck: dist
|
||||
-rm -rf $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
|
||||
mkdir $(distdir)/=build
|
||||
mkdir $(distdir)/=inst
|
||||
dc_install_base=`cd $(distdir)/=inst && pwd`; \
|
||||
cd $(distdir)/=build \
|
||||
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dist
|
||||
-rm -rf $(distdir)
|
||||
@banner="$(distdir).tar.gz is ready for distribution"; \
|
||||
dashes=`echo "$$banner" | sed s/./=/g`; \
|
||||
echo "$$dashes"; \
|
||||
echo "$$banner"; \
|
||||
echo "$$dashes"
|
||||
dist: distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
-rm -rf $(distdir)
|
||||
dist-all: distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
-rm -rf $(distdir)
|
||||
distdir: $(DISTFILES)
|
||||
-rm -rf $(distdir)
|
||||
mkdir $(distdir)
|
||||
-chmod 777 $(distdir)
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
for subdir in $(SUBDIRS); do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -d $(distdir)/$$subdir \
|
||||
|| mkdir $(distdir)/$$subdir \
|
||||
|| exit 1; \
|
||||
chmod 777 $(distdir)/$$subdir; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
info-am:
|
||||
info: info-recursive
|
||||
dvi-am:
|
||||
dvi: dvi-recursive
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
installcheck-am:
|
||||
installcheck: installcheck-recursive
|
||||
install-exec-am:
|
||||
install-exec: install-exec-recursive
|
||||
|
||||
install-data-am:
|
||||
install-data: install-data-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-recursive
|
||||
uninstall-am:
|
||||
uninstall: uninstall-recursive
|
||||
all-am: Makefile
|
||||
all-redirect: all-recursive
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
mostlyclean-am: mostlyclean-tags mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
clean-am: clean-tags clean-generic mostlyclean-am
|
||||
|
||||
clean: clean-recursive
|
||||
|
||||
distclean-am: distclean-tags distclean-generic clean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f config.status
|
||||
|
||||
maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
|
||||
distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f config.status
|
||||
|
||||
.PHONY: install-data-recursive uninstall-data-recursive \
|
||||
install-exec-recursive uninstall-exec-recursive installdirs-recursive \
|
||||
uninstalldirs-recursive all-recursive check-recursive \
|
||||
installcheck-recursive info-recursive dvi-recursive \
|
||||
mostlyclean-recursive distclean-recursive clean-recursive \
|
||||
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
|
||||
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
|
||||
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
|
||||
install-exec install-data-am install-data install-am install \
|
||||
uninstall-am uninstall all-redirect all-am all installdirs-am \
|
||||
installdirs mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
260
NEWS
Normal file
260
NEWS
Normal file
@ -0,0 +1,260 @@
|
||||
Changed in 0.7.4:
|
||||
|
||||
Many bugs have been fixed, including a calling-convention mistake that
|
||||
could cause unpredictable behavior on reboot. Potential buffer overflows
|
||||
have also been corrected.
|
||||
|
||||
Some key assignments have changed. Joystick buttons are now Left-Alt,
|
||||
Right-Alt & Insert. Delete, formerly a joystick button, now produces the
|
||||
DEL ascii code. Reboot is now Break (Ctrl-Pause), and Reset is now
|
||||
Ctrl-Printscreen. (This is reversed from 0.7.3)
|
||||
|
||||
Some significant optimizations were also made in the assembly code. The
|
||||
large memory-access indirection table is now compressed using virtual
|
||||
memory tricks, to slightly reduce cache load and swap requirements.
|
||||
|
||||
Also many cleanups have been made in the internal code. This is
|
||||
user-invisible, and far from complete. When done, it will become easier to
|
||||
add new interface cards, video drivers, and other stuff, as well as port
|
||||
to other unixes.
|
||||
|
||||
Changed in 0.7.3:
|
||||
|
||||
More makefile/configuration bugs were fixed.
|
||||
|
||||
The `Mystery House' sample disk, which was accidently omitted from my
|
||||
distributions, has been reinstated. Also, I've added a new sample
|
||||
disk image - William Night's emulator performance tests.
|
||||
|
||||
Changed in 0.7.2:
|
||||
|
||||
The configure script will now react to absence of X Windows or SVGAlib by
|
||||
only building an emulator for the remaining graphics system.
|
||||
|
||||
A makefile bug that caused xapple-80col not to depend on
|
||||
all it's source files was fixed. Also, the alternate character set is now
|
||||
correctly restored on exit from the <F10> menu.
|
||||
|
||||
Some major cleanups were done to the assembly-language files. This is
|
||||
invisible to the user, but should make further enhancement a little saner.
|
||||
|
||||
The banners on the source code have been synchronized.
|
||||
|
||||
Changed in 0.7.1:
|
||||
|
||||
1. Fixed a makefile bug that caused xapple-80col to be miscompiled.
|
||||
|
||||
2. Put sample .apple2 (config file) back in. It was accidentally excluded
|
||||
from 0.7.
|
||||
|
||||
3. The SVGA emulator is again named `apple2', not `sapple2'.
|
||||
|
||||
Changed in 0.7: (Sep 98)
|
||||
|
||||
Version 0.7 - Michael Deutschmann <michael@talamasca.wkpowerlink.com>
|
||||
|
||||
1. Replaced "character.rom" and Aaron's MouseText table in misc.c with
|
||||
a single file, font.txt, which is converted into a packed c table by a
|
||||
generator utility.
|
||||
|
||||
2. Overhauled Makefile system. We now use GNU autoconf/automake.
|
||||
|
||||
Note: This hasn't been tested extensively. Also, there are a few automake
|
||||
tricks I haven't bothered with - I added them to TODO.
|
||||
|
||||
Changed is 0.06: (Aug 98)
|
||||
-------------------------
|
||||
|
||||
Version 0.06 - Aaron Culliney <chernabog@baldmountain.bbn.com,
|
||||
aculline@bbn.com>
|
||||
My code changes have nothing to do with my employer, GTE
|
||||
Internetworking, BBN Technologies. They were written completely on my
|
||||
own time and on my own machine.
|
||||
|
||||
1) Separated SVGAlib specific stuff into svideo.c. Added X Windows
|
||||
frontend support in xvideo.c. The X frontend works by doing an
|
||||
X(Shm)PutImage() of the emulator's framebuffer around 30 times a
|
||||
second. This saves us from changing the internal video routines (they
|
||||
assume direct access to an 8bit framebuffer), and it's a heck of a lot
|
||||
faster than trying to do an XPutPixels() on each change. The X
|
||||
frontend only currently works for 8bit displays. Make sure you run it
|
||||
using a mode (specified in XF86Config) that has a bit depth of 8 (not
|
||||
16 or greater).
|
||||
|
||||
2) We now build three versions of the emulator: svideo_320x200,
|
||||
xvideo_320x200, xvideo_640x400. The last one really isn't 640x400 for
|
||||
optimization reasons (568x384) although it probably should be...
|
||||
Sorry, but there's no support for switching resolutions on the fly, we
|
||||
ifdef it in with a new define "_640x400".
|
||||
|
||||
3) Provided 80column support for the 640x400 X version. Now you
|
||||
can PR#3 (running as //e) and get 80 columns. This change required
|
||||
a resolution of at least 560 horizontal pixels (Apple //e specs).
|
||||
|
||||
4) Both SVGA and X versions need to be suid root (for PC speaker port
|
||||
access and SVGA stuff). But both versions now give up root access
|
||||
during video initialization. This means that disk access is now done
|
||||
as *you* (not root) even when g(un)zipping images for loading.
|
||||
Before images would be g(un)zipped as root. There was something about
|
||||
this that made me uneasy... Now it's up to you to give the
|
||||
appropriate user/group permissions to your disk image repository.
|
||||
I make no claim about the security fitness of this emulator. See the
|
||||
other READMEs and files for more information/disclaimers.
|
||||
|
||||
5) Did a 180 on the disk image selection menu. <RET> now tries
|
||||
to open disk images as read-only, 'W' for both read-write.
|
||||
Of course this will only work if you have the correct
|
||||
file permissions set (see 5 above). I find this more convenient b/c
|
||||
I play alot of the arcade games where you don't ever save game state.
|
||||
|
||||
6) Removed the disk "Information" submenu. I never use it. Do you?
|
||||
|
||||
|
||||
|
||||
Changes in 0.05: (Feb 98)
|
||||
-------------------------
|
||||
|
||||
Version 0.05 - Aaron Culliney <chernabog@baldmountain.bbn.com,
|
||||
aculline@bbn.com>
|
||||
My code changes have nothing to do with my employer, GTE
|
||||
Internetworking, BBN Technologies. They were written completely on my
|
||||
own time and on my own machine.
|
||||
|
||||
1) Added support for 65c02 instructions. The programs that
|
||||
I've tested which use them work just fine.
|
||||
|
||||
2) Added support for 128k //e EXCEPT 80 column mode, B/W
|
||||
DHIRES mode, and MouseText character set. The two unimplemented video
|
||||
modes require major changes to current video routines, thus a next
|
||||
version... New supported images are copy ii+ 9.0, diagnostics //e,
|
||||
marble madness, airheart, legend of blacksilver, pirates!...
|
||||
|
||||
3) Fixed some old problems with HIRES colors being off around
|
||||
byte edges in interpolated/color modes. but we still give you the
|
||||
option to use these "lazy" modes since emulation is faster with them
|
||||
enabled...
|
||||
|
||||
4) You now have several new options in your .apple2 file. I
|
||||
suggest either copying the distributed one over your existing one, or
|
||||
merging the changes in.
|
||||
|
||||
5) Fixed some potential security bugs where a user could
|
||||
traverse into sensitive directories by using the disk selection
|
||||
interface. The current emulator version is not guaranteed to be
|
||||
foolproof since it has to be installed suid root for normal users to
|
||||
use it. Sysadmins should take extra precautions as they see fit.
|
||||
|
||||
6) Added and deprecated some options in the debugger interface
|
||||
to support the new 128k //e. see the DEBUGGER file for more info.
|
||||
DEBUGGER support is not default compiled in.
|
||||
|
||||
7) added some extra options to the .config file that you build
|
||||
into the emulator. One big one: a way to set the max delay count in
|
||||
the emulator to bring Apple ][ emulation rates down to normal on high
|
||||
end pentiums!... 100 is the default delay rate (which works just fine
|
||||
for low end 386-Pentium100's).
|
||||
|
||||
|
||||
|
||||
Changes in 0.04: (June 97)
|
||||
-----------------------------
|
||||
|
||||
Version 0.04 - Aaron Culliney <chernabog@baldmountain.bbn.com,
|
||||
aculline@bbn.com>
|
||||
My code changes have nothing to do with my employer, BBN. They were
|
||||
written completely on my own time and on my own machine.
|
||||
|
||||
1) Added PC Joystick Support. You must have the joystick
|
||||
kernel loadable module 0.8.0 correctly configured and installed to use
|
||||
this feature.
|
||||
|
||||
2) Changed the way the emulator handles the language card
|
||||
memory space. We no longer patch rom/ram on lc_c08x functions. I did
|
||||
this because under certain conditions the previous versions of the
|
||||
emulator would run a lot slower. Now you may notice the emulator
|
||||
running a tad slower in general (because of the range checking), but
|
||||
Ultima 4 and Arctic Fox (formerly unplayable) should now be just fine.
|
||||
|
||||
3) Changed the way the .apple2 preferences file is handled. I
|
||||
Did this mainly to support saving of PC Joystick parameters, and I'd
|
||||
rather let flex do the dirty work of regexp matching.
|
||||
|
||||
4) Changed the disk interface and main interface menu. In the
|
||||
disk interface, you can now see which disk is in the drive, and with
|
||||
what permission <rw1> for read/write drive 1. You can eject this disk
|
||||
or force it to be write-protected. In the main menu screen, you have
|
||||
more parameters to play around with (associated with the pc joystick
|
||||
add-on).
|
||||
|
||||
5) Disk image files are now opened with user privileges, not
|
||||
root privileges, even though the program is suid root. gzip'ed disks
|
||||
are still handled as root, but we no longer call the unsecure system()
|
||||
to do the dirty work. Instead we fork and directly exec "/bin/gzip".
|
||||
|
||||
5) General bug fixes and enhancements.
|
||||
|
||||
|
||||
Changes in 0.03: (Jan-Feb 97)
|
||||
-----------------------------
|
||||
|
||||
Version 0.03 - Aaron Culliney <chernabog@baldmountain.bbn.com>
|
||||
My code changes have nothing to do with my employer, BBN. They were
|
||||
written completely on my own time and on my own machine.
|
||||
|
||||
1) Fixed language card initialization bug.
|
||||
|
||||
2) Improved colors. Seems that Greens and purples we're
|
||||
switched around. The colors are still slightly off, and color
|
||||
interpolation seems screwy (TODO).
|
||||
|
||||
3) Added apple II debugger interface. This requires flex
|
||||
version 2.5.2. (You can compile this into the program or leave it
|
||||
out.) Type F7 to get into the debugger and type a '?' to see a
|
||||
command summary. Check out the file DEBUGGER for more info.
|
||||
|
||||
4) Added support for standard 232960 .nib disks.
|
||||
|
||||
5) Added a more intuitive interface to selecting disks. You
|
||||
can now traverse forward and backward in a directory hierarchy with
|
||||
the base directory set by your .apple2 config file.
|
||||
|
||||
6) changed keymap: shift-p = @ and shift-N = ^, just like my
|
||||
old II+ keyboard.
|
||||
|
||||
Changes in 0.02: (8 Dec 1995)
|
||||
-----------------------------
|
||||
|
||||
* Ctrl-C will not kill the emulator with newer SVGAlib. Please
|
||||
use SVGAlib > 1.2.9 for best results.
|
||||
|
||||
* Rudimentory REPT key handling. It's too fast though.
|
||||
|
||||
* The assembler files now compiles under ELF.
|
||||
|
||||
* Not every SVGA card can do page-flipping. The emulator now
|
||||
checks for this and fall back to VGA if it can't.
|
||||
|
||||
* Keymap has changed a bit. Backspace and ']' is now <-, '[' is
|
||||
REPT.
|
||||
|
||||
* Disk extension changed to the more common .dsk (and a2d.info to
|
||||
dsk.info).
|
||||
|
||||
|
||||
Changes in 0.01: (9 Oct 1994)
|
||||
-----------------------------
|
||||
|
||||
* Standard VGA support with some performance degradation.
|
||||
(When page flipping occurs, 64K memory banks are swapped;
|
||||
hence the performance degradation.)
|
||||
|
||||
* -vga flag switch added, e.g. "apple2 -vga"; forces standard
|
||||
VGA detection.
|
||||
|
||||
* (Trident) TVGA8900 page flipping bug fixed.
|
||||
|
||||
* File names may now contain any character codes. (The previous
|
||||
version had some problems with compressing/uncompressing file
|
||||
names with extraordinary characters.)
|
||||
|
||||
* Diskette selection retains last cursor position.
|
115
PROBLEMS
Normal file
115
PROBLEMS
Normal file
@ -0,0 +1,115 @@
|
||||
Known issues with the emulator:
|
||||
|
||||
Emulation Fidelity:
|
||||
|
||||
- Disk emulation. The emulator is not very realistic. It handles almost
|
||||
all non-copyprotected disk access okay, but copyprotected or diagnostic
|
||||
programs may be confused by our drive, which magically spins at precisely
|
||||
the optimal speed. (see Specific Programs, below).
|
||||
|
||||
- Medium Resolution graphics. This is a rarely used //e mode that is to
|
||||
Low-Res what 80 Column text is to 40 column text. We don't support it as
|
||||
yet, although it should be relatively simple.
|
||||
|
||||
- Joystick. The apple joystick hardware is read by measuring the time it
|
||||
takes for a specific softswitch to clear. The emulator cannot as yet
|
||||
compensate for the speed of the loop used to measure the joystick --
|
||||
applications using ROM routines will be fine, but custom joystick code
|
||||
may become mistuned. The Range configuration feature can be used to
|
||||
compensate for this.
|
||||
|
||||
- We don't emulate the //e's vertical blanking interval detection feature.
|
||||
|
||||
Graphics:
|
||||
|
||||
- Composite graphics artifacts are not emulated. This is not a big
|
||||
interest to me (Michael), but the previous programmers have suggested it.
|
||||
|
||||
- B/W color setting does not apply to lores or double hires. This
|
||||
generally is not an issue in practice though, as it's really only needed
|
||||
to avoid color fringing in b/w hires images.
|
||||
|
||||
- Double Hires mode is always 140x192 color. Some applications use it as
|
||||
a 560x192 b/w display however. Note that most applications indicate
|
||||
which mode they want using the high bit of the dhires data bytes, so it
|
||||
wouldn't need to be a preferences setting.
|
||||
|
||||
- If an 80-column mode is selected in the low-res emulator, nothing will
|
||||
be written to the display -- the image from the last video mode will
|
||||
remain on the screen. If a menu is brought up it will `stick'. This may
|
||||
make people think the emulator crashed, although it will recover if the
|
||||
application returns to 40-column mode.
|
||||
|
||||
- There is no 80-column mode for svgalib apple2. It would be possible on
|
||||
standard VGA, although there are not enough colors to do flashing letters
|
||||
by palette tricks as we do now.
|
||||
|
||||
- In X, the emulator window takes over the palette, causing all the other
|
||||
windows to be miscolored. We only need 20 or so colors, so it would be
|
||||
better if we could share the common palette.
|
||||
|
||||
Keyboard:
|
||||
|
||||
- Key Handling is a little messy, especially with the way the X support
|
||||
is bolted on top of core code originally designed for SVGA scancodes.
|
||||
|
||||
- Presently, the Backspace key is interpreted as Left-Arrow (Code 0x88).
|
||||
It could be argued that it should be interpreted as Delete (Code 0xff)
|
||||
instead. Real Apples had no seperate Backspace key, but the //e's Delete
|
||||
key was in an analogous position to the PC's Backspace). The PC
|
||||
keyboard's Delete is assigned to 0xff (in //e mode).
|
||||
|
||||
- If you're using Apple ][+ mode, the keyboard may appear broken. That's
|
||||
a feature -- the program is imitating the historical ][+ keyboard layout.
|
||||
Press F5 to see a map. Maybe we should add a means to turn it off.
|
||||
|
||||
- On my X system, without explict xmodmap or xkbcomp intervention,
|
||||
Break (reset) won't work with XKB enabled, and PrintScreen (reboot) won't
|
||||
work with it disabled.
|
||||
|
||||
This is X's fault, and I've sent them a bug-report, but maybe we should
|
||||
consider moving the keys (again...)
|
||||
|
||||
Miscellany:
|
||||
|
||||
- Older versions of this file note problems with scandir() in the
|
||||
presence of orphan symlinks in some versions of the C library. Hasn't
|
||||
been a problem for my glibc 2.1.2 system.
|
||||
|
||||
- Presently the programs are not automatically set SUID on install.
|
||||
|
||||
- The emulator requires ROMs for both ][+ and //e even if only used to
|
||||
emulate one of them.
|
||||
|
||||
- In theory, typing "Ctrl-Left Alt-Pause" should be equivalent to
|
||||
"Ctrl-Open Apple-Reset" and make the //e reboot. This doesn't work
|
||||
properly in practice. Somehow CXROMINT is not cleared at disk-interface
|
||||
detection time, so the disk won't boot.
|
||||
|
||||
(Ctrl-Right Alt-Pause activates diagnostic mode, as expected.)
|
||||
|
||||
Specific Programs:
|
||||
|
||||
- Some programs (Computist's Nibbler, Sword of Kadash Master copy for
|
||||
example) lock up. It appears (in debugger) that they are reading the disk
|
||||
with the motor off. Perhaps they pulsed the real Apple's drive motor to make
|
||||
it turn slower?
|
||||
|
||||
- ProDOS will refuse to format disks, claiming that the disk is too slow.
|
||||
|
||||
- ``Alternate Reality: The City'' seems to get jammed, rapidly changing
|
||||
the video mode. I'm not sure if this is a real failure, or just a special
|
||||
effect that takes longer than I'm willing to wait to finish (mode switches
|
||||
would be much faster on a real Apple.) I can get into the program
|
||||
with some nontrivial debugger manipulation to `short out' the offending loops.
|
||||
|
||||
- ``Moon Patrol'' will crash in ][+ mode at the end of the first level
|
||||
(ie: Point E). This is caused by a "02" opcode at address 1E15, an
|
||||
undocumented HANG instruction. //e mode works, since the 65C02 treats
|
||||
this instruction as a no-op.
|
||||
|
||||
Moon Patrol may actually be //e-only. Yet this seems a gratutious
|
||||
incompatibility, since the fact you can play the first level (and further
|
||||
ones using the debugger) under ][+ mode indicates it doesn't need any //e
|
||||
features. Perhaps the bug was introduced by the people who cracked it's
|
||||
copy protection.
|
408
README
Normal file
408
README
Normal file
@ -0,0 +1,408 @@
|
||||
**************************************************************************
|
||||
* Apple II+ Emulator version 0.7 for Linux *
|
||||
* *
|
||||
* Original Author: Alexander Jean-Claude Bottema *
|
||||
* Email : d91a1bo@meryl.csd.uu.se *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
* Modified: Dec 8 1995 by Stephen Lee <sl14@cornell.edu> *
|
||||
* Modified: Jan 97 by Aaron Culliney <aculline@bbn.com> *
|
||||
* <chernabog@baldmountain.bbn.com> *
|
||||
* Modified: Jun 97 by Aaron Culliney <aculline@bbn.com> *
|
||||
* <chernabog@baldmountain.bbn.com> *
|
||||
* Modified: Feb 98 by Aaron Culliney <aculline@bbn.com> *
|
||||
* <chernabog@baldmountain.bbn.com> *
|
||||
* Modified: Aug 98 by Aaron Culliney <aculline@bbn.com> *
|
||||
* <chernabog@baldmountain.bbn.com> *
|
||||
* *
|
||||
* Modified: Sep 98, Dec 98, Jan 98, Jun 99 *
|
||||
* by Michael Deutschmann *
|
||||
* <michael@talamasca.wkpowerlink.com>*
|
||||
* *
|
||||
**************************************************************************
|
||||
|
||||
NOTE:
|
||||
This is basically the original README. See the CHANGES file
|
||||
first for information on this specific version of the emulator. Then
|
||||
read section 0 (installation) in this file for cookbook compilation /
|
||||
installation instructions. Other information in this file may be
|
||||
outdated, so read the manpage for up-to-date runtime instructions.
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
0. Installation issues (briefly)
|
||||
1. Why did I make an Apple II+ Emulator when there are so many available?
|
||||
2. System Files
|
||||
3. Keyboard & keys
|
||||
4. Diskette database
|
||||
5. Future plans
|
||||
6. Status of the current emulator
|
||||
7. Can you port this to DOS?
|
||||
8. Availability
|
||||
9. Known problems
|
||||
10. Changes since the last
|
||||
11. Final words
|
||||
|
||||
|
||||
0. Installation issues (briefly)
|
||||
================================
|
||||
|
||||
Requirements: SVGA lib version 1.2.9 (or later, see 9.) Tested under 1.2.13.
|
||||
Kernel 2.0.X. Tested under 2.0.36pre12.
|
||||
libc 4.4.4 (or later). Tested under glibc-2.0.6
|
||||
joystick 0.8.0 kernel module for PC Joystick support.
|
||||
flex 2.5.2 (for compiling lex files)
|
||||
|
||||
|
||||
1) Unpack this distribution in a temporary directory.
|
||||
|
||||
2) Run "configure" for a normal build, or "configure --enable-debugger"
|
||||
to add debugger support. (Other GNU autoconf options, such as --prefix,
|
||||
may of course be used.) You may provide optimizations in the enviroment
|
||||
variable CFLAGS.
|
||||
|
||||
3) Type "make" to make the program. As root, type "make install" to
|
||||
install the programs in $(BINDIR) and the man page in $(MANDIR), (both
|
||||
configurable at the configure line). The sysadmin should enable the
|
||||
setuser bit on "apple2" in order for it to use the VGA. Enabling setuser
|
||||
on "xapple2" will allow use of the PC speaker, but is not essential.
|
||||
|
||||
4) Copy the .apple2 configuration file to your home directory, and
|
||||
read the manpage that was installed for further information on how to
|
||||
configure this file. You can configure most of the settings from
|
||||
within the emulator, (F10 for the menu screen), but you need the
|
||||
system path correctly set to point to the rom files before you start
|
||||
the emulator. The emulator won't run without the correct rom files
|
||||
(see the manpage).
|
||||
|
||||
5) After you're done configuring, type "xapple2" to run the
|
||||
emulator under X or "apple2" to run using svgalib. There are two X11
|
||||
versions for different resolutions. Once running, F1 selects disk
|
||||
drive #1, F2 selects disk drive #2, F10 gives you the main menu of
|
||||
runtime parameters, and F5 shows you the keyboard lay out.
|
||||
|
||||
|
||||
1. Why did I make an Apple II+ Emulator when there are so many available?
|
||||
=========================================================================
|
||||
|
||||
For three reasons. The first is that there are no Apple II emulators
|
||||
especially written for Linux; hence they do not take advantages that
|
||||
are commonly provided in Linux systems, e.g. the SVGA library
|
||||
distribution. However, there is an Apple II emulator for X-Windows
|
||||
that easily can be compiled on most UN*X architectures, but the major
|
||||
disadvantage is slow emulation. You cannot obtain a fast emulator by
|
||||
writing it in C, despite the elegant optimizations provided by GNU-C,
|
||||
but of course it becomes more portable if you do that.
|
||||
|
||||
By contrast, this Apple II emulator is partly written in 386 (AT&T)
|
||||
assembler; partly in C. Only those issues that were not time critical
|
||||
were written in C. Especially the CPU emulation was written in
|
||||
optimized assembler to achieve optimum performance. The emulator
|
||||
approximately runs twice as fast as an ordinary Apple II+ computer if
|
||||
it is running on a 486 DX-50.
|
||||
|
||||
The second reason is that there is no Apple II emulator which is 100%
|
||||
usable. Either it is too slow or it is simply too fast (= there is no
|
||||
option to trim the speed of the emulator). Furthermore, many
|
||||
implementors happily avoid implementing mixed text/graphics in high
|
||||
resolution mode; mostly because it complicates the programming. I have
|
||||
never seen an Apple II+ emulator that is entirely complete. I think
|
||||
most emulators fail on implementing the undocumented 6502 instructions
|
||||
(those that are listed as ???), hence some games (or applications) may
|
||||
not work despite they should.
|
||||
|
||||
The third reason is that no emulator support an easy way to switch
|
||||
diskettes given a database of diskettes. With this emulator you can
|
||||
easily switch diskettes through an intuitive interface. You can also
|
||||
add additional information for each diskette (in your database), e.g.
|
||||
which keys to use for a particular game program. The information is
|
||||
kept in a plain text file that can be edited with an ordinary text
|
||||
editor, preferbly GNU-Emacs.
|
||||
(Aaron removed the above feature)
|
||||
|
||||
|
||||
2. System files
|
||||
===============
|
||||
|
||||
Before you can run the emulator, three vital system files must be
|
||||
available. These are:
|
||||
|
||||
apple_II.rom (12k) This file contains the ROM of your Apple II+.
|
||||
It is not distributed due to copyright issues.
|
||||
You have to get this file on your own. If you
|
||||
have been running another emulator, you can
|
||||
probably use its ROM files directly. Technically
|
||||
speaking, this file is a memory dump of the
|
||||
consecutive addresses from D000 to FFFF. This
|
||||
file may also be called by other names such as
|
||||
apple.rom or apple2.rom, but is referenced
|
||||
internally as apple_II.rom.
|
||||
|
||||
appple_IIe.rom Likewise for IIe emulation.
|
||||
|
||||
slot6.rom (256 bytes) Memory dump of the consecutive addresses from
|
||||
C600 to C6FF. This file is not distributed
|
||||
either due to the same reasons as above. This
|
||||
file may also be called by other names such as
|
||||
controller.rom, but is referenced internally
|
||||
as slot6.rom.
|
||||
|
||||
Other important files
|
||||
---------------------
|
||||
|
||||
.apple2 This file is distributed. The file contains default
|
||||
parameter settings. The most important parameter is
|
||||
the setting of the system path, i.e. the directory
|
||||
where the three vital system (ROM) files are
|
||||
stored. Most of the other parameters can be
|
||||
changed during run time via the interface
|
||||
(activated by pressing F10).
|
||||
|
||||
Parameters (that can be set in .apple2):
|
||||
|
||||
speed = <percentage>% Speed of the emulator
|
||||
path = <directory> Diskette database directory
|
||||
color = off Monochrome mode
|
||||
on Plain color mode
|
||||
interpolated Interpolated color mode
|
||||
sound = off Silent mode
|
||||
pc speaker Sound through PC speaker
|
||||
joystick = off Joystick disabled
|
||||
linear Linear joystick mode
|
||||
pc joystick PC Joystick (see CHANGES)
|
||||
digital (Atari) digital joystick mode
|
||||
not yet supported
|
||||
joystick range 1-256 range of joystick
|
||||
origin_x = 0-255 Origin of the joystick (X)
|
||||
origin_y = 0-255 Origin of the joystick (Y)
|
||||
sensitivity <percentage>% Joystick sensitivity
|
||||
system_path = <directory> Directory where the system
|
||||
ROM files are stored.
|
||||
pc joystick parms You don't want to fool
|
||||
around with these, you
|
||||
generate these parms from
|
||||
F10 screen "Calibrate" menu
|
||||
item.
|
||||
|
||||
dsk.info An example is distributed. This file contains
|
||||
information for various diskettes kept in the database.
|
||||
|
||||
Syntax:
|
||||
{<Name of diskette>} i.e. the name is written
|
||||
within curly braces.
|
||||
<Any information...>
|
||||
|
||||
{<Name of another diskette>} ... etc.
|
||||
|
||||
3. Keyboard & keys
|
||||
==================
|
||||
|
||||
F1 To switch diskettes in Drive A, Slot 6
|
||||
F2 To switch diskettes in Drive B, Slot 6
|
||||
F4, also Pause key Pause
|
||||
F5 Keyboard layout
|
||||
F8 Words from the author (removed)
|
||||
F9 Toggle between maximum speed and configured speed.
|
||||
F10 General parameter settings
|
||||
Break (ctrl-Pause) Apple II Reset key
|
||||
Ctrl Printscreen Reboot Apple II emulator
|
||||
|
||||
The numeric keypad is used for joystick emulation.
|
||||
|
||||
Left Alt Joystick button 0
|
||||
Right Alt Joystick button 1
|
||||
Insert Joystick button 2
|
||||
|
||||
F7 Debugger - (if it's compiled into the source).
|
||||
Edit the Makefile if you don't want the
|
||||
debugger. The emulator will run slightly
|
||||
faster without the debugger.
|
||||
|
||||
|
||||
4. Diskette database
|
||||
====================
|
||||
|
||||
The diskettes are provided as plain binary files. These are actually
|
||||
raw dumps, containing the tracks from 0 to 34. For the standard
|
||||
143360 byte .dsk format each track is partitioned into sectors
|
||||
numbered from 0 to 15. Each sector is 256 bytes. Hence, the data is
|
||||
organized as the following:
|
||||
|
||||
File offset (in bytes) Sector Track
|
||||
---------------------- ------ -----
|
||||
0 0 0
|
||||
256 1 0
|
||||
512 2 0
|
||||
. . .
|
||||
. . .
|
||||
. . .
|
||||
3840 15 0
|
||||
4096 0 1
|
||||
4352 1 1
|
||||
. . .
|
||||
. . .
|
||||
. . .
|
||||
143104 15 34
|
||||
|
||||
To transfer Apple II diskettes into this format requires that you own
|
||||
an original Apple II. Since the drives provided by the IBM PC's are
|
||||
not compatible with the original Apple II drives there are no
|
||||
conversion programs directly available. If you have used other Apple
|
||||
II emulators it is most likely that the files will work with this
|
||||
emulator too. It seems to be a common standard to structure the
|
||||
diskettes in the above described way, e.g. the ApplePC and Apl2em
|
||||
emulators for DOS uses the same structure.
|
||||
|
||||
Emulated diskettes MUST have the .dsk or .nib extension (143360 bytes
|
||||
or 232960 bytes respectively), otherwise the emulator will not
|
||||
recognize the file as a valid diskette. However, it is valid to
|
||||
compress them by using gnu-zip (then the extension becomes .dsk.gz or
|
||||
.nib.gz). The emulator will automatically decompress/compress them
|
||||
whenever required (note that it assumes /bin/gzip exists).
|
||||
|
||||
Note that you can add information/documentation for the dsk-diskettes
|
||||
by using an ordinary text editor and edit the file "dsk.info". The
|
||||
name of the diskette is written in curly braces (without the .dsk
|
||||
extension) followed by any information.
|
||||
|
||||
|
||||
5. Future plans
|
||||
===============
|
||||
|
||||
I intend to improve the emulator. Actually, for the next major release
|
||||
(i.e. version 1.00) the emulator will be entirely rewritten. For minor
|
||||
changes, see file CHANGES.
|
||||
|
||||
[Note from Stephen Lee: since this hasn't happened yet, I took to
|
||||
improving the existing emulator until Alexander release a new one.]
|
||||
|
||||
[Note from Aaron Culliney: since this still hasn't happened, I also
|
||||
took the liberty to fix a few things and add some functionality.]
|
||||
|
||||
[v004 note: decided to add in some more features, and fix problems as
|
||||
they've arisen.]
|
||||
|
||||
6. Status of the current emulator
|
||||
=================================
|
||||
|
||||
Works in standard VGA Y
|
||||
Works in SVGA (then using SVGA facilities) Y
|
||||
Disk drive emulation (slot 6) (.dsk & .nib) Y
|
||||
Disk drive emulation (slot 5) N (release 1.00)
|
||||
High resolution emulation Y
|
||||
Low resolution emulation Y
|
||||
Mixed mode (in all resolution modes) Y
|
||||
Correct color emulation (both Low and Hi-res) Y
|
||||
Interpolated color emulation Y
|
||||
Configurable speed Y
|
||||
Diskette switching Y
|
||||
Diskette database Y
|
||||
Interface for parameter settings, etc. Y
|
||||
Sound emulation (PC speaker) Y
|
||||
Flashing text Y
|
||||
Joystick emulation through numeric keypad Y
|
||||
Virtual console switching Y (only when emu. is paused)
|
||||
Raw keyboard mode (reading scancodes) Y
|
||||
Undocumented 6502 instructions Y
|
||||
Language card (i.e. additonal 16k RAM) Y
|
||||
Serial card N (maybe release 1.00)
|
||||
Works on DOS N (AND NEVER WILL)
|
||||
Apple II Debugger Y
|
||||
PC Joystick kernel module support Y
|
||||
|
||||
7. Can you port this to DOS?
|
||||
============================
|
||||
|
||||
No, for two reasons. The first, and probably the most important, is
|
||||
that the current emulator use kernel specific issues that are not, and
|
||||
never will be, available in DOS. Future emulators will be based on the
|
||||
same principles, so the emulator will never run in DOS. The second
|
||||
reason is that DOS is a bad operating system. It is a pain in the neck
|
||||
to write and debug programs in DOS and there is no usable memory
|
||||
management provided by the kernel (if the DOS "interrupts" can be
|
||||
called a "kernel" at all).
|
||||
|
||||
With this free software I hope that more users will switch to Linux
|
||||
(which is a great operating system) and I have a dream that one day,
|
||||
DOS will become a minority.
|
||||
|
||||
8. Availability
|
||||
===============
|
||||
|
||||
This distribution is available at ftp.apple.asimov.net, and
|
||||
tsx-11.mit.edu, and sites mirroring these.
|
||||
|
||||
9. Known problems
|
||||
=================
|
||||
|
||||
Problem: SVGAlib version 1.2.8 and below has a bug in
|
||||
keyboard-handling that makes the '-' key (in the emulator)
|
||||
unusable.
|
||||
|
||||
Solution: Please use SVGAlib version 1.2.9 or above.
|
||||
|
||||
Problem: The REPT (repeat) key repeats too fast.
|
||||
|
||||
Answer: The current implementation is a kludge by me [Stephen]. I
|
||||
might fix it later, but again, I might not.
|
||||
|
||||
Problem: I can't switch virtual consoles while running the program
|
||||
under gdb [Aaron].
|
||||
|
||||
Answer: Actually you do, it's just that the graphic mode stays valid.
|
||||
If you have the svgalib utility "textmode", try a "shell
|
||||
textmode" reset. I haven't played around enough to figure out
|
||||
how/if you can get back to graphic mode after this.
|
||||
|
||||
Problem: Compiling with optimization causes the debugger to choke
|
||||
[Aaron].
|
||||
|
||||
Answer: I'm playing fast and loose with the debugger's assembly hooks.
|
||||
I think it's something to do with -fomit-frame-pointer. And
|
||||
since I don't see much speed gain, I'm ignoring the problem
|
||||
for now.
|
||||
|
||||
10. Changes
|
||||
===========
|
||||
|
||||
see file CHANGES
|
||||
|
||||
|
||||
11. Final words
|
||||
===============
|
||||
|
||||
Note that albeit you can switch between digital and linear joystick
|
||||
emulation, only linear mode is presently supported. I still haven't
|
||||
figured out how the atari (digital) joystick emulation works, so I'll
|
||||
save it to the next release (as I said in the previous release :-) )
|
||||
|
||||
[PC Joystick mode is just another linear mode. In general linear mode
|
||||
seems to work fine for most games. If a game seems to be having
|
||||
trouble with it, change the range from $100 (256) to $80 (128) with
|
||||
center points at $80 and $40 respectively. Switching around ranges
|
||||
often seems to do the trick for most games, but I bet I'm not handling
|
||||
the joystick softswich values correctly. documentation on this is
|
||||
scant. -Aaron]
|
||||
|
||||
I hope you will enjoy this emulator. I do. Many games (that I have
|
||||
ported) works perfectly, even those that use undocumented 6502
|
||||
instructions. Suggestions to improvements are welcome. My email
|
||||
address will be valid at least one more year, i.e. as long as I am a
|
||||
computer science student at the University of Uppsala in Sweden.
|
||||
|
||||
/ Alexander Jean-Claude Bottema (Email: d91a1bo@meryl.csd.uu.se)
|
||||
Oct. 9 1994 15:44:21
|
154
README.debugger
Normal file
154
README.debugger
Normal file
@ -0,0 +1,154 @@
|
||||
*************************************************************************
|
||||
* *
|
||||
* Apple II debugger routines for the Linux-x86 Apple II emulator. *
|
||||
* by Aaron Culliney - chernabog@baldmountain.bbn.com - (C) 1998 *
|
||||
* *
|
||||
* My code changes have nothing to do with my employer, GTE *
|
||||
* Internetworking, BBN Technologies. They were written completely on my*
|
||||
* own time and on my own machine. *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
The debugger console is a mid-size hack onto the main emulator code.
|
||||
I did it b/c I wanted to fool around with some of my old games while
|
||||
they were running and to debug the emulator itself.
|
||||
The code is kinda ugly in some areas, but seems robust enough; (I've
|
||||
used flex to handle most of the dangerous UI stuff). It runs a bit
|
||||
slower than when you're in unrestricted emulation mode because it's
|
||||
doing a lot of switching between C code and asm, copying state, and
|
||||
checking breakpoints/watchpoints.
|
||||
|
||||
|
||||
KNOWN PROBLEMS:
|
||||
--------------
|
||||
|
||||
When you hit a watchpoint or breakpoint, you have to step over it
|
||||
before you can use the g{o}, f{inish}, or u{ntil} commands again.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Usage:
|
||||
-----
|
||||
|
||||
F7 - enters the debugger. (actually we wait until we've finished with
|
||||
the current 6502 instruction before we enter the debugger so we're all
|
||||
synched up if/when we start stepping the machine).
|
||||
|
||||
ESC - exits the debugger console.
|
||||
|
||||
General Command format:
|
||||
|
||||
command {optional part} <mandatory part> (this | that)
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Disassembling Apple II main memory and language card memory:
|
||||
|
||||
d{is} {language card bank} {/bank/}{addrs} {+}{len}
|
||||
|
||||
Examples:
|
||||
"d" - disassemble from current location
|
||||
"dis +5" - disassemble from current location +5
|
||||
"dis /01/2000" - (128k (//e) specific)
|
||||
"dis lc1 d000 5" - disassemble memory +5 at lang card 1 0xd000
|
||||
|
||||
Note: {addrs} can be (d000 <-> ffff) or (0 <-> 2fff) for the language
|
||||
card.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Dumping memory:
|
||||
|
||||
m{em} {lc1|lc2} {addrs} {+}{len}
|
||||
a{scii} {lc1|lc2} {addrs} {+}{len}
|
||||
|
||||
Examples:
|
||||
|
||||
"mem" - dump memory at current location
|
||||
"m dead" - dump memory at 0xDEAD
|
||||
"m lc2 2fff 1" - dump memory at lang card 2 0x2FFF +1
|
||||
"ascii /01/400" - (128k (//e) specific)
|
||||
|
||||
Note: {addrs} can be (d000 <-> ffff) or (0 <-> 2fff) for the language
|
||||
card. Also you need to specify the {addrs} if you're examining lc
|
||||
memory.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Setting memory:
|
||||
<addrs> {lc1|lc2} : <byteseq>
|
||||
|
||||
"4000:deadc0de" - set memory at 0x4000 to 0xDEADC0DE
|
||||
"50lc2:def" - set memory at lang bank 2 0x50 to 0xDE0F
|
||||
|
||||
Note: {addrs} can be (d000 <-> ffff) or (0 <-> 2fff) for the language
|
||||
card.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Displaying machine state (registers, language card, drive, softswitches):
|
||||
|
||||
r{egs} - registers
|
||||
l{ang} - language card settings
|
||||
dr{ive} - disk drive settings
|
||||
vm - other virtual machine settings
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Stepping the machine:
|
||||
|
||||
(s{tep} | n{ext}) {len}
|
||||
f{inish}
|
||||
u{ntil}
|
||||
g{o} {addr}
|
||||
|
||||
-*step* or *next* 0-255 instructions.
|
||||
|
||||
-*finish* current stack-frame (stop at RTS).
|
||||
|
||||
-step *until* PC == next instruction (good for finishing loops).
|
||||
|
||||
-*go* or jump to {addr} and continue executing until user hits a key.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Searching and setting/unsetting memory breakpoints and watchpoints:
|
||||
|
||||
sea{rch} {lc1|lc2} <byteseq>
|
||||
|
||||
"se deadc0de" - search for 0xDEADC0DE
|
||||
"search lc2 def" - search lang bank2 (and lang card) for 0xDEF
|
||||
|
||||
(b{reak} | w{atch}) {addr}
|
||||
br{eak} op <byte>
|
||||
(c{lear} | i{gnore}) {num}
|
||||
c{lear} op <byte>
|
||||
sta{tus} - show status of memory watch/breakpoints
|
||||
op{codes} - show opcodes that we're stopping at
|
||||
|
||||
"w c0e9" - watch memory at C0E9
|
||||
"br" - break at current PC
|
||||
"br op 20" - break on opcode 20
|
||||
"clear 1" - clear breakpoint 1
|
||||
"ig" - ignore all watchpoints
|
||||
"cl op 20" - clear break on opcode 20
|
||||
|
||||
-break or watch addrs. (use in conjunction with g{o})
|
||||
|
||||
-clear breakpoints, ignore watchpoints.
|
||||
|
||||
-show break and watchpoint status.
|
||||
|
||||
Note: breakpoints and watchpoints persist even when you exit the
|
||||
debugger console. They are only reset if you clear/ignore them or
|
||||
virtually reboot.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Loading and saving state:
|
||||
|
||||
bload <file> <addrs>
|
||||
bsave <file> /<bank>/<addrs> <len>
|
||||
|
||||
bload binary 8000 - load file into memory
|
||||
bsave pic /0/2000 2000 - save memory to file
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Miscellaneous:
|
||||
|
||||
fr{esh} - clear screen of graphics
|
12
TODO
Normal file
12
TODO
Normal file
@ -0,0 +1,12 @@
|
||||
Obviously this emulator could use extension. We could do with support
|
||||
for more disk-image formats, additional interface cards, memory-image
|
||||
save/restore, and other things.
|
||||
|
||||
However, most of these things would require hooking into parts of the code
|
||||
that are likely going to change radically in later versions of the
|
||||
emulator, due to badly needed cleanups. Thus, I do not recommend trying
|
||||
to extend this version alone.
|
||||
|
||||
If you want to work on the emulator, contact us first. We can give you alpha
|
||||
versions of the emulator to work on, and coordinate your efforts with
|
||||
other contributors.
|
12
acinclude.m4
Normal file
12
acinclude.m4
Normal file
@ -0,0 +1,12 @@
|
||||
dnl This was cribbed from GNU libc (notice the symbol choices), but highly
|
||||
dnl simplified since we can assume linking is working.
|
||||
dnl A2_ASM_UNDERSCORES
|
||||
AC_DEFUN(A2_ASM_UNDERSCORES,[
|
||||
AC_CACHE_CHECK(for _ prefix on C symbol names, a2_cv_asm_underscores,
|
||||
[AC_TRY_LINK([asm ("_glibc_foobar:");], [glibc_foobar ();],
|
||||
a2_cv_asm_underscores=yes,
|
||||
a2_cv_asm_underscores=no)])
|
||||
if test $a2_cv_asm_underscores = no; then
|
||||
AC_DEFINE(NO_UNDERSCORES)
|
||||
fi
|
||||
])
|
117
aclocal.m4
vendored
Normal file
117
aclocal.m4
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
dnl aclocal.m4 generated automatically by aclocal 1.4
|
||||
|
||||
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
dnl PARTICULAR PURPOSE.
|
||||
|
||||
dnl This was cribbed from GNU libc (notice the symbol choices), but highly
|
||||
dnl simplified since we can assume linking is working.
|
||||
dnl A2_ASM_UNDERSCORES
|
||||
AC_DEFUN(A2_ASM_UNDERSCORES,[
|
||||
AC_CACHE_CHECK(for _ prefix on C symbol names, a2_cv_asm_underscores,
|
||||
[AC_TRY_LINK([asm ("_glibc_foobar:");], [glibc_foobar ();],
|
||||
a2_cv_asm_underscores=yes,
|
||||
a2_cv_asm_underscores=no)])
|
||||
if test $a2_cv_asm_underscores = no; then
|
||||
AC_DEFINE(NO_UNDERSCORES)
|
||||
fi
|
||||
])
|
||||
|
||||
# Do all the work for Automake. This macro actually does too much --
|
||||
# some checks are only needed if your package does certain things.
|
||||
# But this isn't really a big deal.
|
||||
|
||||
# serial 1
|
||||
|
||||
dnl Usage:
|
||||
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
|
||||
|
||||
AC_DEFUN(AM_INIT_AUTOMAKE,
|
||||
[AC_REQUIRE([AC_PROG_INSTALL])
|
||||
PACKAGE=[$1]
|
||||
AC_SUBST(PACKAGE)
|
||||
VERSION=[$2]
|
||||
AC_SUBST(VERSION)
|
||||
dnl test to see if srcdir already configured
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
ifelse([$3],,
|
||||
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
|
||||
AC_REQUIRE([AM_SANITY_CHECK])
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])
|
||||
dnl FIXME This is truly gross.
|
||||
missing_dir=`cd $ac_aux_dir && pwd`
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
|
||||
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])])
|
||||
|
||||
#
|
||||
# Check to make sure that the build environment is sane.
|
||||
#
|
||||
|
||||
AC_DEFUN(AM_SANITY_CHECK,
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftestfile
|
||||
# Do `set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
|
||||
if test "[$]*" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t $srcdir/configure conftestfile`
|
||||
fi
|
||||
if test "[$]*" != "X $srcdir/configure conftestfile" \
|
||||
&& test "[$]*" != "X conftestfile $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
|
||||
test "[$]2" = conftestfile
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
rm -f conftest*
|
||||
AC_MSG_RESULT(yes)])
|
||||
|
||||
dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
|
||||
dnl The program must properly implement --version.
|
||||
AC_DEFUN(AM_MISSING_PROG,
|
||||
[AC_MSG_CHECKING(for working $2)
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||
if ($2 --version) < /dev/null > /dev/null 2>&1; then
|
||||
$1=$2
|
||||
AC_MSG_RESULT(found)
|
||||
else
|
||||
$1="$3/missing $2"
|
||||
AC_MSG_RESULT(missing)
|
||||
fi
|
||||
AC_SUBST($1)])
|
||||
|
35
configure.in
Normal file
35
configure.in
Normal file
@ -0,0 +1,35 @@
|
||||
AC_INIT(src/apple2.h)
|
||||
AM_INIT_AUTOMAKE(apple2-emul, 0.7.4)
|
||||
|
||||
AC_PROG_CC
|
||||
|
||||
AC_CHECK_HEADER(linux/joystick.h, [
|
||||
AC_DEFINE(PC_JOYSTICK)
|
||||
JOYSTICK_O=joystick.o])
|
||||
|
||||
AC_ARG_ENABLE(debugger, [ --enable-debugger Single-step, &c. support],[
|
||||
AC_DEFINE(DEBUGGER)
|
||||
DEBUGGER_O="debug.o debugger.o opcodes.o"])
|
||||
|
||||
AC_FUNC_MMAP
|
||||
A2_ASM_UNDERSCORES
|
||||
|
||||
AC_PATH_XTRA
|
||||
|
||||
if test -z $no_x
|
||||
then
|
||||
PROGS="xapple2 xapple2-80col"
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(vga,vga_init,PROGS="$PROGS apple2")
|
||||
|
||||
# unconditionally enabling //e support. No reason to do without it, IMO
|
||||
AC_DEFINE(APPLE_IIE)
|
||||
AC_DEFINE(MAX_APPLE_DELAY,1000)
|
||||
|
||||
AC_SUBST(JOYSTICK_O)
|
||||
AC_SUBST(DEBUGGER_O)
|
||||
AC_SUBST(PROGS)
|
||||
|
||||
AC_OUTPUT([Makefile src/Makefile disks/Makefile])
|
||||
|
5
disks/Makefile.am
Normal file
5
disks/Makefile.am
Normal file
@ -0,0 +1,5 @@
|
||||
# we may want to change this to pkgdata_DATA, to automatically install
|
||||
# the disk images.
|
||||
|
||||
EXTRA_DIST = README blank.dsk.gz blank.nib.gz etc.dsk.gz mystery.dsk.gz \
|
||||
speedtest.dsk.gz speedtest.txt
|
173
disks/Makefile.in
Normal file
173
disks/Makefile.in
Normal file
@ -0,0 +1,173 @@
|
||||
# Makefile.in generated automatically by automake 1.4 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# we may want to change this to pkgdata_DATA, to automatically install
|
||||
# the disk images.
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
CC = @CC@
|
||||
DEBUGGER_O = @DEBUGGER_O@
|
||||
JOYSTICK_O = @JOYSTICK_O@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
PACKAGE = @PACKAGE@
|
||||
PROGS = @PROGS@
|
||||
VERSION = @VERSION@
|
||||
|
||||
EXTRA_DIST = README blank.dsk.gz blank.nib.gz etc.dsk.gz mystery.dsk.gz speedtest.dsk.gz speedtest.txt
|
||||
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_CLEAN_FILES =
|
||||
DIST_COMMON = README Makefile.am Makefile.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps disks/Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
|
||||
subdir = disks
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
info-am:
|
||||
info: info-am
|
||||
dvi-am:
|
||||
dvi: dvi-am
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
installcheck-am:
|
||||
installcheck: installcheck-am
|
||||
install-exec-am:
|
||||
install-exec: install-exec-am
|
||||
|
||||
install-data-am:
|
||||
install-data: install-data-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-am
|
||||
uninstall-am:
|
||||
uninstall: uninstall-am
|
||||
all-am: Makefile
|
||||
all-redirect: all-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs:
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
mostlyclean-am: mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
clean-am: clean-generic mostlyclean-am
|
||||
|
||||
clean: clean-am
|
||||
|
||||
distclean-am: distclean-generic clean-am
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
maintainer-clean-am: maintainer-clean-generic distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
.PHONY: tags distdir info-am info dvi-am dvi check check-am \
|
||||
installcheck-am installcheck install-exec-am install-exec \
|
||||
install-data-am install-data install-am install uninstall-am uninstall \
|
||||
all-redirect all-am all installdirs mostlyclean-generic \
|
||||
distclean-generic clean-generic maintainer-clean-generic clean \
|
||||
mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
22
disks/README
Normal file
22
disks/README
Normal file
@ -0,0 +1,22 @@
|
||||
Sample Disk Images
|
||||
------ ---- ------
|
||||
|
||||
These disk images are merely distributed with the emulator and are not
|
||||
actually part of it. (ie: not subject to GPL, and not written by us.)
|
||||
|
||||
Many more disk images (including ones we'd never include here due to
|
||||
copyright considerations) may be found on ftp.apple.asimov.net.
|
||||
|
||||
blank.dsk.gz -
|
||||
blank.nib.gz -
|
||||
Blank DOS3.3-formatted disk images.
|
||||
|
||||
etc.dsk.gz -
|
||||
A disk with miscellaneous programs, and apparently an assembler.
|
||||
|
||||
mystery.dsk.gz -
|
||||
Sierra's old Mystery House game, now freely distributable.
|
||||
|
||||
speedtest.dsk.gz -
|
||||
William Night's emulator benchmarks.
|
||||
|
BIN
disks/blank.dsk.gz
Normal file
BIN
disks/blank.dsk.gz
Normal file
Binary file not shown.
BIN
disks/blank.nib.gz
Normal file
BIN
disks/blank.nib.gz
Normal file
Binary file not shown.
BIN
disks/etc.dsk.gz
Normal file
BIN
disks/etc.dsk.gz
Normal file
Binary file not shown.
BIN
disks/mystery.dsk.gz
Normal file
BIN
disks/mystery.dsk.gz
Normal file
Binary file not shown.
BIN
disks/speedtest.dsk.gz
Normal file
BIN
disks/speedtest.dsk.gz
Normal file
Binary file not shown.
74
disks/speedtest.txt
Normal file
74
disks/speedtest.txt
Normal file
@ -0,0 +1,74 @@
|
||||
From: wnight@cafe.net (William Night)
|
||||
Newsgroups: comp.emulators.apple2
|
||||
Subject: Speed Test Results
|
||||
Date: 22 Apr 1995 11:19:31 GMT
|
||||
Organization: Cafe.Net Internet Access System
|
||||
Lines: 63
|
||||
Message-ID: <3naoo3$9q1@scipio.cyberstore.ca>
|
||||
NNTP-Posting-Host: espresso.cafe.net
|
||||
X-Newsreader: TIN [version 1.2 PL2]
|
||||
|
||||
These are the latest results from SpeedTest 2.2.2
|
||||
|
||||
AplWin2 Sim2e Apl2em-2 Applemu
|
||||
Test
|
||||
CPU-Index 6.472 3.155 8.532 11.47
|
||||
TEXT-Index 2.629 0.1957 4.470 6.274
|
||||
VIDEO-Index 1.388 0.1957 3.990 5.271
|
||||
DISK-Index 3.297 0.4715 5.690 0.9626
|
||||
|
||||
I will post the results from all the tests as soon as I get around to
|
||||
typing it in. These highlight the actual strengths and weaknesses of
|
||||
each emulator and are usefull in figuring out how fast an emulator will
|
||||
run a certain class of programs.
|
||||
|
||||
The tests used will remain the same for each minor version level. All
|
||||
patch-level changes 2.2.x etc will just be to the main program and the
|
||||
results will be the same as all other patch levels with the same major
|
||||
and minor versions. For example the results for 2.2.2 and 2.2.8 will be
|
||||
the same, while the results between 2.2.2 and 2.3.2 are not gauranteed
|
||||
to be.
|
||||
|
||||
These results were obtained on a 486dx4/100 with 4-Dos and QEMM loaded,
|
||||
the AplWin tests were performed in Windows 3.1 with the appropriate
|
||||
Win32 extensions added. I have a cirrus logic 5426 1MB VLB card
|
||||
installed.
|
||||
|
||||
My system tests out at 195.7 in Sysinfo from Norton. I don't have any
|
||||
Video benchmarks that are common enough that the results would mean
|
||||
anything (see #1 below)
|
||||
|
||||
A few comments about the results.
|
||||
|
||||
1) Until I get a benchmark program for the machine the emulator is
|
||||
running on that all people involved can agree on, test results do not mean
|
||||
anything between platforms or even between two of the same type of machines
|
||||
running at different speeds. The only way the results should be used is to
|
||||
compare the relative speeds of two emulators on the same machine.
|
||||
|
||||
2) The relative speeds compared to a //e do not mean that the emulator
|
||||
will perform that quickly or slowly on a video game or other
|
||||
application, for example, Sim2e appears to be very slow, but plays games
|
||||
quite well on my machine. The tests are very intensive in a specific
|
||||
area, where most programs are more general in their use of system
|
||||
resources.
|
||||
|
||||
3) These tests aren't completely fair. The CPU tests are for the most
|
||||
part, but differences in the way an emulator is implemented make certain
|
||||
things automatically faster or slower. For instance, both Apl2em-2 and
|
||||
Applemu use IBM text for the apple text screen, therefore all text
|
||||
operations are handled by the IBM graphics card, both Sim2e and AplWin2
|
||||
do their own translation of text to graphics (and achieve a much more
|
||||
realistic looking screen). With the video tests, Applemu will only do
|
||||
black-and-white high-res graphics. This gives it an unfair advantage
|
||||
over the others.
|
||||
|
||||
|
||||
Any suggestions for the next version of speed-test or comments or
|
||||
questions are welcome.
|
||||
|
||||
The new version of SpeedTest will be posted in the next message, and will
|
||||
probably make it's way onto an FTP site soon.
|
||||
|
||||
|
||||
|
250
install-sh
Executable file
250
install-sh
Executable file
@ -0,0 +1,250 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||
#
|
||||
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||
#
|
||||
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||
# documentation for any purpose is hereby granted without fee, provided that
|
||||
# the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting
|
||||
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||
# publicity pertaining to distribution of the software without specific,
|
||||
# written prior permission. M.I.T. makes no representations about the
|
||||
# suitability of this software for any purpose. It is provided "as is"
|
||||
# without express or implied warranty.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
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
|
188
missing
Executable file
188
missing
Executable file
@ -0,0 +1,188 @@
|
||||
#! /bin/sh
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
|
||||
error status if there is no known handling for PROGRAM.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal touch file \`aclocal.m4'
|
||||
autoconf touch file \`configure'
|
||||
autoheader touch file \`config.h.in'
|
||||
automake touch all \`Makefile.in' files
|
||||
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
flex create \`lex.yy.c', if possible, from existing .c
|
||||
lex create \`lex.yy.c', if possible, from existing .c
|
||||
makeinfo touch the output file
|
||||
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing - GNU libit 0.0"
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: Unknown \`$1' option"
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aclocal)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified \`acinclude.m4' or \`configure.in'. You might want
|
||||
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||
any GNU archive site."
|
||||
touch aclocal.m4
|
||||
;;
|
||||
|
||||
autoconf)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified \`configure.in'. You might want to install the
|
||||
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||
archive site."
|
||||
touch configure
|
||||
;;
|
||||
|
||||
autoheader)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified \`acconfig.h' or \`configure.in'. You might want
|
||||
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||
from any GNU archive site."
|
||||
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER([^):]*:\([^)]*\)).*/\1/p' configure.in`
|
||||
if test -z "$files"; then
|
||||
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^):]*\)).*/\1/p' configure.in`
|
||||
test -z "$files" || files="$files.in"
|
||||
else
|
||||
files=`echo "$files" | sed -e 's/:/ /g'`
|
||||
fi
|
||||
test -z "$files" && files="config.h.in"
|
||||
touch $files
|
||||
;;
|
||||
|
||||
automake)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
|
||||
You might want to install the \`Automake' and \`Perl' packages.
|
||||
Grab them from any GNU archive site."
|
||||
find . -type f -name Makefile.am -print \
|
||||
| sed 's/^\(.*\).am$/touch \1.in/' \
|
||||
| sh
|
||||
;;
|
||||
|
||||
bison|yacc)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified a \`.y' file. You may need the \`Bison' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Bison' from any GNU archive site."
|
||||
rm -f y.tab.c y.tab.h
|
||||
if [ $# -ne 1 ]; then
|
||||
eval LASTARG="\${$#}"
|
||||
case "$LASTARG" in
|
||||
*.y)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" y.tab.c
|
||||
fi
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" y.tab.h
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f y.tab.h ]; then
|
||||
echo >y.tab.h
|
||||
fi
|
||||
if [ ! -f y.tab.c ]; then
|
||||
echo 'main() { return 0; }' >y.tab.c
|
||||
fi
|
||||
;;
|
||||
|
||||
lex|flex)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified a \`.l' file. You may need the \`Flex' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Flex' from any GNU archive site."
|
||||
rm -f lex.yy.c
|
||||
if [ $# -ne 1 ]; then
|
||||
eval LASTARG="\${$#}"
|
||||
case "$LASTARG" in
|
||||
*.l)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" lex.yy.c
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f lex.yy.c ]; then
|
||||
echo 'main() { return 0; }' >lex.yy.c
|
||||
fi
|
||||
;;
|
||||
|
||||
makeinfo)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||
indirectly affecting the aspect of the manual. The spurious
|
||||
call might also be the consequence of using a buggy \`make' (AIX,
|
||||
DU, IRIX). You might want to install the \`Texinfo' package or
|
||||
the \`GNU make' package. Grab either from any GNU archive site."
|
||||
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||
if test -z "$file"; then
|
||||
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
|
||||
fi
|
||||
touch $file
|
||||
;;
|
||||
|
||||
*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
||||
system. You might have modified some files without having the
|
||||
proper tools for further handling them. Check the \`README' file,
|
||||
it often tells you about the needed prerequirements for installing
|
||||
this package. You may also peek at any GNU archive site, in case
|
||||
some other package would contain this missing \`$1' program."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
40
mkinstalldirs
Executable file
40
mkinstalldirs
Executable file
@ -0,0 +1,40 @@
|
||||
#! /bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Public domain
|
||||
|
||||
# $Id: mkinstalldirs,v 1.10 1996/05/03 07:37:52 friedman Exp $
|
||||
|
||||
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" 1>&2
|
||||
|
||||
mkdir "$pathcomp" || lasterr=$?
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
errstatus=$lasterr
|
||||
fi
|
||||
fi
|
||||
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# mkinstalldirs ends here
|
77
src/Makefile.am
Normal file
77
src/Makefile.am
Normal file
@ -0,0 +1,77 @@
|
||||
noinst_HEADERS = apple2.h debug.h disk.h interface.h keys.h misc.h \
|
||||
video.h cpu.h glue.h gluepro.h prefs.h
|
||||
|
||||
SUFFIXES = .l-cpp -80.o
|
||||
|
||||
man_MANS = apple2.6
|
||||
|
||||
EXTRA_PROGRAMS = apple2 xapple2 xapple2-80col
|
||||
bin_PROGRAMS = @PROGS@
|
||||
|
||||
EXTRA_apple2_SOURCES = debugger.c opcodes.c debug.c joystick.c
|
||||
apple2_SOURCES = cpu.S memory.S display.S glue.S keys.c prefs.c disk.c \
|
||||
interface.c misc.c font.c svideo.c compact.c cpu-supp.c \
|
||||
vidsup.c
|
||||
|
||||
apple2_LDADD = @DEBUGGER_O@ @JOYSTICK_O@ -lvga
|
||||
apple2_DEPENDENCIES = @DEBUGGER_O@ @JOYSTICK_O@
|
||||
|
||||
EXTRA_xapple2_SOURCES = debugger.c opcodes.c debug.c joystick.c
|
||||
|
||||
xapple2_SOURCES = cpu.S memory.S display.S glue.S keys.c prefs.c \
|
||||
disk.c interface.c misc.c font.c xvideo.c compact.c \
|
||||
cpu-supp.c vidsup.c
|
||||
|
||||
xapple2_LDADD = @DEBUGGER_O@ @JOYSTICK_O@ @X_LIBS@ -lX11 -lXext
|
||||
xapple2_DEPENDENCIES = @DEBUGGER_O@ @JOYSTICK_O@
|
||||
|
||||
EXTRA_xapple2_80col_SOURCES = debugger.c opcodes.c debug.c joystick.c
|
||||
|
||||
xapple2_80col_SOURCES = cpu.S memory.S glue.S keys.c prefs.c disk.c \
|
||||
font.c compact.c cpu-supp.c misc.c interface.c
|
||||
|
||||
xapple2_80col_LDADD = @DEBUGGER_O@ @JOYSTICK_O@ \
|
||||
vidsup-80.o xvideo-80.o display-80.o \
|
||||
@X_LIBS@ -lX11 -lXext
|
||||
xapple2_80col_DEPENDENCIES = @DEBUGGER_O@ @JOYSTICK_O@ \
|
||||
vidsup-80.o xvideo-80.o display-80.o
|
||||
|
||||
noinst_PROGRAMS = genfont
|
||||
|
||||
BUILT_SOURCES = font.c debug.c glue.S
|
||||
|
||||
EXTRA_DIST = font.txt apple2.6 debug.l-cpp genglue
|
||||
|
||||
CLEANFILES = font.c debug.c glue.S
|
||||
|
||||
# Warning: this will trip on a cross-compile
|
||||
# (not that we're otherwise portable to non-Linux yet...)
|
||||
font.c : font.txt genfont
|
||||
./genfont < $< > $@
|
||||
|
||||
glue.S : disk.c misc.c
|
||||
$(srcdir)/genglue $^ > $@
|
||||
|
||||
%-80.o: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) -D_640x400 -c -o $@ $<
|
||||
|
||||
display-80.o: display.S
|
||||
$(CC) $(CPPFLAGS) $(DEFS) -D_640x400 -c -o $@ $<
|
||||
|
||||
# I couldn't get Automake's internal Lex support to work with this, as
|
||||
# Automake assumes the program was built to cope with no -P option. These
|
||||
# files require it and also need preprocessing.
|
||||
#
|
||||
# Of course this is really our fault for being nonportable to standard Lex...
|
||||
# (which I presume has no -P)
|
||||
|
||||
%.c: %.l-cpp
|
||||
$(CC) -x c -E -P $(CPPFLAGS) $(DEFS) $< | flex -i -P$* -o$@
|
||||
|
||||
|
||||
# Another hack. I can't see any other way to get across to automake that some
|
||||
# built sources should not be distributed. (since they vary with
|
||||
# configuration)
|
||||
|
||||
dist-hook:
|
||||
rm -f $(distdir)/font.c $(distdir)/debug.c $(distdir)/glue.S
|
433
src/Makefile.in
Normal file
433
src/Makefile.in
Normal file
@ -0,0 +1,433 @@
|
||||
# Makefile.in generated automatically by automake 1.4 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
CC = @CC@
|
||||
DEBUGGER_O = @DEBUGGER_O@
|
||||
JOYSTICK_O = @JOYSTICK_O@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
PACKAGE = @PACKAGE@
|
||||
PROGS = @PROGS@
|
||||
VERSION = @VERSION@
|
||||
|
||||
noinst_HEADERS = apple2.h debug.h disk.h interface.h keys.h misc.h video.h cpu.h glue.h gluepro.h prefs.h
|
||||
|
||||
|
||||
SUFFIXES = .l-cpp -80.o
|
||||
|
||||
man_MANS = apple2.6
|
||||
|
||||
EXTRA_PROGRAMS = apple2 xapple2 xapple2-80col
|
||||
bin_PROGRAMS = @PROGS@
|
||||
|
||||
EXTRA_apple2_SOURCES = debugger.c opcodes.c debug.c joystick.c
|
||||
apple2_SOURCES = cpu.S memory.S display.S glue.S keys.c prefs.c disk.c interface.c misc.c font.c svideo.c compact.c cpu-supp.c vidsup.c
|
||||
|
||||
|
||||
apple2_LDADD = @DEBUGGER_O@ @JOYSTICK_O@ -lvga
|
||||
apple2_DEPENDENCIES = @DEBUGGER_O@ @JOYSTICK_O@
|
||||
|
||||
EXTRA_xapple2_SOURCES = debugger.c opcodes.c debug.c joystick.c
|
||||
|
||||
xapple2_SOURCES = cpu.S memory.S display.S glue.S keys.c prefs.c disk.c interface.c misc.c font.c xvideo.c compact.c cpu-supp.c vidsup.c
|
||||
|
||||
|
||||
xapple2_LDADD = @DEBUGGER_O@ @JOYSTICK_O@ @X_LIBS@ -lX11 -lXext
|
||||
xapple2_DEPENDENCIES = @DEBUGGER_O@ @JOYSTICK_O@
|
||||
|
||||
EXTRA_xapple2_80col_SOURCES = debugger.c opcodes.c debug.c joystick.c
|
||||
|
||||
xapple2_80col_SOURCES = cpu.S memory.S glue.S keys.c prefs.c disk.c font.c compact.c cpu-supp.c misc.c interface.c
|
||||
|
||||
|
||||
xapple2_80col_LDADD = @DEBUGGER_O@ @JOYSTICK_O@ vidsup-80.o xvideo-80.o display-80.o @X_LIBS@ -lX11 -lXext
|
||||
|
||||
xapple2_80col_DEPENDENCIES = @DEBUGGER_O@ @JOYSTICK_O@ vidsup-80.o xvideo-80.o display-80.o
|
||||
|
||||
|
||||
noinst_PROGRAMS = genfont
|
||||
|
||||
BUILT_SOURCES = font.c debug.c glue.S
|
||||
|
||||
EXTRA_DIST = font.txt apple2.6 debug.l-cpp genglue
|
||||
|
||||
CLEANFILES = font.c debug.c glue.S
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_CLEAN_FILES =
|
||||
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
|
||||
|
||||
|
||||
DEFS = @DEFS@ -I. -I$(srcdir)
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
X_CFLAGS = @X_CFLAGS@
|
||||
X_LIBS = @X_LIBS@
|
||||
X_EXTRA_LIBS = @X_EXTRA_LIBS@
|
||||
X_PRE_LIBS = @X_PRE_LIBS@
|
||||
apple2_OBJECTS = cpu.o memory.o display.o glue.o keys.o prefs.o disk.o \
|
||||
interface.o misc.o font.o svideo.o compact.o cpu-supp.o vidsup.o
|
||||
apple2_LDFLAGS =
|
||||
xapple2_OBJECTS = cpu.o memory.o display.o glue.o keys.o prefs.o disk.o \
|
||||
interface.o misc.o font.o xvideo.o compact.o cpu-supp.o vidsup.o
|
||||
xapple2_LDFLAGS =
|
||||
xapple2_80col_OBJECTS = cpu.o memory.o glue.o keys.o prefs.o disk.o \
|
||||
font.o compact.o cpu-supp.o misc.o interface.o
|
||||
xapple2_80col_LDFLAGS =
|
||||
genfont_SOURCES = genfont.c
|
||||
genfont_OBJECTS = genfont.o
|
||||
genfont_LDADD = $(LDADD)
|
||||
genfont_DEPENDENCIES =
|
||||
genfont_LDFLAGS =
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
man6dir = $(mandir)/man6
|
||||
MANS = $(man_MANS)
|
||||
|
||||
NROFF = nroff
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
|
||||
DIST_COMMON = Makefile.am Makefile.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
SOURCES = $(apple2_SOURCES) $(EXTRA_apple2_SOURCES) $(xapple2_SOURCES) $(EXTRA_xapple2_SOURCES) $(xapple2_80col_SOURCES) $(EXTRA_xapple2_80col_SOURCES) genfont.c
|
||||
OBJECTS = $(apple2_OBJECTS) $(xapple2_OBJECTS) $(xapple2_80col_OBJECTS) genfont.o
|
||||
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: -80.o .S .c .l-cpp .o .s
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
||||
mostlyclean-binPROGRAMS:
|
||||
|
||||
clean-binPROGRAMS:
|
||||
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
|
||||
|
||||
distclean-binPROGRAMS:
|
||||
|
||||
maintainer-clean-binPROGRAMS:
|
||||
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-binPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
|
||||
done
|
||||
|
||||
mostlyclean-noinstPROGRAMS:
|
||||
|
||||
clean-noinstPROGRAMS:
|
||||
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
|
||||
|
||||
distclean-noinstPROGRAMS:
|
||||
|
||||
maintainer-clean-noinstPROGRAMS:
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.s.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.S.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.o core *.core
|
||||
|
||||
clean-compile:
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
maintainer-clean-compile:
|
||||
|
||||
apple2: $(apple2_OBJECTS) $(apple2_DEPENDENCIES)
|
||||
@rm -f apple2
|
||||
$(LINK) $(apple2_LDFLAGS) $(apple2_OBJECTS) $(apple2_LDADD) $(LIBS)
|
||||
|
||||
xapple2: $(xapple2_OBJECTS) $(xapple2_DEPENDENCIES)
|
||||
@rm -f xapple2
|
||||
$(LINK) $(xapple2_LDFLAGS) $(xapple2_OBJECTS) $(xapple2_LDADD) $(LIBS)
|
||||
|
||||
xapple2-80col: $(xapple2_80col_OBJECTS) $(xapple2_80col_DEPENDENCIES)
|
||||
@rm -f xapple2-80col
|
||||
$(LINK) $(xapple2_80col_LDFLAGS) $(xapple2_80col_OBJECTS) $(xapple2_80col_LDADD) $(LIBS)
|
||||
|
||||
genfont: $(genfont_OBJECTS) $(genfont_DEPENDENCIES)
|
||||
@rm -f genfont
|
||||
$(LINK) $(genfont_LDFLAGS) $(genfont_OBJECTS) $(genfont_LDADD) $(LIBS)
|
||||
|
||||
install-man6:
|
||||
$(mkinstalldirs) $(DESTDIR)$(man6dir)
|
||||
@list='$(man6_MANS)'; \
|
||||
l2='$(man_MANS)'; for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.6*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
|
||||
else file=$$i; fi; \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man6dir)/$$inst"; \
|
||||
$(INSTALL_DATA) $$file $(DESTDIR)$(man6dir)/$$inst; \
|
||||
done
|
||||
|
||||
uninstall-man6:
|
||||
@list='$(man6_MANS)'; \
|
||||
l2='$(man_MANS)'; for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.6*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " rm -f $(DESTDIR)$(man6dir)/$$inst"; \
|
||||
rm -f $(DESTDIR)$(man6dir)/$$inst; \
|
||||
done
|
||||
install-man: $(MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-man6
|
||||
uninstall-man:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
$(MAKE) $(AM_MAKEFLAGS) uninstall-man6
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
here=`pwd` && cd $(srcdir) \
|
||||
&& mkid -f$$here/ID $$unique $(LISP)
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|
||||
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
|
||||
subdir = src
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
$(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
|
||||
info-am:
|
||||
info: info-am
|
||||
dvi-am:
|
||||
dvi: dvi-am
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
installcheck-am:
|
||||
installcheck: installcheck-am
|
||||
install-exec-am: install-binPROGRAMS
|
||||
install-exec: install-exec-am
|
||||
|
||||
install-data-am: install-man
|
||||
install-data: install-data-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-am
|
||||
uninstall-am: uninstall-binPROGRAMS uninstall-man
|
||||
uninstall: uninstall-am
|
||||
all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS)
|
||||
all-redirect: all-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man6
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \
|
||||
mostlyclean-compile mostlyclean-tags \
|
||||
mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-compile \
|
||||
clean-tags clean-generic mostlyclean-am
|
||||
|
||||
clean: clean-am
|
||||
|
||||
distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \
|
||||
distclean-compile distclean-tags distclean-generic \
|
||||
clean-am
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
maintainer-clean-am: maintainer-clean-binPROGRAMS \
|
||||
maintainer-clean-noinstPROGRAMS \
|
||||
maintainer-clean-compile maintainer-clean-tags \
|
||||
maintainer-clean-generic distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
|
||||
maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
|
||||
mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
|
||||
clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
|
||||
mostlyclean-compile distclean-compile clean-compile \
|
||||
maintainer-clean-compile install-man6 uninstall-man6 install-man \
|
||||
uninstall-man tags mostlyclean-tags distclean-tags clean-tags \
|
||||
maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
|
||||
installcheck-am installcheck install-exec-am install-exec \
|
||||
install-data-am install-data install-am install uninstall-am uninstall \
|
||||
all-redirect all-am all installdirs mostlyclean-generic \
|
||||
distclean-generic clean-generic maintainer-clean-generic clean \
|
||||
mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# Warning: this will trip on a cross-compile
|
||||
# (not that we're otherwise portable to non-Linux yet...)
|
||||
font.c : font.txt genfont
|
||||
./genfont < $< > $@
|
||||
|
||||
glue.S : disk.c misc.c
|
||||
$(srcdir)/genglue $^ > $@
|
||||
|
||||
%-80.o: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) -D_640x400 -c -o $@ $<
|
||||
|
||||
display-80.o: display.S
|
||||
$(CC) $(CPPFLAGS) $(DEFS) -D_640x400 -c -o $@ $<
|
||||
|
||||
# I couldn't get Automake's internal Lex support to work with this, as
|
||||
# Automake assumes the program was built to cope with no -P option. These
|
||||
# files require it and also need preprocessing.
|
||||
#
|
||||
# Of course this is really our fault for being nonportable to standard Lex...
|
||||
# (which I presume has no -P)
|
||||
|
||||
%.c: %.l-cpp
|
||||
$(CC) -x c -E -P $(CPPFLAGS) $(DEFS) $< | flex -i -P$* -o$@
|
||||
|
||||
# Another hack. I can't see any other way to get across to automake that some
|
||||
# built sources should not be distributed. (since they vary with
|
||||
# configuration)
|
||||
|
||||
dist-hook:
|
||||
rm -f $(distdir)/font.c $(distdir)/debug.c $(distdir)/glue.S
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
301
src/apple2.6
Normal file
301
src/apple2.6
Normal file
@ -0,0 +1,301 @@
|
||||
.\" Apple ][ emulator manpage
|
||||
.\" by Aaron Culliney - chernabog@baldmountain.bbn.com - (C) 1997-1998
|
||||
.\"
|
||||
.\" apple2.6 - manpage which mostly echos README
|
||||
.\"
|
||||
.\" $Id: apple2.6,v 1.8 1998/08/25 03:00:00 chernabog Exp $
|
||||
.\"
|
||||
.\" MODIFICATION HISTORY
|
||||
.\" v0.5 by Aaron Culliney <chernabog@baldmountain.bbn.com>, Feb 1998.
|
||||
.\" v0.6 by Aaron Culliney <chernabog@baldmountain.bbn.com>, Aug 1998.
|
||||
.\" This code has nothing to do with my employer, GTE Internetworking,
|
||||
.\" BBN Technologies. It was written completely on my own time and on
|
||||
.\" my own machine.
|
||||
.\"
|
||||
.TH APPLE2 6 "31 August 1998"
|
||||
.UC 7
|
||||
.SH NAME
|
||||
apple2, xapple2 \- Apple ][+ and //e emulator
|
||||
.SH SYNOPSIS
|
||||
.ft B
|
||||
apple2
|
||||
.PP
|
||||
.ft B
|
||||
xapple2 [ -noshm ]
|
||||
.ft R
|
||||
.SH DESCRIPTION
|
||||
.I apple2
|
||||
(svgalib) and
|
||||
.I xapple2
|
||||
(X11) both emulate a 64k Apple ][+ and 128k Apple //e computer (the latter
|
||||
only if //e support
|
||||
compiled in). To use the emulator you need to acquire the original
|
||||
][+ and //e ROM files which are not distributed due to copyright
|
||||
reasons. The emulator reads standard 143360-byte and 232960-byte disk
|
||||
image files with
|
||||
.I .dsk
|
||||
and
|
||||
.I .nib
|
||||
suffixes respectively.
|
||||
You can also change any images with the extension
|
||||
.I .do
|
||||
to
|
||||
.I .dsk
|
||||
and they will work too.
|
||||
.PP
|
||||
There are only a few command line options:
|
||||
.TP
|
||||
.I -noshm
|
||||
This forces the X11 version to not use the MITSHM extension. This may degrade
|
||||
the speed of the emulator but allow you to run it remote.
|
||||
.PP
|
||||
.ft R
|
||||
.SH THE .apple2 FILE
|
||||
The emulator reads user preferences from a
|
||||
.I .apple2
|
||||
file located in your home directory. Copy the
|
||||
.I .apple2
|
||||
file that comes distributed with the emulator to your home directory.
|
||||
You can edit the settings using your favorite editor, but most of the
|
||||
settings can be tweaked from within the emulator (see menus section below).
|
||||
.TP
|
||||
.I speed
|
||||
Speed of emulation, 1 - XXX. (Actually this is an inverse delay-loop counter). 1 is
|
||||
slow, and XXX is as fast as can be.
|
||||
A delay loop is needed to bring the emulation rate down to near what would be
|
||||
considered a normal Apple ][ speed.
|
||||
The max speed value should be determined by
|
||||
.I YOU
|
||||
when you compile the emulator.
|
||||
For <= 100Mhz Pentium systems, I personally
|
||||
like a max value of 100 with a normal apple ][ speed somewhere in the 70s.
|
||||
For faster machines, try larger ranges.
|
||||
.TP
|
||||
.I mode
|
||||
Starting emulation mode. One of "][+", "][+ undocumented", "//e". You can
|
||||
also dynamically change the emulation mode from within the emulator.
|
||||
.TP
|
||||
.I disk path
|
||||
Toplevel path of disk images directory. Personally I like
|
||||
/usr/local/games/apple2/disks.
|
||||
.TP
|
||||
.I color
|
||||
Black/white, lazy color, color, lazy interpolated, interpolated.
|
||||
.TP
|
||||
.I sound
|
||||
Off, pc speaker.
|
||||
.TP
|
||||
.I joystick
|
||||
Off, linear, pc joystick.
|
||||
.TP
|
||||
.I joystick range
|
||||
2 - 256. Range of the joystick values. Good settings are 256 and
|
||||
sometimes 128, with centers at 128 and 64 respectively. This often depends on
|
||||
the game.
|
||||
.TP
|
||||
.I origin_x
|
||||
X coordinate origin. 128 is good for many games with a range of 256. Others
|
||||
like 64 with a range of 128.
|
||||
.TP
|
||||
.I origin_y
|
||||
Y coordinate origin. 128 is good for many games with a range of 256. Others
|
||||
like 64 with a range of 128.
|
||||
.TP
|
||||
.I pc joystick parms
|
||||
You can configure this from within the emulator. Select the 'Calibrate'
|
||||
option from the F10 menu. If the emulator complains that
|
||||
it cannot open the joystick device, make sure the module is loaded.
|
||||
.I This option is only valid if you've compiled the emulator with -DPC_JOYSTICK.
|
||||
.TP
|
||||
.I sensitivity
|
||||
1% - 100%. This value is used for the emulated joystick using the
|
||||
numeric keypad.
|
||||
.TP
|
||||
.I system path
|
||||
The directory holding the rom files. The emulator won't run if this
|
||||
is not set properly. You can only change this by editing the
|
||||
.I .apple2
|
||||
file.
|
||||
.PP
|
||||
So here is an example .apple2 file:
|
||||
.nf
|
||||
speed = 72
|
||||
mode = ][+
|
||||
disk path = /usr/local/games/apple2/disks
|
||||
color = interpolated
|
||||
sound = pc speaker
|
||||
joystick = pc joystick
|
||||
joystick range = 256
|
||||
origin_x = 128
|
||||
origin_y = 128
|
||||
pc joystick parms = 767 693 1344 28 1454 28 13
|
||||
sensitivity = 13%
|
||||
system path = /usr/local/games/apple2/rom
|
||||
.fi
|
||||
.PP
|
||||
.ft R
|
||||
.SH ROM FILES
|
||||
The emulator requires several ROM files to run.
|
||||
.TP
|
||||
.I apple_II.rom
|
||||
You need this file for basic ][+ emulation. It contains the 12K ROM
|
||||
of your Apple ][+. It is not distributed due to copyright issues, so
|
||||
you have to get this file on your own. If you have been running
|
||||
another apple2 emulator, you can most likely use its ROM files
|
||||
directly. This file is a memory dump of the consecutive addresses
|
||||
from D000 to FFFF of the Apple ][+. This file may also be named
|
||||
.I apple.rom
|
||||
or
|
||||
.I apple2.rom,
|
||||
but is referenced internally as
|
||||
.I apple_II.rom.
|
||||
.TP
|
||||
.I slot6.rom
|
||||
You need this file for basic disk drive emulation. It is 256 byte
|
||||
memory dump of the consecutive addresses from C600 to C6FF. This file
|
||||
is not distributed again due to copyright issues. This file may also
|
||||
be named
|
||||
.I controller.rom,
|
||||
but is referenced internally as
|
||||
.I slot6.rom.
|
||||
.TP
|
||||
.I apple_IIe.rom
|
||||
If //e support was not compiled into the emulator, then you do not need this
|
||||
file.
|
||||
It is the 32K ROM of your 128k Apple //e, a dump of main memory (bank 0)
|
||||
addresses C000-FFFF concatenated with auxiliary memory (bank 1)
|
||||
addresses C000-FFFF. Because the
|
||||
.I apple_IIe.rom
|
||||
contains the C600 slot, you can construct the
|
||||
.I slot6.rom
|
||||
file from this one. The
|
||||
.I apple_IIe.rom
|
||||
file may also be named
|
||||
.I apple2e.rom
|
||||
but is referenced internally as
|
||||
.I apple_IIe.rom.
|
||||
.TP
|
||||
.I character.rom
|
||||
A 2048 byte ][+ character rom file. This file is distributed with the
|
||||
emulator.
|
||||
.PP
|
||||
.ft R
|
||||
.SH DISK IMAGES
|
||||
The emulator reads standard DOS3.3-order 143360 byte '.dsk' images and
|
||||
raw-nibble 232960 byte '.nib' images. The emulator can handle images
|
||||
which are gzip'ed as long as the suffixes are '.dsk.gz' and '.nib.gz'
|
||||
respectively. The emulator simply assumes that /bin/gzip is available
|
||||
to compress/decompress these images in place as needed and that you have
|
||||
permission to do so.
|
||||
.PP
|
||||
The images are raw binary dumps, containing the tracks from 0 to 34
|
||||
from the original 5.25 disk. For the standard 143360 byte '.dsk'
|
||||
format each track is partitioned into sectors of 256 bytes, numbered
|
||||
from 0 to 15.
|
||||
.PP
|
||||
The raw nibblized 232960-byte images are usually made of
|
||||
programs that have non-standard formatting as a means of copy
|
||||
protection. The nibblized format attempts to preserve the
|
||||
non-standard format, and so defeats the copy protection without
|
||||
"cracking" the program.
|
||||
.PP
|
||||
To transfer Apple ][ diskettes into one of these formats requires that
|
||||
you own an original Apple ][. Since the drives provided by the IBM
|
||||
PC's are not compatible with the original Apple ][ drives there are no
|
||||
conversion programs directly available. If you have used other Apple
|
||||
][ emulators it is most likely that the files will work with this
|
||||
emulator too. For more information on Apple ][ disk formats and such,
|
||||
see
|
||||
.I Beneath Apple DOS
|
||||
by Don Worth and Pieter Lechner, published long ago by Quality Software.
|
||||
.PP
|
||||
.ft R
|
||||
.SH EMULATOR KEYS/MENUS
|
||||
.TP
|
||||
.I F1
|
||||
Interface to switch disk in Drive A, Slot 6. Arrow keys navigate the
|
||||
selection. If the disk highlighted is already in the drive, it will
|
||||
have a <rw1> or <r1> tag after the name indicating read/write or
|
||||
read-only access. Select this disk to eject it. To select a disk,
|
||||
you can press 'w' or RETURN to insert it into the drive. Pressing 'w'
|
||||
will attempt to open the disk as read/write (if you have permission to
|
||||
do so).
|
||||
Pressing RETURN defaults to opening the disk read-only. Press
|
||||
ESC to accept current settings and exit the menu.
|
||||
.TP
|
||||
.I F2
|
||||
Interface to switch disk in Drive B, Slot 6. Same controls as for
|
||||
.I F1.
|
||||
.TP
|
||||
.I F4
|
||||
Pause the emulation. The Pause/Break key will also work. Hit a key
|
||||
to resume.
|
||||
.TP
|
||||
.I F5
|
||||
Display the Apple ][+ or //e keyboard layout.
|
||||
.TP
|
||||
.I F7
|
||||
Enter the Debugger console (if this support was compiled into the
|
||||
program). See the file DEBUGGER that came with the emulator for
|
||||
command information.
|
||||
.TP
|
||||
.I F9
|
||||
Toggles between maximum speed and configured speed. This is useful to 'fastboot'
|
||||
programs, and then slip back to normal Apple ][ speed.
|
||||
.TP
|
||||
.I F10
|
||||
General parameter settings menu, including the all-important QUIT option.
|
||||
You can edit most of the parameters in your
|
||||
.I .apple2
|
||||
file from this menu.
|
||||
Two options worth mentioning are
|
||||
the 'Calibrate' and 'JS Sample' options. 'Calibrate' lets you
|
||||
calibrate the PC Joystick device. 'JS Sample' lets you set the sample
|
||||
rate of the PC Joystick device. 'Save' lets you save the settings to
|
||||
your
|
||||
.I .apple2
|
||||
file.
|
||||
.TP
|
||||
.I Special Keys
|
||||
The key combination Ctrl-'PrintScrn/SysReq' will reboot the machine.
|
||||
The Ctrl-'Pause/Break' combination will reset the machine. Remember
|
||||
that 'Pause/Break' alone will pause emulation. AltLeft and AltRight
|
||||
keys correspond to the OpenApple and ClosedApple keys (joystick
|
||||
buttons 0 & 1). NOTE: In //e mode try Ctrl-AltRight-'Pause/Break'
|
||||
sequence for a system self-test. The numeric keypad is used for
|
||||
emulated joystick movement.
|
||||
.ft R
|
||||
.SH BUGS AND STUFF
|
||||
See the PROBLEMS file that came with the code.
|
||||
.PP
|
||||
Using the joystick for some disk images is problematic.
|
||||
Apparently there is a bug in Apple ]['s where reading values from the
|
||||
joystick ports too quickly results in a smaller value than normal.
|
||||
Unfortunately the emulator doesn't emulate this bug in the machine,
|
||||
but you can mostly get the same
|
||||
effect by changing the range of the joystick. For instance, games like Space
|
||||
Rogue and Airheart like a range of 0x80 with the center around 0x40. Most
|
||||
other games will like a range of 0x100 with the center around 0x80.
|
||||
.PP
|
||||
Under X, you may notice that some keys are not working as advertised
|
||||
(Pause/Break as reboot for instance). Make sure that these keys are mapped.
|
||||
(Run xmodmap -pke for the current mapping).
|
||||
.ft R
|
||||
.SH MORE INFO
|
||||
More information is available in the online newsgroups
|
||||
.I comp.emulators.apple2,
|
||||
and
|
||||
.I comp.sys.apple2.
|
||||
.PP
|
||||
See also:
|
||||
.TP
|
||||
.I Apple //e Technical Reference Manual
|
||||
.TP
|
||||
.I Beneath Apple DOS
|
||||
.TP
|
||||
.I Beneath Apple ProDOS
|
||||
.ft R
|
||||
.SH AUTHORS
|
||||
Apple //e support and revisions v006, v005, v004, v003 by Aaron Culliney
|
||||
(aculline@bbn.com). Revision v002 by Stephen Lee. Original version(s)
|
||||
by Alexander Jean-Claude Bottema.
|
38
src/apple2.h
Normal file
38
src/apple2.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Common definitions
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef A2_H
|
||||
#define A2_H
|
||||
|
||||
#define BANK2 0x10000
|
||||
|
||||
/* Code alignment */
|
||||
#if defined(__i486__) || defined(__i586__)
|
||||
#define ALIGN .balign 16
|
||||
#else /* !(__i486__ || __i586__) */
|
||||
#define ALIGN .balign 4
|
||||
#endif /* !(__i486__ || __i586__) */
|
||||
|
||||
/* Symbol naming issues */
|
||||
#ifdef NO_UNDERSCORES
|
||||
#define SN(foo) foo
|
||||
#define E(foo) .globl foo ; ALIGN ; foo##:
|
||||
#else /* !NO_UNDERSCORES */
|
||||
#define SN(foo) _##foo
|
||||
#define E(foo) .globl _##foo ; ALIGN ; _##foo##:
|
||||
#endif /* !NO_UNDERSCORES */
|
||||
|
||||
#endif/* A2_H */
|
174
src/compact.c
Normal file
174
src/compact.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Memory optimizer
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/* This code is not essential to emulator operation. It (ab)uses the
|
||||
* virtual-memory system so that repetitive parts of the memory-access
|
||||
* indirection table are compressed. This should hopefully relieve load
|
||||
* on the processor's cache and boost speed.
|
||||
*
|
||||
* This file is far more complicated than it needs to be. For the present
|
||||
* purpose --- emulating an Apple // series machine on an 386 box --- I
|
||||
* could have hard-wired the compaction specifically for the Apple layout and
|
||||
* i386 page size.
|
||||
*
|
||||
* But it's more flexible - it needs no change to be used in an emulator
|
||||
* for Nintendo, C64, etc. Support for host processors with different
|
||||
* page sizes will just be matter of changing the PSIZE and TPAGES macros.
|
||||
*
|
||||
*/
|
||||
|
||||
#define TSIZE 524288 /* Size of the entire table */
|
||||
#define PSIZE 4096 /* Size of a page */
|
||||
#define TPAGES 128 /* pages in table */
|
||||
|
||||
#ifndef HAVE_MMAP
|
||||
|
||||
void precompact(void){}
|
||||
void compact(void){}
|
||||
|
||||
#else /* HAVE_MMAP */
|
||||
|
||||
static int compaction_file = -1;
|
||||
|
||||
void pre_compact(void)
|
||||
{
|
||||
const char *tmpdir;
|
||||
char *filename;
|
||||
char *x;
|
||||
|
||||
/* Destroy any old mapping file */
|
||||
close(compaction_file);
|
||||
|
||||
/* Reset the mapping on the table to normal, in case compaction has
|
||||
* been done before. This also tests if the kernel is advanced enough
|
||||
* to support this stunt.
|
||||
*/
|
||||
x = mmap((void *) cpu65_vmem,
|
||||
TSIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE,
|
||||
0,
|
||||
0);
|
||||
|
||||
if (x == MAP_FAILED)
|
||||
{
|
||||
/* mmap failed.
|
||||
* For now we assume this is because we are running on a system
|
||||
* which doesn't support cookie-cutter mmap operations.
|
||||
*
|
||||
* We set compaction_file to -1 and return. This tells compact to
|
||||
* do nothing. (The emu still works.)
|
||||
*/
|
||||
printf("System does not appear to support fancy mmap\n"
|
||||
"(error: %m)\n");
|
||||
|
||||
compaction_file = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a fresh new mapping file */
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (!tmpdir) tmpdir = "/tmp";
|
||||
filename = alloca(strlen(tmpdir) + 9);
|
||||
strcpy(filename,tmpdir);
|
||||
strcat(filename,"/a2-XXXXXX");
|
||||
compaction_file = mkstemp(filename);
|
||||
|
||||
if (!compaction_file)
|
||||
{
|
||||
fprintf(stderr,"cannot open temporary file (%m)\n");
|
||||
exit(EXIT_FAILURE);
|
||||
};
|
||||
|
||||
unlink(filename);
|
||||
ftruncate(compaction_file,TSIZE); /* might not be 100% portable */
|
||||
|
||||
/* If the ftruncate doesn't work (Single Unix does not require it
|
||||
* to work for the extending case), try this instead:
|
||||
*
|
||||
* lseek(compaction_file,TSIZE-1,SEEK_SET);
|
||||
* write(compaction_file,"",1);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void compact(void)
|
||||
{
|
||||
int i,j,n;
|
||||
char *work;
|
||||
char *x;
|
||||
|
||||
/* Give up if the first mmap didn't work out */
|
||||
if (compaction_file == -1) return;
|
||||
|
||||
work = mmap(0,
|
||||
TSIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_FILE|MAP_SHARED,
|
||||
compaction_file,
|
||||
0);
|
||||
|
||||
if (work == MAP_FAILED)
|
||||
{
|
||||
fprintf(stderr,"mmap failure (%m)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
n = 0;
|
||||
i = TPAGES;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
j = n;
|
||||
while (j-- && memcmp(work+j*PSIZE,
|
||||
((void *) cpu65_vmem)+i*PSIZE,
|
||||
PSIZE));
|
||||
if (j == -1)
|
||||
{
|
||||
memcpy(work+n*PSIZE,
|
||||
((void *) cpu65_vmem)+i*PSIZE,
|
||||
PSIZE);
|
||||
j = n++;
|
||||
}
|
||||
|
||||
x = mmap(((void *) cpu65_vmem)+i*PSIZE,
|
||||
PSIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_FIXED|MAP_FILE|MAP_SHARED,
|
||||
compaction_file,
|
||||
j*PSIZE);
|
||||
|
||||
if (work == MAP_FAILED)
|
||||
{
|
||||
fprintf(stderr,"mmap failure (%m)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
munmap(work,TSIZE);
|
||||
|
||||
}
|
||||
|
||||
#endif /* HAVE_MMAP */
|
88
src/cpu-supp.c
Normal file
88
src/cpu-supp.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: C support for 6502 on i386
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
/* different than in defs.h! */
|
||||
#define C_Flag_6502 0x1
|
||||
#define X_Flag_6502 0x20
|
||||
#define I_Flag_6502 0x4
|
||||
#define V_Flag_6502 0x40
|
||||
#define B_Flag_6502 0x10
|
||||
#define D_Flag_6502 0x8
|
||||
#define Z_Flag_6502 0x2
|
||||
#define N_Flag_6502 0x80
|
||||
|
||||
static void initialize_code_tables(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
unsigned char val = 0;
|
||||
|
||||
if (i & C_Flag)
|
||||
val |= C_Flag_6502;
|
||||
if (i & X_Flag)
|
||||
val |= X_Flag_6502;
|
||||
if (i & I_Flag)
|
||||
val |= I_Flag_6502;
|
||||
if (i & V_Flag)
|
||||
val |= V_Flag_6502;
|
||||
if (i & B_Flag)
|
||||
val |= B_Flag_6502;
|
||||
if (i & D_Flag)
|
||||
val |= D_Flag_6502;
|
||||
if (i & Z_Flag)
|
||||
val |= Z_Flag_6502;
|
||||
if (i & N_Flag)
|
||||
val |= N_Flag_6502;
|
||||
|
||||
cpu65_flags_encode[ i ] = val | 0x20;
|
||||
cpu65_flags_decode[ val ] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cpu65_set(int flags)
|
||||
{
|
||||
initialize_code_tables();
|
||||
|
||||
switch (flags & 0xf)
|
||||
{
|
||||
case CPU65_NMOS:
|
||||
if (flags & CPU65_FAULT)
|
||||
memcpy(cpu65__opcodes,cpu65__nmosbrk,1024);
|
||||
else
|
||||
memcpy(cpu65__opcodes,cpu65__nmos,1024);
|
||||
break;
|
||||
case CPU65_C02:
|
||||
memcpy(cpu65__opcodes,cpu65__cmos,1024);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
cpu65__signal = 0;
|
||||
}
|
||||
|
||||
void cpu65_interrupt(int reason)
|
||||
{
|
||||
cpu65__signal = reason;
|
||||
}
|
||||
|
131
src/cpu.h
Normal file
131
src/cpu.h
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Virtual 6502/65C02 interface
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <sys/types.h>
|
||||
|
||||
/* types */
|
||||
|
||||
typedef void *WMEM;
|
||||
typedef void *RMEM;
|
||||
|
||||
struct memory_vector
|
||||
{
|
||||
RMEM r;
|
||||
WMEM w;
|
||||
};
|
||||
|
||||
struct cpu65_state
|
||||
{
|
||||
u_int16_t pc; /* Program counter */
|
||||
u_int8_t a; /* Accumulator */
|
||||
u_int8_t f; /* Flags (order not same as in real 6502) */
|
||||
u_int8_t x,y; /* Index register */
|
||||
u_int8_t sp; /* Stack Pointer */
|
||||
};
|
||||
|
||||
struct cpu65_extra /* for debugging */
|
||||
{
|
||||
u_int16_t ea; /* Last effective address */
|
||||
u_int8_t d; /* Last data byte written */
|
||||
u_int8_t op; /* 1 = read occured, 2 = write, 3 = both */
|
||||
};
|
||||
|
||||
/* 6502 CPU models */
|
||||
#define CPU65_NMOS 0x0
|
||||
#define CPU65_C02 0x1
|
||||
|
||||
#define CPU65_FAULT 0x100 /* Undoc. opcodes are BRK */
|
||||
#define CPU65_SYNCHRO 0x200 /* Synchronize speed, not imp. */
|
||||
|
||||
/* Set up the processor for a new run. Sets up opcode table.
|
||||
*/
|
||||
extern void cpu65_set(int flags);
|
||||
|
||||
/* Interrupt the processor */
|
||||
extern void cpu65_interrupt(int reason);
|
||||
|
||||
extern void cpu65_run(void);
|
||||
|
||||
extern void cpu65_step(void);
|
||||
|
||||
extern void cpu65_direct_write(int ea,int data);
|
||||
|
||||
extern struct memory_vector cpu65_vmem[65536];
|
||||
extern struct cpu65_state cpu65_current;
|
||||
extern struct cpu65_extra cpu65_debug;
|
||||
|
||||
extern unsigned char cpu65_flags_encode[256];
|
||||
extern unsigned char cpu65_flags_decode[256];
|
||||
|
||||
extern unsigned int cpu65_delay;
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#define RebootSig 0x01
|
||||
#define ResetSig 0x02
|
||||
#define DebugStepSig 0x04
|
||||
#define EnterDebugSig 0x08
|
||||
|
||||
/* Note: These are *not* the bit positions used for the flags in the P
|
||||
* register of a real 6502. Rather, they have been distorted so that C,
|
||||
* N and Z match the analogous flags in the _80386_ flags register.
|
||||
*
|
||||
* Additionally, V matches the position of the overflow flag in the high byte
|
||||
* of the 80386 register.
|
||||
*
|
||||
*/
|
||||
#define C_Flag 0x1 /* 6502 Carry */
|
||||
#define X_Flag 0x2 /* 6502 Xtra */
|
||||
#define I_Flag 0x4 /* 6502 Interrupt disable */
|
||||
#define V_Flag 0x8 /* 6502 Overflow */
|
||||
#define B_Flag 0x10 /* 6502 Break */
|
||||
#define D_Flag 0x20 /* 6502 Decimal mode */
|
||||
#define Z_Flag 0x40 /* 6502 Zero */
|
||||
#define N_Flag 0x80 /* 6502 Neg */
|
||||
|
||||
#define C_Flag_Bit 8 /* 6502 Carry */
|
||||
#define X_Flag_Bit 9 /* 6502 Xtra */
|
||||
#define I_Flag_Bit 10 /* 6502 Interrupt disable */
|
||||
#define V_Flag_Bit 11 /* 6502 Overflow */
|
||||
#define B_Flag_Bit 12 /* 6502 Break */
|
||||
#define D_Flag_Bit 13 /* 6502 Decimal mode */
|
||||
#define Z_Flag_Bit 14 /* 6502 Zero */
|
||||
#define N_Flag_Bit 15 /* 6502 Neg */
|
||||
|
||||
#define X_Reg %bl /* 6502 X register in %bl */
|
||||
#define Y_Reg %bh /* 6502 Y register in %bh */
|
||||
#define A_Reg %cl /* 6502 A register in %cl */
|
||||
#define F_Reg %ch /* 6502 flags in %ch */
|
||||
#define FF_Reg %ecx /* 6502 flags for bt */
|
||||
#define SP_Reg %edx /* 6502 Stack pointer */
|
||||
#define SP_Reg_L %dl /* 6502 Stack pointer low */
|
||||
#define SP_Reg_H %dh /* 6502 Stack pointer high */
|
||||
#define PC_Reg %si /* 6502 Program Counter */
|
||||
#define PC_Reg_E %esi /* 6502 Program Counter */
|
||||
#define EffectiveAddr %di /* Effective address */
|
||||
#define EffectiveAddr_E %edi /* Effective address */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
/* Private data. */
|
||||
extern void *cpu65__opcodes[256];
|
||||
extern void *const cpu65__nmos[256];
|
||||
extern void *const cpu65__nmosbrk[256];
|
||||
extern void *const cpu65__cmos[256];
|
||||
|
||||
extern unsigned char cpu65__signal;
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
104
src/debug.h
Normal file
104
src/debug.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Definitions for debugger
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef A2_DEBUG_H
|
||||
#define A2_DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* debugger defines */
|
||||
#define BUF_X 39
|
||||
#define BUF_Y 22
|
||||
#define MAX_BRKPTS 16
|
||||
#define SCREEN_X 41
|
||||
#define SCREEN_Y 24
|
||||
#define PROMPT_X 2
|
||||
#define PROMPT_Y BUF_Y - 1
|
||||
#define PROMPT_END_X BUF_X - 2
|
||||
#define command_line command_buf[PROMPT_Y]
|
||||
#define uchar unsigned char
|
||||
|
||||
/* debugger commands */
|
||||
enum token_type { MEM, DIS, REGS, SETMEM, STEP, FINISH, UNTIL, GO, VM,
|
||||
BREAK, WATCH, CLEAR, IGNORE, STATUS, OPCODES, LC, DRIVE,
|
||||
SEARCH, HELP, LOG, BSAVE, BLOAD, SAVE, UNKNOWN };
|
||||
|
||||
enum addressing_mode
|
||||
{
|
||||
addr_implied,
|
||||
addr_accumulator,
|
||||
addr_immediate,
|
||||
addr_zeropage,
|
||||
addr_zeropage_x,
|
||||
addr_zeropage_y,
|
||||
addr_absolute,
|
||||
addr_absolute_x,
|
||||
addr_absolute_y,
|
||||
addr_indirect,
|
||||
addr_indirect_x,
|
||||
addr_indirect_y,
|
||||
addr_j_indirect, /* non-zeropage indirects, used in JMP only */
|
||||
addr_j_indirect_x,
|
||||
addr_relative
|
||||
};
|
||||
|
||||
struct opcode_struct
|
||||
{
|
||||
const char *mnemonic;
|
||||
enum addressing_mode mode;
|
||||
};
|
||||
|
||||
extern const struct opcode_struct *opcodes;
|
||||
|
||||
extern int step_next; /* stepping over instructions */
|
||||
extern char second_buf[BUF_Y][BUF_X]; /* scratch buffer for output */
|
||||
extern int num_buffer_lines; /* num lines of output */
|
||||
extern int arg1, arg2, arg3; /* command arguments */
|
||||
extern int breakpoints[MAX_BRKPTS]; /* memory breakpoints */
|
||||
extern int watchpoints[MAX_BRKPTS]; /* memory watchpoints */
|
||||
|
||||
void clear_debugger_screen();
|
||||
void bload(FILE*, char*, int);
|
||||
void show_misc_info();
|
||||
unsigned char get_current_opcode();
|
||||
void dump_mem(int, int, int, int, int);
|
||||
void search_mem(char*, int, int);
|
||||
void set_mem(int, char*);
|
||||
void set_lc_mem(int, int, char*);
|
||||
void disasm(int, int, int, int);
|
||||
void clear_halt(int*, int);
|
||||
void set_halt(int*, int);
|
||||
void show_breakpts();
|
||||
void show_regs();
|
||||
void display_help();
|
||||
void show_lc_info();
|
||||
void show_disk_info();
|
||||
void c_do_step(int);
|
||||
int at_haltpt();
|
||||
void end_step();
|
||||
void set_halt_opcode(unsigned char opcode);
|
||||
void set_halt_65c02();
|
||||
void clear_halt_65c02();
|
||||
void clear_halt_opcode(unsigned char opcode);
|
||||
void show_opcode_breakpts();
|
||||
|
||||
extern const struct opcode_struct opcodes_6502[256];
|
||||
extern const struct opcode_struct opcodes_65c02[256];
|
||||
extern const struct opcode_struct opcodes_undoc[256];
|
||||
extern const char * const disasm_templates[15];
|
||||
|
||||
#endif
|
901
src/debug.l-cpp
Normal file
901
src/debug.l-cpp
Normal file
@ -0,0 +1,901 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Lexer for debugger
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
/* ASSUMPTIONS:
|
||||
* flex version 2.5.2 or later
|
||||
*
|
||||
* this file is processed in several steps. the Makefile first
|
||||
* runs it through cpp so that we can eliminate whole rules which
|
||||
* are unnecessary. the generated file is then run through flex
|
||||
* to generate the actual c code which is then compiled.
|
||||
*
|
||||
*/
|
||||
|
||||
%{
|
||||
|
||||
/* process includes only the second time we parse this file. */
|
||||
#define INC(HASH,STR) HASH ## include STR
|
||||
INC(#,"misc.h")
|
||||
INC(#,"interface.h")
|
||||
INC(#,"debug.h")
|
||||
INC(#,"disk.h")
|
||||
INC(#,"video.h")
|
||||
INC(#,"keys.h")
|
||||
INC(#,<unistd.h>)
|
||||
INC(#,<strings.h>)
|
||||
INC(#,<ctype.h>)
|
||||
INC(#,"cpu.h")
|
||||
|
||||
|
||||
YY_BUFFER_STATE buffer = 0;
|
||||
|
||||
/*
|
||||
d{is} {lc1|lc2} {/bank/}{addr} {+}{len}
|
||||
m{em} {lc1|lc2} {/bank/}{addr} {+}{len}
|
||||
a{scii} {lc1|lc2} {/bank/}{addr} {+}{len}
|
||||
r{egs}
|
||||
<addr> {lc1|lc2} : <byteseq>
|
||||
bload <file> <addrs>
|
||||
bsave <file> /<bank>/<addrs> <len>
|
||||
(s{tep} | n{ext}) {len}
|
||||
f{inish}
|
||||
u{ntil}
|
||||
g{o} {addr}
|
||||
sea{rch} {lc1|lc2} <bytes>
|
||||
(b{reak} | w{atch}) {addr}
|
||||
(b{reak} | w{atch}) {addr}
|
||||
b{reak} op <byte>
|
||||
(c{lear} | i{gnore}) {num}
|
||||
c{lear} op <byte>
|
||||
key <byte>
|
||||
sta{tus}
|
||||
l{ang}
|
||||
dr{ive}
|
||||
vm
|
||||
fr{esh}
|
||||
(? | h{elp})
|
||||
*/
|
||||
|
||||
%}
|
||||
|
||||
|
||||
DEC [0-9]
|
||||
HEX [0-9a-fA-F]
|
||||
WS [\n\r\t" "]
|
||||
CHAR [^\n\r\t" "]
|
||||
BOS ^
|
||||
EOS {WS}*\0
|
||||
BANK \/0?[01]\/
|
||||
ADDRS [0-9a-fA-F]+
|
||||
|
||||
|
||||
%%
|
||||
|
||||
|
||||
|
||||
{BOS}(me?m?|as?c?i?i?){WS}+{ADDRS}{WS}\+?+{HEX}+{EOS} {
|
||||
/* mem <addrs> <len> */
|
||||
int do_ascii = 0;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = strtol(debugtext, &debugtext, 16);
|
||||
dump_mem(arg1, arg2, 0, do_ascii, -1);
|
||||
return MEM;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}(me?m?|as?c?i?i?){WS}+{BANK}{ADDRS}{WS}+\+?{HEX}+{EOS} {
|
||||
/* mem /<bank>/<addrs> <len> */
|
||||
int do_ascii = 0;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = strtol(debugtext, &debugtext, 16);
|
||||
dump_mem(arg1, arg2, 0, do_ascii, arg3);
|
||||
return MEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}(me?m?|as?c?i?i?){WS}+{ADDRS}{EOS} {
|
||||
/* mem <addrs> */
|
||||
int do_ascii = 0;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
dump_mem(arg1, 256, 0, do_ascii, -1);
|
||||
return MEM;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}(me?m?|as?c?i?i?){WS}+{BANK}{ADDRS}{EOS} {
|
||||
/* mem /<bank>/<addrs> */
|
||||
int do_ascii = 0;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
dump_mem(arg1, 256, 0, do_ascii, arg3);
|
||||
return MEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}(me?m?|as?c?i?i?){WS}+\+{HEX}+{EOS} {
|
||||
/* mem +<len> */
|
||||
int do_ascii = 0;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (*debugtext != '+') ++debugtext;
|
||||
++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
dump_mem(cpu65_current.pc, arg1, 0, do_ascii, -1);
|
||||
return MEM;
|
||||
}
|
||||
|
||||
{BOS}(me?m?|as?c?i?i?){EOS} {
|
||||
/* dump mem from current location */
|
||||
int do_ascii = 0;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
dump_mem(cpu65_current.pc, 256, 0, do_ascii, -1);
|
||||
return MEM;
|
||||
}
|
||||
|
||||
{BOS}(me?m?|as?c?i?i?){WS}*(lc?1|lc?2){WS}+{ADDRS}{WS}+\+?{HEX}+{EOS} {
|
||||
/* dump mem from lc<bank> <addrs> <len> */
|
||||
int do_ascii = 0;
|
||||
int lc;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
dump_mem(arg1, arg2, lc, do_ascii, -1);
|
||||
return MEM;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}(me?m?|as?c?i?i?){WS}*(lc?1|lc?2){WS}+{BANK}{ADDRS}{WS}+\+?{HEX}+{EOS} {
|
||||
/* dump mem from lc<bank> /<bank>/<addrs> <len> */
|
||||
int do_ascii = 0;
|
||||
int lc;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
dump_mem(arg1, arg2, lc, do_ascii, arg3);
|
||||
return MEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}(me?m?|as?c?i?i?){WS}*(lc?1|lc?2){WS}+{ADDRS}{EOS} {
|
||||
/* dump mem from lc<bank> <addrs> */
|
||||
int do_ascii = 0;
|
||||
int lc;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
dump_mem(arg1, 256, lc, do_ascii, -1);
|
||||
return MEM;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}(me?m?|as?c?i?i?){WS}*(lc?1|lc?2){WS}+{BANK}{ADDRS}{EOS} {
|
||||
/* dump mem from lc<bank> /<bank>/<addrs> */
|
||||
int do_ascii = 0;
|
||||
int lc;
|
||||
|
||||
if (tolower(debugtext[0]) == 'a')
|
||||
do_ascii = 1;
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
dump_mem(arg1, 256, lc, do_ascii, arg3);
|
||||
return MEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}di?s?{WS}+{ADDRS}{WS}+\+?{HEX}+{EOS} {
|
||||
/* disassemble at <addrs> <len> */
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
disasm(arg1, arg2, 0, -1);
|
||||
return DIS;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}di?s?{WS}+{BANK}{ADDRS}{WS}+\+?{HEX}+{EOS} {
|
||||
/* disassemble at /<bank>/<addrs> <len> */
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
disasm(arg1, arg2, 0, arg3);
|
||||
return DIS;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}di?s?{WS}+{ADDRS}{EOS} {
|
||||
/* disassemble at <addrs> */
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = 256;
|
||||
if ((arg1 < 0) || (arg1 > 65535)) arg1 = cpu65_current.pc;
|
||||
|
||||
disasm(arg1, arg2, 0, -1);
|
||||
return DIS;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}di?s?{WS}+{BANK}{ADDRS}{EOS} {
|
||||
/* disassemble at /<bank>/<addrs> */
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = 256;
|
||||
if ((arg1 < 0) || (arg1 > 65535)) arg1 = cpu65_current.pc;
|
||||
|
||||
disasm(arg1, arg2, 0, arg3);
|
||||
return DIS;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}di?s?{WS}+\+{HEX}+{EOS} {
|
||||
/* disassemble current location +<len> */
|
||||
while (*debugtext != '+') ++debugtext;
|
||||
++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
disasm(cpu65_current.pc, arg1, 0, -1);
|
||||
return DIS;
|
||||
}
|
||||
|
||||
{BOS}di?s?{EOS} {
|
||||
/* disassemble current location */
|
||||
disasm(cpu65_current.pc, 256, 0, -1);
|
||||
return DIS;
|
||||
}
|
||||
|
||||
{BOS}di?s?{WS}*(lc?1|lc?2){WS}+{ADDRS}{WS}+\+?{HEX}+{EOS} {
|
||||
/* disassemble language<bank> <addr> <len> */
|
||||
int lc;
|
||||
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
disasm(arg1, arg2, lc, -1);
|
||||
return DIS;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}di?s?{WS}*(lc?1|lc?2){WS}+{BANK}{ADDRS}{WS}+\+?{HEX}+{EOS} {
|
||||
/* disassemble language<bank> /<bank>/<addr> <len> */
|
||||
int lc;
|
||||
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
arg2 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
disasm(arg1, arg2, lc, arg3);
|
||||
return DIS;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}di?s?{WS}*(lc?1|lc?2){WS}+{ADDRS}{EOS} {
|
||||
/* disassemble language<bank> <addr> */
|
||||
int lc;
|
||||
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
disasm(arg1, 256, lc, -1);
|
||||
return DIS;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}di?s?{WS}*(lc?1|lc?2){WS}+{BANK}{ADDRS}{EOS} {
|
||||
/* disassemble language<bank> /<bank>/<addr> */
|
||||
int lc;
|
||||
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
disasm(arg1, 256, lc, arg3);
|
||||
return DIS;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}re?g?s?{EOS} {
|
||||
/* show cpu state */
|
||||
show_regs();
|
||||
return REGS;
|
||||
}
|
||||
|
||||
{BOS}{ADDRS}{WS}*\:{WS}*{HEX}+{EOS} {
|
||||
/* set memory <addr> : <hex string> */
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
while (*debugtext != ':') ++debugtext; ++debugtext;
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
|
||||
set_mem(arg1, debugtext);
|
||||
return SETMEM;
|
||||
}
|
||||
|
||||
{BOS}{ADDRS}{WS}*(lc1|lc2)\:{WS}*{HEX}+{EOS} {
|
||||
/* set LC memory <addr> lc1|lc2 : <hex string> */
|
||||
int lc;
|
||||
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; while (isspace(*debugtext)) ++debugtext;
|
||||
|
||||
set_lc_mem(arg1, lc, debugtext);
|
||||
return SETMEM;
|
||||
}
|
||||
|
||||
{BOS}bload{WS}+{CHAR}+{WS}+{ADDRS}{EOS} {
|
||||
/* bload <file> <addr> */
|
||||
FILE *fp = NULL;
|
||||
char *ptr = NULL;
|
||||
char name[128];
|
||||
int len = -1;
|
||||
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
ptr = debugtext;
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
len = debugtext-ptr;
|
||||
|
||||
/* filename */
|
||||
strncpy(name, ptr, len);
|
||||
name[len] = '\0';
|
||||
|
||||
/* bload addr */
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
arg1 = strtol(debugtext, (char**)NULL, 16);
|
||||
|
||||
fp = fopen(name, "r");
|
||||
if (fp == NULL) {
|
||||
sprintf(second_buf[num_buffer_lines++], "problem: %s", name);
|
||||
perror(name);
|
||||
return BLOAD;
|
||||
}
|
||||
|
||||
bload(fp, name, arg1);
|
||||
fclose(fp);
|
||||
return BLOAD;
|
||||
}
|
||||
|
||||
{BOS}(st?e?p?|ne?x?t?){EOS} {
|
||||
/* step / step next instruction */
|
||||
if (*debugtext == 'n') step_next = 1;
|
||||
|
||||
c_do_step(1);
|
||||
return STEP;
|
||||
}
|
||||
|
||||
{BOS}(st?e?p?|ne?x?t?){WS}+{HEX}+{EOS} {
|
||||
/* step / step next <n> instructions */
|
||||
if (*debugtext == 'n') step_next = 1;
|
||||
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, (char**)NULL, 16);
|
||||
if ((arg1 < 1) || (arg1 > 255)) arg1 = 255;
|
||||
|
||||
c_do_step(arg1);
|
||||
return STEP;
|
||||
}
|
||||
|
||||
{BOS}fi?n?i?s?h?{EOS} {
|
||||
int step_frame = 1;
|
||||
unsigned char op;
|
||||
|
||||
/* step until finished with curent stack frame */
|
||||
while ((c_mygetch(0) == -1) && !at_haltpt()) {
|
||||
op = get_current_opcode();
|
||||
|
||||
if (op == 0x20) ++step_frame; /* JSR */
|
||||
if (op == 0x60) --step_frame; /* RTS */
|
||||
|
||||
if (!step_frame) break; /* finished */
|
||||
cpu65_step();
|
||||
}
|
||||
end_step(); /* print location */
|
||||
return FINISH;
|
||||
}
|
||||
|
||||
{BOS}un?t?i?l?{EOS} {
|
||||
/* step until PC == next instruction. good for finishing backward
|
||||
loops */
|
||||
unsigned char op;
|
||||
int delta;
|
||||
op = get_current_opcode();
|
||||
|
||||
switch (opcodes[op].mode)
|
||||
{
|
||||
case addr_implied:
|
||||
case addr_accumulator:
|
||||
delta = 1;
|
||||
break;
|
||||
case addr_immediate:
|
||||
case addr_zeropage:
|
||||
case addr_zeropage_x:
|
||||
case addr_zeropage_y:
|
||||
case addr_indirect:
|
||||
case addr_indirect_x:
|
||||
case addr_indirect_y:
|
||||
case addr_relative:
|
||||
delta = 2;
|
||||
break;
|
||||
case addr_absolute:
|
||||
case addr_absolute_x:
|
||||
case addr_absolute_y:
|
||||
case addr_j_indirect:
|
||||
case addr_j_indirect_x:
|
||||
delta = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
arg1 = cpu65_current.pc + delta;
|
||||
|
||||
while ((cpu65_current.pc != arg1) && !at_haltpt() && (c_mygetch(0) == -1))
|
||||
cpu65_step();
|
||||
end_step(); /* print location */
|
||||
return UNTIL;
|
||||
}
|
||||
|
||||
{BOS}go?{WS}+{HEX}+{EOS} {
|
||||
/* jump to addrs and run while remaining in debugger console */
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
/* DANGEROUS! */
|
||||
cpu65_current.pc = strtol(debugtext, (char**)NULL, 16);
|
||||
while (!at_haltpt() && (c_mygetch(0) == -1))
|
||||
cpu65_step();
|
||||
end_step(); /* print location */
|
||||
return GO;
|
||||
}
|
||||
|
||||
{BOS}go?{EOS} {
|
||||
/* run while remaining in debugger console */
|
||||
while (!at_haltpt() && (c_mygetch(0) == -1))
|
||||
cpu65_step();
|
||||
end_step(); /* print location */
|
||||
return GO;
|
||||
}
|
||||
|
||||
{BOS}wa?t?c?h?{EOS} {
|
||||
/* set watchpoint */
|
||||
set_halt(watchpoints, cpu65_current.pc);
|
||||
return WATCH;
|
||||
}
|
||||
|
||||
{BOS}wa?t?c?h?{WS}+{HEX}+{EOS} {
|
||||
/* set watchpoint */
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, (char**)NULL, 16);
|
||||
if ((arg1 < 0) || (arg1 > 65535)) {
|
||||
sprintf(second_buf[num_buffer_lines++], "invalid address");
|
||||
return WATCH;
|
||||
}
|
||||
|
||||
set_halt(watchpoints, arg1);
|
||||
return WATCH;
|
||||
}
|
||||
|
||||
|
||||
{BOS}br?e?a?k?{EOS} {
|
||||
/* set breakpoint */
|
||||
set_halt(breakpoints, cpu65_current.pc);
|
||||
return BREAK;
|
||||
}
|
||||
|
||||
{BOS}br?e?a?k?{WS}+{HEX}+{EOS} {
|
||||
/* set breakpoint */
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, (char**)NULL, 16);
|
||||
if ((arg1 < 0) || (arg1 > 65535)) {
|
||||
sprintf(second_buf[num_buffer_lines++], "invalid address");
|
||||
return BREAK;
|
||||
}
|
||||
|
||||
set_halt(breakpoints, arg1);
|
||||
return BREAK;
|
||||
}
|
||||
|
||||
{BOS}br?e?a?k?{WS}*op{WS}+{HEX}+{EOS} {
|
||||
/* set breakpoint */
|
||||
while (!(*debugtext == 'p')) ++debugtext;
|
||||
++debugtext;
|
||||
|
||||
arg1 = strtol(debugtext, (char**)NULL, 16);
|
||||
if ((arg1 < 0) || (arg1 > 0xFF)) {
|
||||
sprintf(second_buf[num_buffer_lines++], "invalid opcode");
|
||||
return BREAK;
|
||||
}
|
||||
|
||||
set_halt_opcode((unsigned char)arg1);
|
||||
return BREAK;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}br65c02{EOS} {
|
||||
/* set opcode breakpoints on 65c02 instructions */
|
||||
set_halt_65c02();
|
||||
return BREAK;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}ig?n?o?r?e?{EOS} {
|
||||
/* ignore everything */
|
||||
clear_halt(watchpoints, 0);
|
||||
sprintf(second_buf[num_buffer_lines++], "ignored all");
|
||||
return IGNORE;
|
||||
}
|
||||
|
||||
{BOS}ig?n?o?r?e?({WS}+{DEC}+)+{EOS} {
|
||||
/* ignore <watchpt> ... */
|
||||
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
while (*debugtext) {
|
||||
arg1 = strtol(debugtext, &debugtext, 10);
|
||||
if ((arg1 < 1) || (arg1 > MAX_BRKPTS)) {
|
||||
sprintf(second_buf[num_buffer_lines++], "invalid watchpoint");
|
||||
return IGNORE;
|
||||
}
|
||||
clear_halt(watchpoints, arg1);
|
||||
sprintf(second_buf[num_buffer_lines++], "ignored %d", arg1);
|
||||
}
|
||||
return IGNORE;
|
||||
}
|
||||
|
||||
|
||||
{BOS}cl?e?a?r?{EOS} {
|
||||
/* clear everything */
|
||||
clear_halt(breakpoints, 0);
|
||||
sprintf(second_buf[num_buffer_lines++], "cleared all");
|
||||
return CLEAR;
|
||||
}
|
||||
|
||||
{BOS}cl?e?a?r?({WS}+{DEC}+)+{EOS} {
|
||||
/* clear <breakpt> ... */
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
|
||||
while (*debugtext) {
|
||||
arg1 = strtol(debugtext, &debugtext, 10);
|
||||
if ((arg1 < 1) || (arg1 > MAX_BRKPTS)) {
|
||||
sprintf(second_buf[num_buffer_lines++], "invalid breakpoint");
|
||||
return CLEAR;
|
||||
}
|
||||
clear_halt(breakpoints, arg1);
|
||||
sprintf(second_buf[num_buffer_lines++], "cleared %d", arg1);
|
||||
}
|
||||
return CLEAR;
|
||||
}
|
||||
|
||||
{BOS}cl?e?a?r?{WS}*op({WS}+{HEX}+)+{EOS} {
|
||||
/* clear <opcode breakpt> ... */
|
||||
while (!(*debugtext == 'p')) ++debugtext;
|
||||
++debugtext;
|
||||
|
||||
while (*debugtext) {
|
||||
arg1 = strtol(debugtext, &debugtext, 16);
|
||||
if ((arg1 < 0) || (arg1 > 255)) {
|
||||
sprintf(second_buf[num_buffer_lines++], "invalid opcode");
|
||||
return CLEAR;
|
||||
}
|
||||
clear_halt_opcode((unsigned char)arg1);
|
||||
sprintf(second_buf[num_buffer_lines++], "cleared opcode %02X",
|
||||
(unsigned char)arg1);
|
||||
}
|
||||
return CLEAR;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}cl65c02{EOS} {
|
||||
/* clear 65c02 ... */
|
||||
clear_halt_65c02();
|
||||
return CLEAR;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}stat?u?s?{EOS} {
|
||||
/* show breakpoints and watchpoints */
|
||||
show_breakpts();
|
||||
return STATUS;
|
||||
}
|
||||
|
||||
{BOS}opc?o?d?e?s?{EOS} {
|
||||
/* show opcode breakpoints */
|
||||
show_opcode_breakpts();
|
||||
return OPCODES;
|
||||
}
|
||||
|
||||
{BOS}sea?r?c?h?{WS}+{HEX}+{EOS} {
|
||||
/* search main memory for <bytes> */
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
|
||||
search_mem(debugtext, 0, -1);
|
||||
|
||||
return SEARCH;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}sea?r?c?h?{WS}+{BANK}{WS}+{HEX}+{EOS} {
|
||||
/* search memory<bank> for <bytes> */
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
|
||||
search_mem(debugtext, 0, arg3);
|
||||
|
||||
return SEARCH;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}sea?r?c?h?{WS}*(lc?1|lc?2){WS}+{HEX}+{EOS} {
|
||||
/* search LC<bank> for <bytes> */
|
||||
int lc;
|
||||
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
|
||||
search_mem(debugtext, lc, -1);
|
||||
|
||||
return SEARCH;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
{BOS}sea?r?c?h?{WS}*(lc?1|lc?2){WS}+{BANK}{WS}+{HEX}+{EOS} {
|
||||
/* search LC<bank> memory<bank> for <bytes> */
|
||||
int lc;
|
||||
|
||||
while (tolower(*debugtext) != 'l') ++debugtext; ++debugtext;
|
||||
if (tolower(*debugtext) == 'c') ++debugtext;
|
||||
lc = strtol(debugtext, &debugtext, 10);
|
||||
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext; /* after / */
|
||||
arg3 = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext; /* after / */
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
|
||||
search_mem(debugtext, lc, arg3);
|
||||
|
||||
return SEARCH;
|
||||
}
|
||||
#endif
|
||||
|
||||
{BOS}key{WS}+{HEX}+{EOS} {
|
||||
/* send key code to emulator */
|
||||
unsigned char key;
|
||||
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
key = (unsigned char) strtol(debugtext, &debugtext, 16);
|
||||
|
||||
apple_ii_64k[0][0xC000] = key;
|
||||
apple_ii_64k[1][0xC000] = key;
|
||||
}
|
||||
|
||||
{BOS}la?n?g?{EOS} {
|
||||
/* display language card settings */
|
||||
show_lc_info();
|
||||
return LC;
|
||||
}
|
||||
|
||||
{BOS}dri?v?e?{EOS} {
|
||||
/* show disk settings */
|
||||
show_disk_info();
|
||||
return DRIVE;
|
||||
}
|
||||
|
||||
{BOS}vm?{EOS} {
|
||||
/* show other VM softswitch settings */
|
||||
show_misc_info();
|
||||
return VM;
|
||||
}
|
||||
|
||||
{BOS}fre?s?h?{EOS} {
|
||||
/* refresh the screen */
|
||||
clear_debugger_screen();
|
||||
}
|
||||
|
||||
{BOS}(\?|he?l?p?){EOS} {
|
||||
display_help();
|
||||
return HELP;
|
||||
}
|
||||
|
||||
{BOS}bsave{WS}+{CHAR}+{WS}+{BANK}{ADDRS}{WS}+{HEX}+{EOS} {
|
||||
/* bsave <file> /<bank>/<addr> <len> */
|
||||
/* save memory dump to file */
|
||||
FILE *fp = NULL;
|
||||
char *ptr = NULL;
|
||||
int len, start, len2, bank;
|
||||
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
while (isspace(*debugtext)) ++debugtext;
|
||||
|
||||
/* copy file name */
|
||||
ptr = debugtext;
|
||||
while (!isspace(*debugtext)) ++debugtext;
|
||||
len = debugtext - ptr;
|
||||
strncpy(temp, ptr, len);
|
||||
temp[len] = '\0';
|
||||
|
||||
/* get bank info */
|
||||
while (*debugtext != '/') ++debugtext;
|
||||
++debugtext;
|
||||
bank = strtol(debugtext, &debugtext, 10);
|
||||
++debugtext;
|
||||
|
||||
/* extract start and len */
|
||||
start = strtol(debugtext, &debugtext, 16);
|
||||
len2 = strtol(debugtext, &debugtext, 16);
|
||||
|
||||
fp = fopen(temp, "w"); /* try to open file for writing */
|
||||
if (fp == NULL) {
|
||||
sprintf(second_buf[num_buffer_lines++], "problem: %s", temp);
|
||||
perror(temp);
|
||||
return BSAVE;
|
||||
}
|
||||
len = fwrite(apple_ii_64k[bank]+start, 1, len2, fp);
|
||||
if (len < len2) {
|
||||
sprintf(second_buf[num_buffer_lines++], "problem: %s", temp);
|
||||
perror(temp);
|
||||
fclose(fp);
|
||||
return BSAVE;
|
||||
}
|
||||
|
||||
sprintf(second_buf[num_buffer_lines++], "bsaved: %s", temp);
|
||||
fclose(fp);
|
||||
return BSAVE;
|
||||
}
|
||||
|
||||
{BOS}log{EOS} {
|
||||
/* log debugger output to file - not implemented */
|
||||
return LOG;
|
||||
}
|
||||
|
||||
{BOS}save{EOS} {
|
||||
/* save apple2 state to a .img file - not implemented I'd like to
|
||||
* be compatible with the applePC emulator's .img format. anyone
|
||||
* have documentation on this? -ASC
|
||||
**/
|
||||
return SAVE;
|
||||
}
|
||||
|
||||
|
||||
\n /* ignore newlines */
|
||||
|
||||
. /* ignore extraneous characters */
|
||||
|
||||
|
||||
%%
|
||||
|
||||
|
||||
int yywrap () {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* initialize the buffer - needed each time through */
|
||||
void init_lex (char *str, int size) {
|
||||
if (buffer) yy_delete_buffer(buffer);
|
||||
buffer = yy_scan_buffer(str, size);
|
||||
|
||||
if (!buffer) { /* oops */
|
||||
video_shutdown();
|
||||
printf("lex buffer not big enough\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
1135
src/debugger.c
Normal file
1135
src/debugger.c
Normal file
File diff suppressed because it is too large
Load Diff
671
src/disk.c
Normal file
671
src/disk.c
Normal file
@ -0,0 +1,671 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: C portion of Disk ][ emulation
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "disk.h"
|
||||
#include "misc.h"
|
||||
#include "cpu.h"
|
||||
#include "glue.h"
|
||||
#include "prefs.h"
|
||||
|
||||
#define PHASE_BYTES 3328
|
||||
|
||||
static unsigned char slot6_rom[256];
|
||||
static int slot6_rom_loaded = 0;
|
||||
|
||||
struct drive disk6;
|
||||
|
||||
static int skew_table_6[16] = /* Sector skew table */
|
||||
{ 0,7,14,6,13,5,12,4,11,3,10,2,9,1,8,15 };
|
||||
|
||||
static int translate_table_6[256] =/* Translation table */
|
||||
{
|
||||
0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
|
||||
0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
|
||||
0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
|
||||
0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3,
|
||||
0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
|
||||
0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec,
|
||||
0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
|
||||
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x01,
|
||||
0x80, 0x80, 0x02, 0x03, 0x80, 0x04, 0x05, 0x06,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x07, 0x08,
|
||||
0x80, 0x80, 0x80, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
|
||||
0x80, 0x80, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
|
||||
0x80, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x1b, 0x80, 0x1c, 0x1d, 0x1e,
|
||||
0x80, 0x80, 0x80, 0x1f, 0x80, 0x80, 0x20, 0x21,
|
||||
0x80, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x29, 0x2a, 0x2b,
|
||||
0x80, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
|
||||
0x80, 0x80, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
||||
0x80, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_init_6()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void c_init_6()
|
||||
{
|
||||
disk6.disk[0].phase = disk6.disk[1].phase = 42;
|
||||
disk6.disk[0].phase_change = disk6.disk[1].phase_change = 0;
|
||||
|
||||
disk6.motor = 1; /* motor on */
|
||||
disk6.drive = 0; /* first drive active */
|
||||
disk6.ddrw = 0;
|
||||
disk6.volume = 254;
|
||||
#if 0 /* BUGS!: */
|
||||
file_name_6[0][1024] = '\0';
|
||||
file_name_6[1][1024] = '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_eject_6() - assumes privileged access to image file (to re-gzip)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void c_eject_6(int drive) {
|
||||
pid_t pid;
|
||||
|
||||
if (disk6.disk[drive].compressed) {
|
||||
/* gzip the last disk if it was compressed_6 */
|
||||
if ((pid = fork())) { /* parent process */
|
||||
/* privileged mode - gzip in place */
|
||||
waitpid(pid, NULL, 0);
|
||||
} else if (!pid) { /* child process */
|
||||
/* privileged mode - gzip in place */
|
||||
if (execl("/bin/gzip", "/bin/gzip",
|
||||
disk6.disk[drive].file_name, NULL) == -1)
|
||||
{
|
||||
perror("Problem exec'ing /bin/gzip");
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
perror("Problem calling fork" );
|
||||
}
|
||||
}
|
||||
disk6.disk[drive].compressed = 0;
|
||||
disk6.disk[drive].nibblized = 0;
|
||||
sprintf(disk6.disk[drive].file_name, "%s", "");
|
||||
if (disk6.disk[drive].fp) {
|
||||
fclose(disk6.disk[drive].fp);
|
||||
disk6.disk[drive].fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_new_diskette_6( int drive, char *filename, Tr cmpr, Tr nib )
|
||||
inserts a new disk image into the appropriate drive. assumes
|
||||
privileged user level on entry, sets to the user when using disks.
|
||||
return 1 if we can't open an image file for reading.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int c_new_diskette_6(int drive, char *file_name, int cmpr, int nib, int force) {
|
||||
struct stat buf;
|
||||
|
||||
strcpy(disk6.disk[drive].file_name, file_name);
|
||||
disk6.disk[drive].compressed = cmpr;
|
||||
disk6.disk[drive].nibblized = nib;
|
||||
if (disk6.disk[drive].fp) {
|
||||
fclose(disk6.disk[drive].fp);
|
||||
disk6.disk[drive].fp = NULL;
|
||||
}
|
||||
/* set to users privilege level for disk access */
|
||||
|
||||
if (stat(disk6.disk[drive].file_name, &buf) < 0) {
|
||||
disk6.disk[drive].fp = NULL;
|
||||
c_eject_6(drive);
|
||||
return 1; /* problem: disk unreadable */
|
||||
}
|
||||
else {
|
||||
disk6.disk[drive].file_size = buf.st_size;
|
||||
|
||||
if (!force) {
|
||||
/* Open read only */
|
||||
disk6.disk[drive].fp = fopen(disk6.disk[drive].file_name, "r+");
|
||||
disk6.disk[drive].protected = 0;
|
||||
}
|
||||
if ((disk6.disk[drive].fp == NULL) || (force)) {
|
||||
/* Open for read AND write */
|
||||
disk6.disk[drive].fp = fopen(disk6.disk[drive].file_name, "r");
|
||||
disk6.disk[drive].protected = 1; /* disk is write protected! */
|
||||
}
|
||||
if (disk6.disk[drive].fp == NULL) {
|
||||
/* Failed to open file. */
|
||||
c_eject_6(drive);
|
||||
return 1; /* problem: disk unreadable */
|
||||
}
|
||||
/* seek to current head position. */
|
||||
fseek(disk6.disk[drive].fp, PHASE_BYTES * disk6.disk[drive].phase, SEEK_SET);
|
||||
}
|
||||
|
||||
disk6.disk[drive].sector = 0;
|
||||
disk6.disk[drive].run_byte = 0;
|
||||
|
||||
return 0; /* no problem */
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_read_nibblized_6_6() - reads a standard .nib file of length 232960 bytes.
|
||||
|
||||
there are 70 phases positioned every 3328 bytes.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
unsigned char c_read_nibblized_6_6()
|
||||
{
|
||||
static unsigned char ch;
|
||||
|
||||
if (disk6.disk[disk6.drive].phase_change) {
|
||||
fseek(disk6.disk[disk6.drive].fp, PHASE_BYTES * disk6.disk[disk6.drive].phase, SEEK_SET);
|
||||
disk6.disk[disk6.drive].phase_change = 0;
|
||||
}
|
||||
ch = (unsigned char) disk6.disk_byte = fgetc(disk6.disk[disk6.drive].fp);
|
||||
/* track revolves... */
|
||||
if (ftell(disk6.disk[disk6.drive].fp) == (PHASE_BYTES * (disk6.disk[disk6.drive].phase + 2)))
|
||||
fseek(disk6.disk[disk6.drive].fp, -2 * PHASE_BYTES, SEEK_CUR);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_read_normal_6()
|
||||
------------------------------------------------------------------------- */
|
||||
unsigned char c_read_normal_6()
|
||||
{
|
||||
int position;
|
||||
int old_value;
|
||||
|
||||
unsigned char value = 0;
|
||||
|
||||
/* The run byte tells what's to do */
|
||||
switch (disk6.disk[disk6.drive].run_byte)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5:
|
||||
case 20: case 21: case 22: case 23: case 24:
|
||||
/* Sync */
|
||||
value = 0xFF;
|
||||
break;
|
||||
|
||||
case 6: case 25:
|
||||
/* Prologue (first byte) */
|
||||
value = 0xD5;
|
||||
break;
|
||||
|
||||
case 7: case 26:
|
||||
/* Prologue (second byte) */
|
||||
value = 0xAA;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
/* Prologue (third byte) */
|
||||
value = 0x96;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
/* Volume (encoded) */
|
||||
value = (disk6.volume >> 1) | 0xAA;
|
||||
disk6.checksum = disk6.volume;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
/* Volume (encoded) */
|
||||
value = disk6.volume | 0xAA;
|
||||
break;
|
||||
|
||||
case 11:
|
||||
/* Track number (encoded) */
|
||||
disk6.checksum ^= (disk6.disk[disk6.drive].phase >> 1);
|
||||
value = (disk6.disk[disk6.drive].phase >> 2) | 0xAA;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
/* Track number (encoded) */
|
||||
value = (disk6.disk[disk6.drive].phase >> 1) | 0xAA;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
/* Sector number (encoded) */
|
||||
disk6.checksum ^= disk6.disk[disk6.drive].sector;
|
||||
value = (disk6.disk[disk6.drive].sector >> 1) | 0xAA;
|
||||
break;
|
||||
|
||||
case 14:
|
||||
/* Sector number (encoded) */
|
||||
value = disk6.disk[disk6.drive].sector | 0xAA;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
/* Checksum */
|
||||
value = (disk6.checksum >> 1) | 0xAA;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
/* Checksum */
|
||||
value = disk6.checksum | 0xAA;
|
||||
break;
|
||||
|
||||
case 17: case 371:
|
||||
/* Epilogue (first byte) */
|
||||
value = 0xDE;
|
||||
break;
|
||||
|
||||
case 18: case 372:
|
||||
/* Epilogue (second byte) */
|
||||
value = 0xAA;
|
||||
break;
|
||||
|
||||
case 19: case 373:
|
||||
/* Epilogue (third byte) */
|
||||
value = 0xEB;
|
||||
break;
|
||||
|
||||
case 27:
|
||||
/* Data header */
|
||||
disk6.exor_value = 0;
|
||||
|
||||
/* Set file position variable */
|
||||
disk6.disk[disk6.drive].file_pos = 256 * 16 * (disk6.disk[disk6.drive].phase >> 1) +
|
||||
256 * skew_table_6[ disk6.disk[disk6.drive].sector ];
|
||||
|
||||
/* File large enough? */
|
||||
if (disk6.disk[disk6.drive].file_pos + 255 > disk6.disk[disk6.drive].file_size)
|
||||
return 0xFF;
|
||||
|
||||
/* Set position */
|
||||
fseek( disk6.disk[disk6.drive].fp, disk6.disk[disk6.drive].file_pos, SEEK_SET );
|
||||
|
||||
/* Read sector */
|
||||
fread( disk6.disk_data, 1, 256, disk6.disk[disk6.drive].fp );
|
||||
disk6.disk_data[ 256 ] = disk6.disk_data[ 257 ] = 0;
|
||||
value = 0xAD;
|
||||
break;
|
||||
|
||||
case 370:
|
||||
/* Checksum */
|
||||
value = translate_table_6[disk6.exor_value & 0x3F];
|
||||
|
||||
/* Increment sector number (and wrap if necessary) */
|
||||
disk6.disk[disk6.drive].sector++;
|
||||
if (disk6.disk[disk6.drive].sector == 16)
|
||||
disk6.disk[disk6.drive].sector = 0;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
position = disk6.disk[disk6.drive].run_byte - 28;
|
||||
if (position >= 0x56)
|
||||
{
|
||||
position -= 0x56;
|
||||
old_value = disk6.disk_data[ position ];
|
||||
old_value = old_value >> 2;
|
||||
disk6.exor_value ^= old_value;
|
||||
value = translate_table_6[disk6.exor_value & 0x3F];
|
||||
disk6.exor_value = old_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
old_value = 0;
|
||||
old_value |= (disk6.disk_data[position] & 0x1) << 1;
|
||||
old_value |= (disk6.disk_data[position] & 0x2) >> 1;
|
||||
old_value |= (disk6.disk_data[position+0x56] & 0x1) << 3;
|
||||
old_value |= (disk6.disk_data[position+0x56] & 0x2) << 1;
|
||||
old_value |= (disk6.disk_data[position+0xAC] & 0x1) << 5;
|
||||
old_value |= (disk6.disk_data[position+0xAC] & 0x2) << 3;
|
||||
disk6.exor_value ^= old_value;
|
||||
value = translate_table_6[disk6.exor_value & 0x3F];
|
||||
disk6.exor_value = old_value;
|
||||
}
|
||||
break;
|
||||
} /* End switch */
|
||||
|
||||
/* Continue by increasing run byte value */
|
||||
disk6.disk[disk6.drive].run_byte++;
|
||||
if (disk6.disk[disk6.drive].run_byte > 373)
|
||||
disk6.disk[disk6.drive].run_byte = 0;
|
||||
|
||||
disk6.disk_byte = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_write_nibblized_6_6() - writes a standard .nib file of length 232960 bytes.
|
||||
|
||||
there are 70 phases positioned every 3328 bytes.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void c_write_nibblized_6_6()
|
||||
{
|
||||
if (disk6.disk[disk6.drive].phase_change) {
|
||||
fseek(disk6.disk[disk6.drive].fp, PHASE_BYTES * disk6.disk[disk6.drive].phase, SEEK_SET);
|
||||
disk6.disk[disk6.drive].phase_change = 0;
|
||||
}
|
||||
fputc(disk6.disk_byte, disk6.disk[disk6.drive].fp);
|
||||
/* track revolves... */
|
||||
if (ftell(disk6.disk[disk6.drive].fp) == (PHASE_BYTES * (disk6.disk[disk6.drive].phase + 2)))
|
||||
fseek(disk6.disk[disk6.drive].fp, -2 * PHASE_BYTES, SEEK_CUR);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_write_normal_6() disk6.disk_byte contains the value
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void c_write_normal_6()
|
||||
{
|
||||
int position;
|
||||
int old_value;
|
||||
|
||||
if (disk6.disk_byte == 0xD5)
|
||||
disk6.disk[disk6.drive].run_byte = 6; /* Initialize run byte value */
|
||||
|
||||
/* The run byte tells what's to do */
|
||||
|
||||
switch (disk6.disk[disk6.drive].run_byte)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5:
|
||||
case 20: case 21: case 22: case 23: case 24:
|
||||
/* Sync */
|
||||
break;
|
||||
|
||||
case 6: case 25:
|
||||
/* Prologue (first byte) */
|
||||
if (disk6.disk_byte == 0xFF)
|
||||
disk6.disk[disk6.drive].run_byte--;
|
||||
break;
|
||||
|
||||
case 7: case 26:
|
||||
/* Prologue (second byte) */
|
||||
break;
|
||||
|
||||
case 8:
|
||||
/* Prologue (third byte) */
|
||||
if (disk6.disk_byte == 0xAD)
|
||||
disk6.exor_value = 0, disk6.disk[disk6.drive].run_byte = 27;
|
||||
break;
|
||||
|
||||
case 9: case 10:
|
||||
/* Volume */
|
||||
break;
|
||||
|
||||
case 11: case 12:
|
||||
/* Track */
|
||||
break;
|
||||
|
||||
case 13: case 14:
|
||||
/* Sector */
|
||||
break;
|
||||
|
||||
case 15:
|
||||
/* Checksum */
|
||||
break;
|
||||
|
||||
case 16:
|
||||
/* Checksum */
|
||||
break;
|
||||
|
||||
case 17: case 371:
|
||||
/* Epilogue (first byte) */
|
||||
break;
|
||||
|
||||
case 18: case 372:
|
||||
/* Epilogue (second byte) */
|
||||
break;
|
||||
|
||||
case 19: case 373:
|
||||
/* Epilogue (third byte) */
|
||||
break;
|
||||
|
||||
case 27:
|
||||
disk6.exor_value = 0;
|
||||
break;
|
||||
|
||||
case 370:
|
||||
/* Set file position variable */
|
||||
disk6.disk[disk6.drive].file_pos = 256 * 16 * (disk6.disk[disk6.drive].phase >> 1) +
|
||||
256 * skew_table_6[ disk6.disk[disk6.drive].sector ];
|
||||
|
||||
/* Is the file large enough? */
|
||||
if (disk6.disk[disk6.drive].file_pos + 255 > disk6.disk[disk6.drive].file_size)
|
||||
return;
|
||||
|
||||
|
||||
/* Set position */
|
||||
fseek( disk6.disk[disk6.drive].fp, disk6.disk[disk6.drive].file_pos, SEEK_SET );
|
||||
|
||||
/* Write sector */
|
||||
fwrite(disk6.disk_data, 1, 256, disk6.disk[disk6.drive].fp);
|
||||
fflush( disk6.disk[disk6.drive].fp );
|
||||
/* Increment sector number (and wrap if necessary) */
|
||||
disk6.disk[disk6.drive].sector++;
|
||||
if (disk6.disk[disk6.drive].sector == 16)
|
||||
disk6.disk[disk6.drive].sector = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
position = disk6.disk[disk6.drive].run_byte - 28;
|
||||
disk6.disk_byte = translate_table_6[ disk6.disk_byte ];
|
||||
if (position >= 0x56)
|
||||
{
|
||||
position -= 0x56;
|
||||
disk6.disk_byte ^= disk6.exor_value;
|
||||
old_value = disk6.disk_byte;
|
||||
disk6.disk_data[position] |= (disk6.disk_byte << 2) & 0xFC;
|
||||
disk6.exor_value = old_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
disk6.disk_byte ^= disk6.exor_value;
|
||||
old_value = disk6.disk_byte;
|
||||
disk6.disk_data[position] = (disk6.disk_byte & 0x01) << 1;
|
||||
disk6.disk_data[position] |= (disk6.disk_byte & 0x02) >> 1;
|
||||
disk6.disk_data[position + 0x56] = (disk6.disk_byte & 0x04) >> 1;
|
||||
disk6.disk_data[position + 0x56] |= (disk6.disk_byte & 0x08) >> 3;
|
||||
disk6.disk_data[position + 0xAC] = (disk6.disk_byte & 0x10) >> 3;
|
||||
disk6.disk_data[position + 0xAC] |= (disk6.disk_byte & 0x20) >> 5;
|
||||
disk6.exor_value = old_value;
|
||||
}
|
||||
break;
|
||||
} /* End switch */
|
||||
|
||||
disk6.disk[disk6.drive].run_byte++;
|
||||
if (disk6.disk[disk6.drive].run_byte > 373)
|
||||
disk6.disk[disk6.drive].run_byte = 0;
|
||||
}
|
||||
|
||||
GLUE_C_READ(disk_read_byte)
|
||||
{
|
||||
if (disk6.ddrw)
|
||||
{
|
||||
if (disk6.disk[disk6.drive].fp == NULL)
|
||||
return 0; /* Return if there is no disk in drive */
|
||||
if (disk6.disk[disk6.drive].protected)
|
||||
return 0; /* Do not write if diskette is write protected */
|
||||
|
||||
if (disk6.disk_byte < 0x96)
|
||||
return 0; /* Only byte values at least 0x96 are allowed */
|
||||
|
||||
(disk6.disk[disk6.drive].nibblized) ? c_write_nibblized_6_6() : c_write_normal_6();
|
||||
return 0; /* ??? */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disk6.disk[disk6.drive].fp == NULL)
|
||||
return 0xFF; /* Return FF if there is no disk in drive */
|
||||
|
||||
if (disk6.motor) /* Motor turned on? */
|
||||
{
|
||||
if (disk6.motor > 99)
|
||||
return 0;
|
||||
else
|
||||
disk6.motor++;
|
||||
}
|
||||
|
||||
/* handle nibblized_6 or regular disks */
|
||||
return (disk6.disk[disk6.drive].nibblized) ? c_read_nibblized_6_6() : c_read_normal_6() ;
|
||||
}
|
||||
}
|
||||
|
||||
GLUE_C_READ(disk_read_phase)
|
||||
{
|
||||
/*
|
||||
* Comment from xapple2+ by Phillip Stephens:
|
||||
* Turn motor phases 0 to 3 on. Turning on the previous phase + 1
|
||||
* increments the track position, turning on the previous phase - 1
|
||||
* decrements the track position. In this scheme phase 0 and 3 are
|
||||
* considered to be adjacent. The previous phase number can be
|
||||
* computed as the track number % 4.
|
||||
*/
|
||||
|
||||
switch (((ea >> 1) - disk6.disk[disk6.drive].phase) & 3)
|
||||
{
|
||||
case 1:
|
||||
disk6.disk[disk6.drive].phase++;
|
||||
break;
|
||||
case 3:
|
||||
disk6.disk[disk6.drive].phase--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (disk6.disk[disk6.drive].phase<0) disk6.disk[disk6.drive].phase=0;
|
||||
if (disk6.disk[disk6.drive].phase>69) disk6.disk[disk6.drive].phase=69;
|
||||
|
||||
disk6.disk[disk6.drive].phase_change = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
GLUE_C_READ(disk_read_motor_off)
|
||||
{
|
||||
disk6.motor = 1;
|
||||
return disk6.drive;
|
||||
}
|
||||
|
||||
GLUE_C_READ(disk_read_motor_on)
|
||||
{
|
||||
disk6.motor = 0;
|
||||
return disk6.drive;
|
||||
}
|
||||
|
||||
GLUE_C_READ(disk_read_select_a)
|
||||
{
|
||||
return disk6.drive = 0;
|
||||
}
|
||||
|
||||
GLUE_C_READ(disk_read_select_b)
|
||||
{
|
||||
return disk6.drive = 1;
|
||||
}
|
||||
|
||||
|
||||
GLUE_C_READ(disk_read_latch)
|
||||
{
|
||||
return disk6.drive;
|
||||
}
|
||||
|
||||
GLUE_C_READ(disk_read_prepare_in)
|
||||
{
|
||||
disk6.ddrw = 0;
|
||||
return disk6.disk[disk6.drive].protected ? 0x80 : 0x00;
|
||||
}
|
||||
|
||||
GLUE_C_READ(disk_read_prepare_out)
|
||||
{
|
||||
disk6.ddrw = 1;
|
||||
return disk6.drive;
|
||||
}
|
||||
|
||||
GLUE_C_WRITE(disk_write_latch)
|
||||
{
|
||||
disk6.disk_byte = d;
|
||||
}
|
||||
|
||||
void disk_install(int slot)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
|
||||
assert(slot == 6);
|
||||
|
||||
/* load Disk II rom */
|
||||
if (!slot6_rom_loaded) {
|
||||
snprintf(temp, TEMPSIZE, "%s/slot6.rom", system_path);
|
||||
if ((f = fopen( temp, "r" )) == NULL) {
|
||||
printf("Cannot find file '%s'.\n",temp);
|
||||
exit( 0 );
|
||||
}
|
||||
fread(slot6_rom, 0x100, 1, f);
|
||||
fclose(f);
|
||||
slot6_rom_loaded = 1;
|
||||
}
|
||||
memcpy(apple_ii_64k[0] + 0xC600, slot6_rom, 0x100);
|
||||
|
||||
/* disk softswitches */
|
||||
cpu65_vmem[0xC0E0].r = cpu65_vmem[0xC0E2].r =
|
||||
cpu65_vmem[0xC0E4].r = cpu65_vmem[0xC0E6].r =
|
||||
ram_nop;
|
||||
|
||||
cpu65_vmem[0xC0E1].r = cpu65_vmem[0xC0E3].r =
|
||||
cpu65_vmem[0xC0E5].r = cpu65_vmem[0xC0E7].r =
|
||||
disk_read_phase;
|
||||
|
||||
cpu65_vmem[0xC0E8].r =
|
||||
disk_read_motor_off;
|
||||
cpu65_vmem[0xC0E9].r =
|
||||
disk_read_motor_on;
|
||||
cpu65_vmem[0xC0EA].r =
|
||||
disk_read_select_a;
|
||||
cpu65_vmem[0xC0EB].r =
|
||||
disk_read_select_b;
|
||||
cpu65_vmem[0xC0EC].r =
|
||||
disk_read_byte;
|
||||
cpu65_vmem[0xC0ED].r =
|
||||
disk_read_latch; /* read latch */
|
||||
cpu65_vmem[0xC0EE].r =
|
||||
disk_read_prepare_in;
|
||||
cpu65_vmem[0xC0EF].r =
|
||||
disk_read_prepare_out;
|
||||
|
||||
for (i = 0xC0E0; i < 0xC0F0; i++) {
|
||||
cpu65_vmem[i].w =
|
||||
cpu65_vmem[i].r;
|
||||
}
|
||||
|
||||
cpu65_vmem[0xC0ED].w =
|
||||
disk_write_latch; /* write latch */
|
||||
}
|
67
src/disk.h
Normal file
67
src/disk.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Defines for Disk ][ emulation
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef A2_DISK_H
|
||||
|
||||
struct diskette
|
||||
{
|
||||
unsigned char file_name[1024];
|
||||
int compressed;
|
||||
int nibblized;
|
||||
int protected;
|
||||
int phase_change;
|
||||
int sector;
|
||||
long file_size;
|
||||
int phase;
|
||||
int run_byte;
|
||||
FILE *fp;
|
||||
int file_pos;
|
||||
};
|
||||
|
||||
struct drive
|
||||
{
|
||||
int motor;
|
||||
int drive;
|
||||
int ddrw;
|
||||
int disk_byte;
|
||||
int volume;
|
||||
int checksum;
|
||||
int exor_value;
|
||||
unsigned char disk_data[258];
|
||||
struct diskette disk[2];
|
||||
};
|
||||
|
||||
extern struct drive disk6;
|
||||
|
||||
void c_init_6();
|
||||
int c_new_diskette_6(int, char*, int, int, int);
|
||||
void c_eject_6(int);
|
||||
|
||||
void disk_read_nop(),
|
||||
disk_read_phase(),
|
||||
disk_read_motor_off(),
|
||||
disk_read_motor_on(),
|
||||
disk_read_select_a(),
|
||||
disk_read_select_b(),
|
||||
disk_read_byte(),
|
||||
disk_read_latch(),
|
||||
disk_write_latch(),
|
||||
disk_read_prepare_in(),
|
||||
disk_read_prepare_out();
|
||||
|
||||
#define A2_DISK_H
|
||||
#endif
|
1238
src/display.S
Normal file
1238
src/display.S
Normal file
File diff suppressed because it is too large
Load Diff
1276
src/font.txt
Normal file
1276
src/font.txt
Normal file
File diff suppressed because it is too large
Load Diff
115
src/genfont.c
Normal file
115
src/genfont.c
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Font compiler
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
|
||||
/* I'm not sure if this is the correct way to detect libc 5/4. I long
|
||||
* since removed it from my system.
|
||||
*/
|
||||
#ifdef __GLIBC__
|
||||
#if __GLIBC__ == 1
|
||||
|
||||
/* Older Linux C libraries had getline removed (to humor programs that
|
||||
* used that name for their own functions), but kept getdelim */
|
||||
#define getline(l,s,f) getdelim(l,s,'\n',f)
|
||||
|
||||
#endif /* __GLIBC__ == 1 */
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned char byte;
|
||||
|
||||
char *line = 0;
|
||||
size_t line_size = 0;
|
||||
|
||||
int i,mx;
|
||||
|
||||
printf("/* Apple II text font data\n"
|
||||
" * \n"
|
||||
" * THIS FILE IS AUTOMATICALLY GENERATED --- DO NOT EDIT\n"
|
||||
" */\n");
|
||||
|
||||
i = 0x100;
|
||||
|
||||
while (getline(&line,&line_size,stdin) != -1)
|
||||
{
|
||||
if (line[0] == ';') continue;
|
||||
|
||||
if (line[0] == '=')
|
||||
{
|
||||
char *name,*size;
|
||||
|
||||
name = line + 1;
|
||||
while (isspace(*name)) name++;
|
||||
size = strchr(name,',');
|
||||
*size++ = 0;
|
||||
mx = i = strtol(size,0,0);
|
||||
|
||||
printf("\nconst unsigned char %s[%d] =\n{\n ",name,i*8);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
i--;
|
||||
|
||||
if (line[0] == ':')
|
||||
{
|
||||
int j = 8;
|
||||
|
||||
while (j--)
|
||||
{
|
||||
int k;
|
||||
|
||||
getline(&line,&line_size,stdin);
|
||||
k = 8;
|
||||
byte = 0;
|
||||
while (k--)
|
||||
{
|
||||
byte <<= 1;
|
||||
byte += (line[k] == '#');
|
||||
}
|
||||
|
||||
if (j)
|
||||
printf("0x%02x, ",byte);
|
||||
else if (i)
|
||||
printf("0x%02x,\n ",byte); /* last byte in glyph */
|
||||
else
|
||||
printf("0x%02x\n};\n",byte); /* last item in array */
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
|
||||
if (i)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Trouble with font file at character 0x%02x\n",
|
||||
mx-i-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
}
|
||||
|
5
src/genglue
Executable file
5
src/genglue
Executable file
@ -0,0 +1,5 @@
|
||||
#! /bin/sh
|
||||
echo '/* Automatically Generated -- do not edit */'
|
||||
echo '#include "gluepro.h"'
|
||||
grep -E -h '^(GLUE_)|(#if)|(#endif)|(#else)|(#elif)' $*
|
||||
exit 0
|
28
src/glue.h
Normal file
28
src/glue.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Glue macros
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#define GLUE_FIXED_READ(func,address)
|
||||
#define GLUE_FIXED_WRITE(func,address)
|
||||
#define GLUE_BANK_READ(func,pointer)
|
||||
#define GLUE_BANK_WRITE(func,pointer)
|
||||
#define GLUE_BANK_MAYBEWRITE(func,pointer)
|
||||
|
||||
#define GLUE_C_WRITE(func) \
|
||||
void unglued_##func(int ea, unsigned char d) /* you complete definition */
|
||||
|
||||
#define GLUE_C_READ(func) \
|
||||
unsigned char unglued_##func(int ea) /* you complete definition */
|
||||
|
75
src/gluepro.h
Normal file
75
src/gluepro.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Glue file prologue for Intel 386
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#define __ASSEMBLY__
|
||||
#include <apple2.h>
|
||||
|
||||
#define GLUE_FIXED_READ(func,address) \
|
||||
E(func) movb SN(address)(%edi),%al; \
|
||||
ret;
|
||||
|
||||
#define GLUE_FIXED_WRITE(func,address) \
|
||||
E(func) movb %al,SN(address)(%edi); \
|
||||
ret;
|
||||
|
||||
#define GLUE_BANK_READ(func,pointer) \
|
||||
E(func) addl SN(pointer),%edi; \
|
||||
movb (%edi),%al; \
|
||||
subl SN(pointer),%edi; \
|
||||
ret;
|
||||
|
||||
#define GLUE_BANK_WRITE(func,pointer) \
|
||||
E(func) addl SN(pointer),%edi; \
|
||||
movb %al,(%edi); \
|
||||
subl SN(pointer),%edi; \
|
||||
ret;
|
||||
|
||||
#define GLUE_BANK_MAYBEWRITE(func,pointer) \
|
||||
E(func) addl SN(pointer),%edi; \
|
||||
cmpl $0,SN(pointer); \
|
||||
jz 1f; \
|
||||
movb %al,(%edi); \
|
||||
1: ret;
|
||||
|
||||
|
||||
#define GLUE_C_WRITE(func) \
|
||||
E(func) pushl %eax; \
|
||||
andl $0xff,%eax; \
|
||||
pushl %ecx; \
|
||||
pushl %edx; \
|
||||
pushl %eax; \
|
||||
pushl %edi; \
|
||||
call SN(unglued_##func); \
|
||||
popl %edx; /* dummy */ \
|
||||
popl %edx; /* dummy */ \
|
||||
popl %edx; \
|
||||
popl %ecx; \
|
||||
popl %eax; \
|
||||
ret; \
|
||||
|
||||
#define GLUE_C_READ(func) \
|
||||
E(func) pushl %eax; \
|
||||
pushl %ecx; \
|
||||
pushl %edx; \
|
||||
pushl %edi; \
|
||||
call SN(unglued_##func); \
|
||||
movb %al,12(%esp); \
|
||||
popl %edx; /* dummy */ \
|
||||
popl %edx; \
|
||||
popl %ecx; \
|
||||
popl %eax; \
|
||||
ret;
|
||||
|
1229
src/interface.c
Normal file
1229
src/interface.c
Normal file
File diff suppressed because it is too large
Load Diff
28
src/interface.h
Normal file
28
src/interface.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Exported menu routines
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef A2_INTERFACE_H
|
||||
#define A2_INTERFACE_H
|
||||
|
||||
void c_interface_print( int x, int y, int cs, unsigned char *s );
|
||||
void c_interface_redo_bottom();/* bit of a HACK? */
|
||||
void c_load_interface_font();
|
||||
void c_interface_keyboard_layout();
|
||||
void c_interface_parameters();
|
||||
void c_interface_exit();
|
||||
void c_interface_translate_screen(unsigned char screen[24][41]);
|
||||
void c_interface_select_diskette(int);
|
||||
#endif
|
207
src/joystick.c
Normal file
207
src/joystick.c
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Joystick calibration routines
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/joystick.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <values.h>
|
||||
|
||||
#include "interface.h"
|
||||
#include "video.h"
|
||||
#include "keys.h"
|
||||
#include "misc.h"
|
||||
#include "prefs.h"
|
||||
|
||||
int js_fd = -1; /* joystick file descriptor */
|
||||
struct JS_DATA_TYPE js; /* joystick data struct */
|
||||
|
||||
int js_lowerrange_x,
|
||||
js_upperrange_x,
|
||||
js_lowerrange_y,
|
||||
js_upperrange_y,
|
||||
js_offset_x,
|
||||
js_offset_y;
|
||||
|
||||
float
|
||||
js_adjustlow_x,
|
||||
js_adjustlow_y,
|
||||
js_adjusthigh_x,
|
||||
js_adjusthigh_y;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_open_joystick() - opens joystick device and sets timelimit value
|
||||
------------------------------------------------------------------------- */
|
||||
int c_open_joystick() {
|
||||
if (js_fd < 0) {
|
||||
if ((js_fd = open("/dev/js0", O_RDONLY)) < 0) {
|
||||
|
||||
/* try again with another name */
|
||||
if ((js_fd = open("/dev/joystick", O_RDONLY)) < 0)
|
||||
return 1;/* problem */
|
||||
}
|
||||
/* set timelimit value */
|
||||
if (ioctl(js_fd, JS_SET_TIMELIMIT, &js_timelimit) == -1)
|
||||
return 1;/* problem */
|
||||
}
|
||||
return 0;/* no problem */
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_close_joystick() - closes joystick device
|
||||
------------------------------------------------------------------------- */
|
||||
void c_close_joystick() {
|
||||
if (js_fd < 0)
|
||||
return;
|
||||
close(js_fd);
|
||||
js_fd = -1;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* c_calculate_joystick_parms() - calculates parameters for joystick
|
||||
* device. assumes that device extremes have already been determined.
|
||||
* ------------------------------------------------------------------------- */
|
||||
void c_calculate_joystick_parms() {
|
||||
|
||||
js_lowerrange_x = js_center_x - js_min_x;
|
||||
js_upperrange_x = js_max_x - js_center_x;
|
||||
js_lowerrange_y = js_center_y - js_min_y;
|
||||
js_upperrange_y = js_max_y - js_center_y;
|
||||
|
||||
js_offset_x = js_min_x;
|
||||
js_offset_y = js_min_y;
|
||||
|
||||
js_adjustlow_x = (float)half_joy_range / (float)js_lowerrange_x;
|
||||
js_adjustlow_y = (float)half_joy_range / (float)js_lowerrange_y;
|
||||
js_adjusthigh_x = (float)half_joy_range / (float)js_upperrange_x;
|
||||
js_adjusthigh_y = (float)half_joy_range / (float)js_upperrange_y;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_calibrate_joystick() - calibrates joystick. determines extreme
|
||||
and center coordinates. assumes that it can write to the interface
|
||||
screen.
|
||||
------------------------------------------------------------------------- */
|
||||
void c_calibrate_joystick () {
|
||||
int almost_done, done;
|
||||
unsigned char x_val, y_val;
|
||||
|
||||
/* reset all the extremes */
|
||||
js_max_x = -1;
|
||||
js_max_y = -1;
|
||||
js_min_x = MAXINT;
|
||||
js_min_y = MAXINT;
|
||||
|
||||
/* open joystick device if not open */
|
||||
if (js_fd < 0) {
|
||||
if (c_open_joystick()) { /* problem opening device */
|
||||
c_interface_print(
|
||||
1, 21, 0, " " );
|
||||
c_interface_print(
|
||||
1, 22, 0, " cannot open joystick device. " );
|
||||
video_sync(0);
|
||||
usleep(1500000);
|
||||
c_interface_redo_bottom();
|
||||
return;/* problem */
|
||||
}
|
||||
}
|
||||
|
||||
c_interface_print(
|
||||
1, 21, 0, " Move joystick to all extremes then " );
|
||||
c_interface_print(
|
||||
1, 22, 0, " center it and press a button. " );
|
||||
video_sync(0);
|
||||
usleep(1500000);
|
||||
c_interface_print(
|
||||
1, 21, 0, " " );
|
||||
c_interface_print(
|
||||
1, 22, 0, " " );
|
||||
|
||||
almost_done = done = 0; /* not done calibrating */
|
||||
while ((read(js_fd, &js, JS_RETURN) > 0) && (!done))
|
||||
{
|
||||
sprintf (temp, " x = %04x, y = %04x", js.x, js.y);
|
||||
c_interface_print(1, 22, 0, temp);
|
||||
video_sync(0);
|
||||
if (js_max_x < js.x)
|
||||
js_max_x = js.x;
|
||||
if (js_max_y < js.y)
|
||||
js_max_y = js.y;
|
||||
|
||||
if (js_min_x > js.x)
|
||||
js_min_x = js.x;
|
||||
if (js_min_y > js.y)
|
||||
js_min_y = js.y;
|
||||
|
||||
if (js.buttons != 0x00) /* press */
|
||||
almost_done = 1;
|
||||
if (almost_done && (js.buttons == 0x00)) /* release */
|
||||
done = 1;
|
||||
}
|
||||
|
||||
js_center_x = js.x;
|
||||
js_center_y = js.y;
|
||||
|
||||
printf("js_min_x = %d\n", js_min_x);
|
||||
printf("js_min_y = %d\n", js_min_y);
|
||||
printf("js_max_x = %d\n", js_max_x);
|
||||
printf("js_max_y = %d\n", js_max_y);
|
||||
printf("js_center_x = %d\n", js_center_x);
|
||||
printf("js_center_y = %d\n", js_center_y);
|
||||
printf("\n");
|
||||
|
||||
c_calculate_joystick_parms(); /* determine the parms */
|
||||
|
||||
printf("js_lowerrange_x = %d\n", js_lowerrange_x);
|
||||
printf("js_lowerrange_y = %d\n", js_lowerrange_y);
|
||||
printf("js_upperrange_x = %d\n", js_upperrange_x);
|
||||
printf("js_upperrange_y = %d\n", js_upperrange_y);
|
||||
printf("\n");
|
||||
printf("js_offset_x = %d\n", js_offset_x);
|
||||
printf("js_offset_y = %d\n", js_offset_y);
|
||||
printf("\n");
|
||||
printf("js_adjustlow_x = %f\n", js_adjustlow_x);
|
||||
printf("js_adjustlow_y = %f\n", js_adjustlow_y);
|
||||
printf("js_adjusthigh_x = %f\n", js_adjusthigh_x);
|
||||
printf("js_adjusthigh_y = %f\n", js_adjusthigh_y);
|
||||
printf("\n");
|
||||
|
||||
c_interface_print(
|
||||
1, 21, 0, " Press a button to continue. " );
|
||||
video_sync(0);
|
||||
|
||||
/* show the normalized values until user presses button */
|
||||
while ((read(js_fd, &js, JS_RETURN) > 0) && js.buttons == 0x00) {
|
||||
x_val = (js.x < js_center_x)
|
||||
? (js.x - js_offset_x) * js_adjustlow_x
|
||||
: (js.x - (js_center_x/*+js_offset_x*/)) * js_adjusthigh_x +
|
||||
half_joy_range;
|
||||
|
||||
y_val = (js.y < js_center_y)
|
||||
? (js.y - js_offset_y) * js_adjustlow_y
|
||||
: (js.y - (js_center_y/*+js_offset_y*/)) * js_adjusthigh_y +
|
||||
half_joy_range;
|
||||
sprintf(temp, " x = %02x, y = %02x", x_val, y_val);
|
||||
c_interface_print(1, 22, 0, temp);
|
||||
video_sync(0);
|
||||
}
|
||||
c_interface_redo_bottom();
|
||||
video_sync(0);
|
||||
}
|
461
src/keys.c
Normal file
461
src/keys.c
Normal file
@ -0,0 +1,461 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Keyboard handler
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/keyboard.h>
|
||||
|
||||
#include "keys.h"
|
||||
#include "misc.h"
|
||||
#include "video.h"
|
||||
#include "interface.h"
|
||||
#include "cpu.h"
|
||||
#include "prefs.h"
|
||||
|
||||
/* from misc.c */
|
||||
extern uid_t user, privileged;
|
||||
|
||||
#ifdef DEBUGGER
|
||||
/* from debugger.c */
|
||||
extern void c_do_debugging();
|
||||
#endif
|
||||
|
||||
|
||||
/* parameters for generic and keyboard-simulated joysticks */
|
||||
short joy_x = 127;
|
||||
short joy_y = 127;
|
||||
unsigned char joy_button0 = 0;
|
||||
unsigned char joy_button1 = 0;
|
||||
unsigned char joy_button2 = 0;
|
||||
|
||||
#ifdef PC_JOYSTICK
|
||||
#include <linux/joystick.h>
|
||||
int x_val, y_val;
|
||||
#endif
|
||||
|
||||
static int next_key = -1;
|
||||
static char caps_lock = 1; /* is enabled */
|
||||
static int in_mygetch = 0;
|
||||
|
||||
/* ----------------------------------------------------
|
||||
Keymap. Mapping scancodes to Apple II+ US Keyboard
|
||||
---------------------------------------------------- */
|
||||
static int apple_ii_keymap_plain[128] =
|
||||
{ -1 , 27 , '1', '2', '3', '4', '5', '6', /* 00-07 */
|
||||
'7', '8', '9', '0', ':', '-', 8 , 27 , /* 08-15 */
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16-23 */
|
||||
'O', 'P', -1 , 8 , 13 , -1 , 'A', 'S', /* 24-31 */
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', /* 32-39 */
|
||||
8 , -1 , -1 , 21 , 'Z', 'X', 'C', 'V', /* 40-47 */
|
||||
'B', 'N', 'M', ',', '.', '/', -1 , -1 , /* 48-55 */
|
||||
JB0 , ' ', -1 , kF1 , kF2 , kF3 , kF4 , kF5 , /* 56-63 */
|
||||
kF6 , kF7 , kF8 , kF9 , kF10, -1 , -1 , JUL, /* 64-71 */
|
||||
J_U, JUR, S_D, J_L, J_C, J_R, S_I, JDL, /* 72-79 */
|
||||
J_D, JDR, -1 , -1 , -1 , kF11, kF12, -1 , /* 80-87 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , /* 88-95 */
|
||||
-1 , -1 , -1 , -1, JB1 , RST , kHOME , -1 , /* 96-103 */
|
||||
kPGUP , 8 , 21 , kEND , -1 , kPGDN, JB2 , -1, /* 104-111 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , kF4 /* (pause) */, /* 112-119 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; /* 120-127 */
|
||||
|
||||
static int apple_ii_keymap_ctrl[128] =
|
||||
{ -1 , 027, '1', '2', '3', '4', '5', '6', /* 00-07 */
|
||||
'7', '8', '9', '0', ':', '-', 8 , 27 , /* 08-15 */
|
||||
17 , 23 , 5 , 18 , 20 , 25 , 21 , 9 , /* 16-23 */
|
||||
15 , 16 , -1 , 8 , 13 , -1 , 1 , 19 , /* 24-31 */
|
||||
4 , 6 , 7 , 8 , 10 , 11 , 12 , ';', /* 32-39 */
|
||||
8 , -1 , -1 , 21 , 26 , 24 , 3 , 22 , /* 40-47 */
|
||||
2 , 14 , 13 , ',', '.', '/', -1 , -1 , /* 48-55 */
|
||||
JB0 , ' ', -1 , kF1 , kF2 , kF3 , kF4 , kF5 , /* 56-63 */
|
||||
kF6 , kF7 , kF8 , kF9 , kF10, -1 , -1 , JUL, /* 64-71 */
|
||||
J_U, JUR, S_D, J_L, J_C, J_R, S_I, JDL, /* 72-79 */
|
||||
J_D, JDR, -1 , -1 , -1 , kF11, kF12, -1 , /* 80-87 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , /* 88-95 */
|
||||
-1 , -1 , -1 , BOT, JB1 , RST , kHOME , -1 , /* 96-103 */
|
||||
kPGUP , 8 , 21 , kEND, -1 , kPGDN, JB2 , -1, /* 104-111 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , kF4 /* pause */, /* 112-119 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; /* 120-127 */
|
||||
|
||||
static int apple_ii_keymap_shifted[128] =
|
||||
{ -1 , 27 , '!', '"', '#', '$', '%', '&', /* 00-07 */
|
||||
39 , '(', ')', '0', '*', '=', 8 , 27 , /* 08-15 */
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16-23 */
|
||||
'O', '@', -1 , 8 , 13 , -1 , 'A', 'S', /* 24-31 */
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', '+', /* 32-39 */
|
||||
8 , -1 , -1 , 21 , 'Z', 'X', 'C', 'V', /* 40-47 */
|
||||
'B', '^', 'M', '<', '>', '?', -1 , -1 , /* 48-55 */
|
||||
JB0 , ' ', -1 , kF1 , kF2 , kF3 , kF4 , kF5 , /* 56-63 */
|
||||
kF6 , kF7 , kF8 , kF9 , kF10, -1 , -1 , JUL, /* 64-71 */
|
||||
J_U, JUR, S_D, J_L, J_C, J_R, S_I, JDL, /* 72-79 */
|
||||
J_D, JDR, -1 , -1 , -1 , kF11, kF12, -1 , /* 80-87 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , /* 88-95 */
|
||||
-1 , -1 , -1 , -1 , JB1 , RST , kHOME , -1 , /* 96-103 */
|
||||
kPGUP , 8 , 21 , kEND, -1 , kPGDN, JB2 , -1, /* 104-111 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , kF4 /* pause */, /* 112-119 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; /* 120-127 */
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* ----------------------------------------------------
|
||||
//e Keymap. Mapping scancodes to Apple //e US Keyboard
|
||||
---------------------------------------------------- */
|
||||
static int apple_iie_keymap_plain[128] =
|
||||
{ -1 , 27 , '1', '2', '3', '4', '5', '6', /* 00-07 */
|
||||
'7', '8', '9', '0', '-', '=', 8 , 9 , /* 08-15 */
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 16-23 */
|
||||
'o', 'p', '[', ']', 13 , -1 , 'a', 's', /* 24-31 */
|
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 32-39 */
|
||||
'\'', '`', -1 ,'\\', 'z', 'x', 'c', 'v', /* 40-47 */
|
||||
'b', 'n', 'm', ',', '.', '/', -1 , -1 , /* 48-55 */
|
||||
JB0 , ' ', -1 , kF1 , kF2 , kF3 , kF4 , kF5 , /* 56-63 */
|
||||
kF6 , kF7 , kF8 , kF9 , kF10, -1 , -1 , JUL, /* 64-71 */
|
||||
J_U, JUR, S_D, J_L, J_C, J_R, S_I, JDL, /* 72-79 */
|
||||
J_D, JDR, -1 , -1 , -1 , kF11, kF12, -1 , /* 80-87 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , /* 88-95 */
|
||||
-1 , -1 , -1 , -1, JB1 , RST , kHOME , 11 , /* 96-103 */
|
||||
kPGUP , 8 , 21 , kEND, 10 , kPGDN, JB2, 127, /* 104-111 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , kF4 /* pause */, /* 112-119 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; /* 120-127 */
|
||||
|
||||
static int apple_iie_keymap_ctrl[128] =
|
||||
{ -1 , 27 , '1', '2', '3', '4', '5', '6', /* 00-07 */
|
||||
'7', '8', '9', '0', '-', '=', 8 , 9 , /* 08-15 */
|
||||
17 , 23 , 5 , 18 , 20 , 25 , 21 , 9 , /* 16-23 */
|
||||
15 , 16 , 27 , 29 , 13 , -1 , 1 , 19 , /* 24-31 */
|
||||
4 , 6 , 7 , 8 , 10 , 11 , 12 , ';', /* 32-39 */
|
||||
'\'', '`', -1 ,'\\', 26 , 24 , 3 , 22 , /* 40-47 */
|
||||
2 , 14 , 13 , ',', '.', '/', -1 , -1 , /* 48-55 */
|
||||
JB0 , ' ', -1 , kF1 , kF2 , kF3 , kF4 , kF5 , /* 56-63 */
|
||||
kF6 , kF7 , kF8 , kF9 , kF10, -1 , -1 , JUL, /* 64-71 */
|
||||
J_U, JUR, S_D, J_L, J_C, J_R, S_I, JDL, /* 72-79 */
|
||||
J_D, JDR, -1 , -1 , -1 , kF11, kF12, -1 , /* 80-87 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , /* 88-95 */
|
||||
-1 , -1 , -1 , BOT, JB1 , RST , kHOME , 11 , /* 96-103 */
|
||||
kPGUP , 8 , 21 , kEND, 10 , kPGDN, JB2, 127, /* 104-111 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , kF4 /* pause */, /* 112-119 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; /* 120-127 */
|
||||
|
||||
static int apple_iie_keymap_shifted[128] =
|
||||
{ -1 , 27 , '!', '@', '#', '$', '%', '^', /* 00-07 */
|
||||
'&', '*', '(', ')', '_', '+', 8 , 9 , /* 08-15 */
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16-23 */
|
||||
'O', 'P', '{', '}', 13 , -1 , 'A', 'S', /* 24-31 */
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 32-39 */
|
||||
'"', '~', -1 , '|', 'Z', 'X', 'C', 'V', /* 40-47 */
|
||||
'B', 'N', 'M', '<', '>', '?', -1 , -1 , /* 48-55 */
|
||||
JB0 , ' ', -1 , kF1 , kF2 , kF3 , kF4 , kF5 , /* 56-63 */
|
||||
kF6 , kF7 , kF8 , kF9 , kF10, -1 , -1 , JUL, /* 64-71 */
|
||||
J_U, JUR, S_D, J_L, J_C, J_R, S_I, JDL, /* 72-79 */
|
||||
J_D, JDR, -1 , -1 , -1 , kF11, kF12, -1 , /* 80-87 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , /* 88-95 */
|
||||
-1 , -1 , -1 , -1 , JB1 , RST , kHOME , 11 , /* 96-103 */
|
||||
kPGUP , 8 , 21 , kEND, 10 , kPGDN, JB2, 127, /* 104-111 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , kF4 /* pause */, /* 112-119 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; /* 120-127 */
|
||||
|
||||
static int apple_iie_keymap_caps[128] =
|
||||
{ -1 , 27 , '1', '2', '3', '4', '5', '6', /* 00-07 */
|
||||
'7', '8', '9', '0', '-', '=', 8 , 9 , /* 08-15 */
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16-23 */
|
||||
'O', 'P', '[', ']', 13 , -1 , 'A', 'S', /* 24-31 */
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', /* 32-39 */
|
||||
'\'', '`', -1 ,'\\', 'Z', 'X', 'C', 'V', /* 40-47 */
|
||||
'B', 'N', 'M', ',', '.', '/', -1 , -1 , /* 48-55 */
|
||||
JB0 , ' ', -1 , kF1 , kF2 , kF3 , kF4 , kF5 , /* 56-63 */
|
||||
kF6 , kF7 , kF8 , kF9 , kF10, -1 , -1 , JUL, /* 64-71 */
|
||||
J_U, JUR, S_D, J_L, J_C, J_R, S_I, JDL, /* 72-79 */
|
||||
J_D, JDR, -1 , -1 , -1 , kF11, kF12, -1 , /* 80-87 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , /* 88-95 */
|
||||
-1 , -1 , -1 , -1, JB1 , RST , kHOME , 11 , /* 96-103 */
|
||||
kPGUP , 8 , 21 , kEND, 10 , kPGDN, JB2, 127, /* 104-111 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , kF4 /* pause */, /* 112-119 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; /* 120-127 */
|
||||
|
||||
static int apple_iie_keymap_shift_ctrl[128] =
|
||||
{ -1 , 27 , '1', 0 , '3', '4', '5', 30 , /* 00-07 */
|
||||
'7', '8', '9', '0', 31 , '=', 8 , 9 , /* 08-15 */
|
||||
17 , 23 , 5 , 18 , 20 , 25 , 21 , 9 , /* 16-23 */
|
||||
15 , 16 , 27 , 29 , 13 , -1 , 1 , 19 , /* 24-31 */
|
||||
4 , 6 , 7 , 8 , 10 , 11 , 12 , ';', /* 32-39 */
|
||||
'\'', '`', 28 , -1 , 26 , 24 , 3 , 22 , /* 40-47 */
|
||||
2 , 14 , 13 , ',', '.', '/', -1 , -1 , /* 48-55 */
|
||||
JB0 , ' ', -1 , kF1 , kF2 , kF3 , kF4 , kF5 , /* 56-63 */
|
||||
kF6 , kF7 , kF8 , kF9 , kF10, -1 , -1 , JUL, /* 64-71 */
|
||||
J_U, JUR, S_D, J_L, J_C, J_R, S_I, JDL, /* 72-79 */
|
||||
J_D, JDR, -1 , -1 , -1 , kF11, kF12, -1 , /* 80-87 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , /* 88-95 */
|
||||
-1 , -1 , -1 , BOT, JB1 , RST , kHOME , 11 , /* 96-103 */
|
||||
kPGUP , 8 , 21 , kEND, 10 , kPGDN, JB2, 127, /* 104-111 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , kF4 /* pause */, /* 112-119 */
|
||||
-1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; /* 120-127 */
|
||||
#endif
|
||||
|
||||
static unsigned short max_speed = 0;
|
||||
static char key_pressed[ 256 ];
|
||||
|
||||
|
||||
/* ----------------------------------------------------
|
||||
functions
|
||||
---------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* This routine is called periodically to update the state of the emulator.
|
||||
* -handles switching to menus
|
||||
* -polls PC Joystick
|
||||
* -update palette for flashing text
|
||||
* ------------------------------------------------------------------------- */
|
||||
void c_periodic_update(int dummysig) {
|
||||
int current_key;
|
||||
|
||||
video_sync(0);
|
||||
|
||||
if (next_key >= 0)
|
||||
{
|
||||
current_key = next_key;
|
||||
next_key = -1;
|
||||
|
||||
if (current_key < 128) {
|
||||
apple_ii_64k[0][0xC000] = current_key | 0x80;
|
||||
apple_ii_64k[1][0xC000] = current_key | 0x80;
|
||||
} else switch (current_key) {
|
||||
case RST:
|
||||
cpu65_interrupt(ResetSig);
|
||||
break;
|
||||
case BOT:
|
||||
cpu65_interrupt(RebootSig);
|
||||
break;
|
||||
case J_C:
|
||||
joy_x = joy_center_x;
|
||||
joy_y = joy_center_y;
|
||||
break;
|
||||
case kF1:
|
||||
c_interface_select_diskette( 0 );
|
||||
break;
|
||||
case kF2:
|
||||
c_interface_select_diskette( 1 );
|
||||
break;
|
||||
case kF4:
|
||||
while (c_mygetch(1) == -1) { }/*busy loop*/
|
||||
break;
|
||||
case kF5:
|
||||
c_interface_keyboard_layout();
|
||||
break;
|
||||
#ifdef DEBUGGER
|
||||
case kF7:
|
||||
cpu65_interrupt(EnterDebugSig);
|
||||
break;
|
||||
#endif
|
||||
#if 0
|
||||
case kF8:
|
||||
c_interface_words();
|
||||
break;
|
||||
#endif
|
||||
case kF9:
|
||||
if (max_speed != 0)
|
||||
cpu65_delay = max_speed, max_speed = 0;
|
||||
else
|
||||
max_speed = cpu65_delay, cpu65_delay = 1;
|
||||
break;
|
||||
case kF10:
|
||||
if (max_speed != 0)
|
||||
cpu65_delay = max_speed, max_speed = 0;
|
||||
c_interface_parameters();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* simulated joystick */
|
||||
if (joy_mode == JOY_KYBD) {
|
||||
if (key_pressed[ SCODE_J_U ])
|
||||
{
|
||||
if (joy_y > joy_step)
|
||||
joy_y -= joy_step;
|
||||
else
|
||||
joy_y = 0;
|
||||
}
|
||||
|
||||
if (key_pressed[ SCODE_J_D ])
|
||||
{
|
||||
if (joy_y < joy_range - joy_step)
|
||||
joy_y += joy_step;
|
||||
else
|
||||
joy_y = joy_range-1;
|
||||
}
|
||||
|
||||
if (key_pressed[ SCODE_J_L ])
|
||||
{
|
||||
if (joy_x > joy_step)
|
||||
joy_x -= joy_step;
|
||||
else
|
||||
joy_x = 0;
|
||||
}
|
||||
|
||||
if (key_pressed[ SCODE_J_R ])
|
||||
{
|
||||
if (joy_x < joy_range - joy_step)
|
||||
joy_x += joy_step;
|
||||
else
|
||||
joy_x = joy_range-1;
|
||||
}
|
||||
}
|
||||
#ifdef PC_JOYSTICK
|
||||
else if ((joy_mode == JOY_PCJOY) && !(js_fd < 0)) {
|
||||
read(js_fd, &js, JS_RETURN);
|
||||
|
||||
x_val = (js.x < js_center_x)
|
||||
? (js.x - js_offset_x) * js_adjustlow_x
|
||||
: (js.x - js_center_x) * js_adjusthigh_x + half_joy_range;
|
||||
|
||||
y_val = (js.y < js_center_y)
|
||||
? (js.y - js_offset_y) * js_adjustlow_y
|
||||
: (js.y - js_center_y) * js_adjusthigh_y + half_joy_range;
|
||||
|
||||
joy_y = (y_val > 0xff) ? 0xff : (y_val < 0) ? 0 : y_val;
|
||||
joy_x = (x_val > 0xff) ? 0xff : (x_val < 0) ? 0 : x_val;
|
||||
|
||||
/* almost_x = (x_val > 0xff) ? 0xff : (x_val < 0) ? 0 : x_val; */
|
||||
/* adj_x = (3-(joy_y/0x40)) + 10; */
|
||||
/* turnpt_x = joy_y + adj_x; */
|
||||
/* almost_x = (almost_x < turnpt_x) */
|
||||
/* ? almost_x */
|
||||
/* : (almost_x - turnpt_x) * adjusthigh_x; */
|
||||
|
||||
/* joy_x = (almost_x > 0xff) ? 0xff : (almost_x < 0) ? 0 : almost_x; */
|
||||
|
||||
/* sample buttons only if apple keys aren't pressed. keys get set to
|
||||
* 0xff, and js buttons are set to 0x80. */
|
||||
if (!(joy_button0 & 0x7f))
|
||||
joy_button0 = (js.buttons & 0x01) ? 0x80 : 0x0;
|
||||
if (!(joy_button1 & 0x7f))
|
||||
joy_button1 = (js.buttons & 0x02) ? 0x80 : 0x0;
|
||||
if (!(joy_button2 & 0x7f))
|
||||
joy_button2 = (js.buttons & 0x03) ? 0x80 : 0x0;
|
||||
}
|
||||
#endif
|
||||
else if (joy_mode == JOY_OFF)
|
||||
joy_x = joy_y = 256;
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER
|
||||
/* Called from cpu code. Perhaps should be moved to misc.c, but was
|
||||
* abstracted from function above...
|
||||
*/
|
||||
void enter_debugger(void)
|
||||
{
|
||||
setitimer(ITIMER_VIRTUAL,&timer_off,0);
|
||||
c_do_debugging();
|
||||
setitimer(ITIMER_VIRTUAL,&timer_on,0);
|
||||
}
|
||||
#endif /* DEBUGGER */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
void c_read_raw_key() : handle a scancode
|
||||
------------------------------------------------------------------------- */
|
||||
void c_read_raw_key(int scancode, int pressed) {
|
||||
int *keymap = NULL;
|
||||
|
||||
/* determine which key mapping to use */
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE || in_mygetch) {
|
||||
/* set/reset caps lock */
|
||||
if (key_pressed[ SCODE_CAPS ])
|
||||
caps_lock = !caps_lock;
|
||||
|
||||
if ((key_pressed[ SCODE_L_SHIFT ] || /* shift-ctrl */
|
||||
key_pressed[ SCODE_R_SHIFT ]) &&
|
||||
(key_pressed[ SCODE_L_CTRL ] ||
|
||||
key_pressed[ SCODE_R_CTRL ]))
|
||||
keymap = apple_iie_keymap_shift_ctrl;
|
||||
else if (key_pressed[ SCODE_L_CTRL ] || /* ctrl */
|
||||
key_pressed[ SCODE_R_CTRL ])
|
||||
keymap = apple_iie_keymap_ctrl;
|
||||
else if (key_pressed[ SCODE_L_SHIFT ] || /* shift */
|
||||
key_pressed[ SCODE_R_SHIFT ])
|
||||
keymap = apple_iie_keymap_shifted;
|
||||
else if (caps_lock) /* caps lock */
|
||||
keymap = apple_iie_keymap_caps;
|
||||
else /* plain */
|
||||
keymap = apple_iie_keymap_plain;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (key_pressed[ SCODE_L_CTRL ] ||
|
||||
key_pressed[ SCODE_R_CTRL ])
|
||||
keymap = apple_ii_keymap_ctrl;
|
||||
else if (key_pressed[ SCODE_L_SHIFT ] ||
|
||||
key_pressed[ SCODE_R_SHIFT ])
|
||||
keymap = apple_ii_keymap_shifted;
|
||||
else
|
||||
keymap = apple_ii_keymap_plain;
|
||||
}
|
||||
|
||||
/* key is pressed */
|
||||
if (pressed) {
|
||||
|
||||
key_pressed[ scancode ] = 1;
|
||||
|
||||
switch (keymap[ scancode ]) {
|
||||
case JB0:
|
||||
joy_button0 = 0xff;/* open apple */
|
||||
break;
|
||||
case JB1:
|
||||
joy_button1 = 0xff;/* closed apple */
|
||||
break;
|
||||
case JB2:
|
||||
joy_button2 = 0xff;/* unused? */
|
||||
break;
|
||||
default:
|
||||
next_key = keymap[scancode];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* key is released */
|
||||
else {
|
||||
key_pressed[ scancode ] = 0;
|
||||
switch (keymap[ scancode ]) {
|
||||
case JB0:
|
||||
joy_button0 = 0x00;
|
||||
break;
|
||||
case JB1:
|
||||
joy_button1 = 0x00;
|
||||
break;
|
||||
case JB2:
|
||||
joy_button2 = 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int c_mygetch(int block)
|
||||
{
|
||||
int retval;
|
||||
|
||||
in_mygetch = 1;
|
||||
|
||||
if (block) while (next_key == -1)
|
||||
video_sync(1);
|
||||
else
|
||||
video_sync(0);
|
||||
|
||||
in_mygetch = 0;
|
||||
|
||||
retval = next_key;
|
||||
next_key = -1;
|
||||
|
||||
return retval;
|
||||
}
|
95
src/keys.h
Normal file
95
src/keys.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Keyboard definitions
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef A2_KEYS_H
|
||||
#define A2_KEYS_H
|
||||
|
||||
#define SCODE_L_CTRL 29
|
||||
#define SCODE_R_CTRL 97
|
||||
#define SCODE_L_SHIFT 42
|
||||
#define SCODE_R_SHIFT 54
|
||||
#define SCODE_CAPS 58
|
||||
#define SCODE_J_U 72
|
||||
#define SCODE_J_D 80
|
||||
#define SCODE_J_L 75
|
||||
#define SCODE_J_R 77
|
||||
#define SCODE_J_C 76
|
||||
|
||||
#define kF1 128
|
||||
#define kF2 129
|
||||
#define kF3 130
|
||||
#define kF4 131
|
||||
#define kF5 132
|
||||
#define kF6 133
|
||||
#define kF7 134
|
||||
#define kF8 135
|
||||
#define kF9 136
|
||||
#define kF10 137
|
||||
#define kF11 138
|
||||
#define kF12 139
|
||||
#define kPRNT 140
|
||||
#define RST kPRNT
|
||||
|
||||
#define J_U 141
|
||||
#define J_D 142
|
||||
#define J_L 143
|
||||
#define J_R 144
|
||||
#define JUL 145
|
||||
#define JUR 146
|
||||
#define JDL 147
|
||||
#define JDR 148
|
||||
|
||||
#define JB0 149
|
||||
#define JB1 150
|
||||
#define JB2 151
|
||||
|
||||
#define S_D 152
|
||||
#define S_I 153
|
||||
#define J_C 154
|
||||
#define kPAUSE 155
|
||||
#define BOT kPAUSE
|
||||
|
||||
#define kLEFT 8 /* 157 */
|
||||
#define kRIGHT 21 /* 158 */
|
||||
#define kUP 11 /* 159 */
|
||||
#define kDOWN 10 /* 160 */
|
||||
|
||||
#define kESC 27 /* 161 */
|
||||
#define kPGUP 162
|
||||
#define kHOME 163
|
||||
#define kPGDN 164
|
||||
#define kEND 165
|
||||
|
||||
#define TIMER_DELAY 30000L
|
||||
|
||||
|
||||
#ifdef PC_JOYSTICK
|
||||
extern int js_fd;
|
||||
extern struct JS_DATA_TYPE js;
|
||||
extern int js_offset_x, js_offset_y;
|
||||
extern float js_adjustlow_x, js_adjustlow_y, js_adjusthigh_x, js_adjusthigh_y;
|
||||
extern int c_open_joystick(void);
|
||||
extern void c_calculate_joystick_parms(void);
|
||||
extern void c_close_joystick(void);
|
||||
extern void c_calibrate_joystick(void);
|
||||
#endif
|
||||
|
||||
void c_read_raw_key(int scancode, int pressed);
|
||||
void c_periodic_update(int dummysig);
|
||||
void enter_debugger(void);
|
||||
int c_mygetch(int block);
|
||||
|
||||
#endif
|
977
src/memory.S
Normal file
977
src/memory.S
Normal file
@ -0,0 +1,977 @@
|
||||
/*
|
||||
* Apple // emulator for Linux:
|
||||
* Functions for memory-access indirection table.
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "apple2.h"
|
||||
#include "cpu.h"
|
||||
#include "misc.h"
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
....................................................................
|
||||
Apple ][+ Memory documentation (//e differs mostly in softswitches)
|
||||
|
||||
I use two jump tables; one for get_memory and one for set_memory
|
||||
respectively. The jump tables contain exactly 64k entries to
|
||||
avoid unnecessary range checking. Furthermore, special access
|
||||
or to serve memory mapped I/O services are easily obtained by
|
||||
patching the jump table with various routines.
|
||||
|
||||
Apple 64k address space:
|
||||
|
||||
(Two byte addresses are represented with least significant
|
||||
byte first, e.g. address FA59 is represented as 59 FA)
|
||||
|
||||
Address Description
|
||||
|
||||
0000 - 00FF Zero page RAM
|
||||
0100 - 01FF Stack
|
||||
0200 - 03EF RAM
|
||||
03F0 - 03F1 Address for BRK instruction
|
||||
(normally 59 FA = FA59)
|
||||
03F2 - 03F3 Soft entry vector (normally BF 9D = 9DBF)
|
||||
03F4 Power-up byte
|
||||
03F5 - 03F7 Jump instruction to the subroutine which
|
||||
handles Applesoft II &-commands
|
||||
(normally 4C 58 FF = JMP FF58)
|
||||
03F8 - 03FA Jump instruction to the subroutine which
|
||||
handles User CTRL-Y commands
|
||||
(normally 4C 65 FF = JMP FF65)
|
||||
03FB - 03FD Jump instruction to the subroutine which
|
||||
handles Non-Maskable Interrupts (NMI)
|
||||
(normally 4C 65 FF = JMP FF65)
|
||||
03FE - 03FF Address of the subroutine which handles
|
||||
Interrupt ReQuests (IRQ)
|
||||
(normally 65 FF = FF65)
|
||||
0400 - 07FF Basically primary video text page
|
||||
0478 - 047F I/O Scratchpad RAM Addresses for Slot 0 - 7
|
||||
04F8 - 04FF - " " -
|
||||
0578 - 057F - " " -
|
||||
05F8 - 05FF - " " -
|
||||
0678 - 067F - " " -
|
||||
06F8 - 06FF - " " -
|
||||
0778 - 077F - " " -
|
||||
07F8 - 07FF - " " -
|
||||
----- These two addresses are pretty strange; the values
|
||||
provided were inconsistent at least on my Apple II
|
||||
05F8 Holds the slot number of the disk
|
||||
controller card from which DOS was
|
||||
booted.
|
||||
07F8 Holds the slot number (CX, X = Slot #)
|
||||
of the slot that is currently active.
|
||||
|
||||
0800 - 0BFF Basically secondary video text page
|
||||
|
||||
0C00 - 1FFF Plain RAM
|
||||
2000 - 3FFF Primary video hires page (RAM)
|
||||
4000 - 5FFF Secondary video Hi-Res page (RAM)
|
||||
6000 - BFFF Plain RAM
|
||||
(Normally the operating system is
|
||||
loaded into ~= 9C00 - BFFF)
|
||||
C000 - C00F Keyboard data
|
||||
(C00X contains the character ASCII
|
||||
code of the pressed key. The
|
||||
value is available at any C00X
|
||||
address)
|
||||
C010 - C01F Clear Keyboard strobe
|
||||
C020 - C02F Cassette output toggle
|
||||
C030 - C03F Speaker toggle
|
||||
C040 - C04F Utility strobe
|
||||
C050 Set graphics mode
|
||||
C051 Set text mode
|
||||
C052 Set all text or graphics
|
||||
C053 Mix text and graphics
|
||||
C054 Display primary page
|
||||
C055 Display secondary page
|
||||
C056 Display low-res graphics
|
||||
C057 Display hi-res graphics
|
||||
C058 - C05F Annunciator outputs
|
||||
C060 Cassette input
|
||||
C061 - C063 Pushbutton inputs (button 1, 2 and 3)
|
||||
C064 - C067 Game controller inputs
|
||||
C068 - C06F Same as C060 - C067
|
||||
C070 - C07F Game controller strobe
|
||||
C080 - C08F Slot 0 I/O space (usually a language card)
|
||||
--- If language card
|
||||
C080 Reset language card
|
||||
Read mode enabled
|
||||
Write mode disabled
|
||||
Read from language card
|
||||
Write to ROM (impossible of course)
|
||||
C081 --- First access
|
||||
Read mode disabled
|
||||
Read from ROM
|
||||
--- On second access
|
||||
Write mode enabled
|
||||
Write to language card
|
||||
C082 --- (Disable language card)
|
||||
Read mode disabled
|
||||
Write mode disabled
|
||||
Read from ROM
|
||||
Write to ROM
|
||||
C083 --- First access
|
||||
Read mode enabled
|
||||
Read from language card
|
||||
--- On second access
|
||||
Write mode enabled
|
||||
Write to language card
|
||||
C088 - C08B Same as C080 - C083, but
|
||||
switch to second bank, i.e.
|
||||
map addresses D000-DFFF to
|
||||
other 4k area.
|
||||
C100 - C1FF Slot 1 PROM
|
||||
C200 - C2FF Slot 2 PROM
|
||||
C300 - C3FF Slot 3 PROM
|
||||
C400 - C4FF Slot 4 PROM
|
||||
C500 - C5FF Slot 5 PROM
|
||||
C600 - C6FF Slot 6 PROM
|
||||
C700 - C7FF Slot 7 PROM
|
||||
C800 - CFFF Expansion ROM (for peripheral cards)
|
||||
CFFF Disable access to expansion ROM for
|
||||
ALL peripheral cards.
|
||||
D000 - DFFF ROM or 4k RAM if language card is
|
||||
enabled. However, there are TWO 4k
|
||||
banks that can be mapped onto addresses
|
||||
D000 - DFFF. See C088 - C08B.
|
||||
E000 - FFFF ROM or 8k RAM if language card is
|
||||
enabled.
|
||||
----------------------------------------------------------------- */
|
||||
|
||||
|
||||
.comm SN(softswitches),4
|
||||
|
||||
.comm SN(base_ramrd),4
|
||||
.comm SN(base_ramwrt),4
|
||||
.comm SN(base_textrd),4
|
||||
.comm SN(base_textwrt),4
|
||||
.comm SN(base_hgrrd),4
|
||||
.comm SN(base_hgrwrt),4
|
||||
|
||||
.comm SN(base_stackzp),4
|
||||
.comm SN(base_d000_rd),4
|
||||
.comm SN(base_d000_wrt),4
|
||||
.comm SN(base_e000_rd),4
|
||||
.comm SN(base_e000_wrt),4
|
||||
|
||||
.comm SN(base_cxrom),4
|
||||
.comm SN(base_c3rom),4
|
||||
|
||||
/* ram_nop, read_ram_default, write_ram_default: default ram/rom
|
||||
read/write functions. */
|
||||
E(ram_nop)
|
||||
ret
|
||||
|
||||
E(read_unmapped_softswitch)
|
||||
movb SN(apple_ii_64k)(,EffectiveAddr_E,1), %al
|
||||
ret
|
||||
|
||||
E(write_unmapped_softswitch)
|
||||
ret
|
||||
|
||||
E(read_keyboard)
|
||||
movb SN(apple_ii_64k)+0xC000, %al
|
||||
ret
|
||||
|
||||
E(read_keyboard_strobe)
|
||||
andb $0x7f, SN(apple_ii_64k)+0xC000
|
||||
andb $0x7f, SN(apple_ii_64k)+0x1C000
|
||||
movb SN(apple_ii_64k)+0xC000, %al /* HACK: necessary? */
|
||||
ret
|
||||
|
||||
E(read_random)
|
||||
pushal
|
||||
call SN(c_read_random)
|
||||
popal
|
||||
movb SN(random_value), %al
|
||||
ret
|
||||
|
||||
E(read_speaker_toggle_pc)
|
||||
inb $0x61, %al
|
||||
xorb $0x2, %al
|
||||
outb %al, $0x61
|
||||
ret
|
||||
|
||||
E(read_switch_primary_page)
|
||||
testl $SS_PAGE2, SN(softswitches)
|
||||
jnz _read_switch_primary
|
||||
ret
|
||||
_read_switch_primary:
|
||||
andl $~(SS_PAGE2|SS_SCREEN), SN(softswitches)
|
||||
pushal
|
||||
pushl $0
|
||||
call SN(video_setpage)
|
||||
addl $4, %esp
|
||||
popal
|
||||
ret
|
||||
|
||||
E(read_switch_secondary_page)
|
||||
testl $SS_PAGE2, SN(softswitches)
|
||||
jz _read_switch_secondary
|
||||
ret
|
||||
_read_switch_secondary:
|
||||
orl $(SS_PAGE2|SS_SCREEN), SN(softswitches)
|
||||
pushal
|
||||
pushl $1
|
||||
call SN(video_setpage)
|
||||
addl $4, %esp
|
||||
popal
|
||||
ret
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* PAGE2 off. if 80STORE on then we use main text page1, and if HIRES
|
||||
on we also use main hires page1, regardless of RAMRD and
|
||||
RAMWRT. */
|
||||
E(iie_page2_off)
|
||||
testl $SS_PAGE2, SN(softswitches) # already off?
|
||||
jz ram_nop
|
||||
andl $~(SS_PAGE2|SS_SCREEN), SN(softswitches)
|
||||
testl $SS_80STORE, SN(softswitches)
|
||||
jz _iie_page2_off_hires_off # no 80STORE
|
||||
andl $~(SS_TEXTRD|SS_TEXTWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_textrd)
|
||||
movl $SN(apple_ii_64k), SN(base_textwrt)
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jz _iie_page2_off_hires_off # no HIRES
|
||||
andl $~(SS_HGRRD|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrrd)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrwrt)
|
||||
_iie_page2_off_hires_off:
|
||||
pushal
|
||||
pushl $0 # page 1 main
|
||||
call SN(video_setpage)
|
||||
addl $4, %esp
|
||||
popal
|
||||
/* call SN(video_redraw)# redraw */
|
||||
ret
|
||||
|
||||
|
||||
/* PAGE2 on. if 80STORE on then we use aux text page 1, and if HIRES
|
||||
on we also use aux hires page 1, regardless of RAMRD and
|
||||
RAMWRT. */
|
||||
E(iie_page2_on)
|
||||
testl $SS_PAGE2, SN(softswitches) # already on?
|
||||
jnz ram_nop
|
||||
orl $SS_PAGE2, SN(softswitches)
|
||||
testl $SS_80STORE, SN(softswitches)
|
||||
jz _iie_page2_on_80store_off # no 80STORE
|
||||
orl $(SS_TEXTRD|SS_TEXTWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_textrd)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_textwrt)
|
||||
testl $(SS_HIRES), SN(softswitches)
|
||||
jz _iie_page2_on_cont
|
||||
orl $(SS_HGRRD|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrrd)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrwrt)
|
||||
_iie_page2_on_cont:
|
||||
ret
|
||||
|
||||
_iie_page2_on_80store_off: # no 80STORE
|
||||
orl $SS_SCREEN, SN(softswitches)
|
||||
pushal
|
||||
pushl $1 # page 2 main
|
||||
call SN(video_setpage)
|
||||
addl $4, %esp
|
||||
popal
|
||||
/* call SN(video_redraw)# redraw */
|
||||
ret
|
||||
#endif
|
||||
|
||||
E(read_switch_graphics)
|
||||
testl $SS_TEXT, SN(softswitches)
|
||||
jz ram_nop
|
||||
andl $~SS_TEXT, SN(softswitches)
|
||||
call SN(video_redraw)
|
||||
ret
|
||||
|
||||
E(read_switch_text)
|
||||
testl $SS_TEXT, SN(softswitches)
|
||||
jnz ram_nop
|
||||
orl $SS_TEXT, SN(softswitches)
|
||||
call SN(video_redraw)
|
||||
ret
|
||||
|
||||
E(read_switch_no_mixed)
|
||||
testl $SS_MIXED, SN(softswitches)
|
||||
jz ram_nop
|
||||
andl $~SS_MIXED, SN(softswitches)
|
||||
call SN(video_redraw)
|
||||
ret
|
||||
|
||||
E(read_switch_mixed)
|
||||
testl $SS_MIXED, SN(softswitches)
|
||||
jnz ram_nop
|
||||
orl $SS_MIXED, SN(softswitches)
|
||||
call SN(video_redraw)
|
||||
ret
|
||||
|
||||
E(read_switch_lores)
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jz ram_nop
|
||||
andl $~SS_HIRES, SN(softswitches)
|
||||
call SN(video_redraw)
|
||||
ret
|
||||
|
||||
E(read_switch_hires)
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jnz ram_nop
|
||||
orl $SS_HIRES, SN(softswitches)
|
||||
call SN(video_redraw)
|
||||
ret
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* HIRES off. use RAMRD/RAMWRT offsets for hires page 1. */
|
||||
E(iie_hires_off)
|
||||
testl $SS_HIRES, SN(softswitches) # already off?
|
||||
jz ram_nop
|
||||
andl $~(SS_HIRES|SS_HGRRD|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrrd)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrwrt)
|
||||
testl $SS_RAMRD,SN(softswitches)
|
||||
jz iie_hires_off_no_ramrd
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrrd)
|
||||
orl $SS_HGRRD, SN(softswitches)
|
||||
iie_hires_off_no_ramrd:
|
||||
testl $SS_RAMWRT,SN(softswitches)
|
||||
jz iie_hires_off_no_ramwrt
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrwrt)
|
||||
orl $SS_HGRWRT, SN(softswitches)
|
||||
iie_hires_off_no_ramwrt:
|
||||
call SN(video_redraw) # update screen
|
||||
ret
|
||||
|
||||
/* HIRES on. if 80STORE on, use PAGE2 offset for hires page 1. */
|
||||
E(iie_hires_on)
|
||||
testl $SS_HIRES, SN(softswitches) # already on?
|
||||
jnz ram_nop
|
||||
orl $SS_HIRES, SN(softswitches) # hires on
|
||||
testl $SS_80STORE, SN(softswitches)
|
||||
jz iie_hires_on_80store_off # no 80STORE
|
||||
testl $SS_PAGE2, SN(softswitches)
|
||||
jz iie_hires_on_80store_aux
|
||||
andl $~(SS_HGRRD|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrrd)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrwrt)
|
||||
jmp iie_hires_on_80store_off
|
||||
iie_hires_on_80store_aux:
|
||||
orl $(SS_HGRRD|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrrd)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrwrt)
|
||||
iie_hires_on_80store_off:
|
||||
call SN(video_redraw) # update screen
|
||||
ret
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
.comm joy_trigger0, 2
|
||||
.comm joy_trigger1, 2
|
||||
.comm joy_trigger2, 2
|
||||
.comm joy_trigger3, 2
|
||||
|
||||
E(read_button0)
|
||||
movb SN(joy_button0), %al
|
||||
ret
|
||||
|
||||
E(read_button1)
|
||||
movb SN(joy_button1), %al
|
||||
ret
|
||||
|
||||
E(read_button2)
|
||||
movb SN(joy_button2), %al
|
||||
ret
|
||||
|
||||
E(read_gc0)
|
||||
cmpw $0xFF, joy_trigger0
|
||||
je read_gc0_cont
|
||||
incw joy_trigger0
|
||||
read_gc0_cont:
|
||||
movw joy_trigger0, %ax
|
||||
cmpw %ax, SN(joy_x)
|
||||
jge read_gc0_ff /* XXXX is this correct? */
|
||||
movb $0, %al
|
||||
ret
|
||||
read_gc0_ff:
|
||||
movb $0xFF, %al
|
||||
ret
|
||||
|
||||
E(read_gc1)
|
||||
cmpw $0xFF, joy_trigger1
|
||||
je read_gc1_cont
|
||||
incw joy_trigger1
|
||||
read_gc1_cont:
|
||||
movw joy_trigger1, %ax
|
||||
cmpw %ax, SN(joy_y)
|
||||
jge read_gc1_ff
|
||||
movb $0, %al
|
||||
ret
|
||||
read_gc1_ff:
|
||||
movb $0xFF, %al
|
||||
ret
|
||||
|
||||
/* HACK not doing anything... */
|
||||
E(iie_read_gc2)
|
||||
ret
|
||||
|
||||
E(iie_read_gc3)
|
||||
ret
|
||||
|
||||
E(read_gc_strobe)
|
||||
movb $0, joy_trigger0
|
||||
movb $0, joy_trigger1
|
||||
movb $0, joy_trigger2
|
||||
movb $0, joy_trigger3
|
||||
ret
|
||||
|
||||
E(iie_c080)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jz lc_c080
|
||||
pushl $lc_to_auxmem /* sneak this code in when
|
||||
* ][+ routine exits */
|
||||
|
||||
/* c080: read RAM; no write; use $D000 bank 2. */
|
||||
E(lc_c080)
|
||||
orl $SS_LCRAM|SS_BANK2, SN(softswitches)
|
||||
andl $~(SS_LCSEC|SS_LCWRT), SN(softswitches)
|
||||
movl $SN(language_banks)-0xD000, SN(base_d000_rd)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_rd)
|
||||
movl $0, SN(base_d000_wrt)
|
||||
movl $0, SN(base_e000_wrt)
|
||||
ret
|
||||
|
||||
E(iie_c081)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jz lc_c081
|
||||
pushl $lc_to_auxmem /* sneak this code in when
|
||||
* ][+ routine exits */
|
||||
|
||||
/* c081: read ROM; write RAM; use $D000 bank 2. */
|
||||
E(lc_c081)
|
||||
testl $SS_LCSEC, SN(softswitches)
|
||||
je lc_c081_exit
|
||||
orl $SS_LCWRT, SN(softswitches)
|
||||
movl $SN(language_banks)-0xD000, SN(base_d000_wrt)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_wrt)
|
||||
lc_c081_exit:
|
||||
andl $~SS_LCRAM, SN(softswitches)
|
||||
orl $SS_LCSEC|SS_BANK2, SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_d000_rd)
|
||||
movl $SN(apple_ii_64k), SN(base_e000_rd)
|
||||
ret
|
||||
|
||||
/* There is no iie_c082 --- since the LC is offline, no auxillary memory
|
||||
* could be exposed. (ditto for c08a) */
|
||||
|
||||
/* c082: read ROM; no write; use $D000 bank 2. */
|
||||
E(lc_c082)
|
||||
andl $~(SS_LCRAM|SS_LCWRT|SS_LCSEC), SN(softswitches)
|
||||
orl $SS_BANK2, SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_d000_rd)
|
||||
movl $SN(apple_ii_64k), SN(base_e000_rd)
|
||||
movl $0, SN(base_d000_wrt)
|
||||
movl $0, SN(base_e000_wrt)
|
||||
ret
|
||||
|
||||
E(iie_c083)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jz lc_c083
|
||||
pushl $lc_to_auxmem /* sneak this code in when
|
||||
* ][+ routine exits */
|
||||
|
||||
/* c083: read and write RAM; no write; use $D000 bank 2. */
|
||||
E(lc_c083) testl $SS_LCSEC, SN(softswitches)
|
||||
je lc_c083_exit
|
||||
orl $SS_LCWRT, SN(softswitches)
|
||||
movl $SN(language_banks)-0xD000, SN(base_d000_wrt)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_wrt)
|
||||
lc_c083_exit:
|
||||
orl $(SS_LCSEC|SS_LCRAM|SS_BANK2), SN(softswitches)
|
||||
movl $SN(language_banks)-0xD000, SN(base_d000_rd)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_rd)
|
||||
ret
|
||||
|
||||
E(iie_c088)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jz lc_c088
|
||||
pushl $lc_to_auxmem /* sneak this code in when
|
||||
* ][+ routine exits */
|
||||
|
||||
/* c088: read RAM; no write; use $D000 bank 1. */
|
||||
E(lc_c088)
|
||||
orl $(SS_LCRAM), SN(softswitches)
|
||||
andl $~(SS_LCWRT|SS_LCSEC|SS_BANK2), SN(softswitches)
|
||||
movl $SN(language_banks)-0xC000, SN(base_d000_rd)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_rd)
|
||||
movl $0, SN(base_d000_wrt)
|
||||
movl $0, SN(base_e000_wrt)
|
||||
ret
|
||||
|
||||
E(iie_c089)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jz lc_c089
|
||||
pushl $lc_to_auxmem /* sneak this code in when
|
||||
* ][+ routine exits */
|
||||
|
||||
/* c089: read ROM; write RAM; use $D000 bank 1. */
|
||||
E(lc_c089)
|
||||
testl $SS_LCSEC, SN(softswitches)
|
||||
jz lc_c089_exit
|
||||
orl $SS_LCWRT, SN(softswitches)
|
||||
movl $SN(language_banks)-0xC000, SN(base_d000_wrt)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_wrt)
|
||||
lc_c089_exit:
|
||||
andl $~(SS_LCRAM|SS_BANK2), SN(softswitches)
|
||||
orl $(SS_LCSEC), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_d000_rd)
|
||||
movl $SN(apple_ii_64k), SN(base_e000_rd)
|
||||
ret
|
||||
|
||||
/* there is no iie_c08a */
|
||||
|
||||
/* c08a: read ROM; no write; use $D000 bank 1. */
|
||||
E(lc_c08a)
|
||||
andl $~(SS_LCRAM|SS_LCWRT|SS_LCSEC|SS_BANK2), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_d000_rd)
|
||||
movl $SN(apple_ii_64k), SN(base_e000_rd)
|
||||
movl $0, SN(base_d000_wrt)
|
||||
movl $0, SN(base_e000_wrt)
|
||||
ret
|
||||
|
||||
E(iie_c08b)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jz lc_c08b
|
||||
pushl $lc_to_auxmem /* sneak this code in when
|
||||
* ][+ routine exits */
|
||||
|
||||
/* c08b: read and write RAM; use $D000 bank 1. */
|
||||
E(lc_c08b)
|
||||
testl $SS_LCSEC, SN(softswitches)
|
||||
jz lc_c08b_exit
|
||||
orl $SS_LCWRT, SN(softswitches)
|
||||
movl $SN(language_banks)-0xC000, SN(base_d000_wrt)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_wrt)
|
||||
lc_c08b_exit:
|
||||
orl $(SS_LCRAM|SS_LCSEC), SN(softswitches)
|
||||
andl $~SS_BANK2,SN(softswitches)
|
||||
movl $SN(language_banks)-0xC000, SN(base_d000_rd)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_rd)
|
||||
ret
|
||||
/* -------------------------------------------------------------------------
|
||||
* misc //e functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
|
||||
/* 80STORE off. use RAMRD/RAMWRT for text/hires display page 1 */
|
||||
E(iie_80store_off)
|
||||
testl $SS_80STORE, SN(softswitches) # already off?
|
||||
jz ram_nop
|
||||
andl $~(SS_80STORE|SS_TEXTRD|SS_TEXTWRT|SS_HGRRD|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k),SN(base_textrd)
|
||||
movl $SN(apple_ii_64k),SN(base_textwrt)
|
||||
movl $SN(apple_ii_64k),SN(base_hgrrd)
|
||||
movl $SN(apple_ii_64k),SN(base_hgrwrt)
|
||||
testl $SS_RAMRD, SN(softswitches)
|
||||
jz iie_80store_off_noramrd
|
||||
orl $(SS_TEXTRD|SS_HGRRD),SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2,SN(base_textrd)
|
||||
movl $SN(apple_ii_64k)+BANK2,SN(base_hgrrd)
|
||||
iie_80store_off_noramrd:
|
||||
testl $SS_RAMRD, SN(softswitches)
|
||||
jz iie_80store_off_noramwrt
|
||||
orl $(SS_TEXTWRT|SS_HGRWRT),SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2,SN(base_textwrt)
|
||||
movl $SN(apple_ii_64k)+BANK2,SN(base_hgrwrt)
|
||||
iie_80store_off_noramwrt:
|
||||
testl $SS_PAGE2, SN(softswitches)
|
||||
jz ram_nop
|
||||
orl $SS_SCREEN, SN(softswitches)
|
||||
pushal
|
||||
pushl $1
|
||||
call SN(video_setpage)
|
||||
addl $4, %esp
|
||||
popal
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
|
||||
/* 80STORE on. we use PAGE2 offset to access text page 1. if HIRES on
|
||||
we also use PAGE2 offset to access hires page 1 */
|
||||
E(iie_80store_on)
|
||||
testl $SS_80STORE, SN(softswitches) # already on?
|
||||
jnz ram_nop
|
||||
orl $SS_80STORE, SN(softswitches)
|
||||
testl $SS_PAGE2, SN(softswitches)
|
||||
jnz iie_80store_on_page2_on
|
||||
andl $~(SS_TEXTRD|SS_TEXTWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_textrd)
|
||||
movl $SN(apple_ii_64k), SN(base_textwrt)
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jz iie_80store_on_cont
|
||||
andl $~(SS_HGRRD|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrrd)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrwrt)
|
||||
jmp iie_80store_on_cont
|
||||
|
||||
iie_80store_on_page2_on:
|
||||
orl $(SS_TEXTRD|SS_TEXTWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_textrd)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_textwrt)
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jz iie_80store_on_cont
|
||||
orl $(SS_HGRRD|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrrd)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrwrt)
|
||||
iie_80store_on_cont:
|
||||
andl $~SS_SCREEN, SN(softswitches)
|
||||
pushal
|
||||
pushl $0 # page 1
|
||||
call SN(video_setpage)
|
||||
addl $4, %esp
|
||||
popal
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
|
||||
return80: movb $0x80,%al
|
||||
ret
|
||||
|
||||
E(iie_check_80store)
|
||||
testl $SS_80STORE,SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al,%al
|
||||
ret
|
||||
|
||||
/* RAMRD main. if 80STORE off then text/hires display pages are in
|
||||
main memory. */
|
||||
E(iie_ramrd_main)
|
||||
testl $SS_RAMRD, SN(softswitches) # already off?
|
||||
jz ram_nop
|
||||
andl $~SS_RAMRD, SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_ramrd)
|
||||
testl $SS_80STORE, SN(softswitches) # 80store?
|
||||
jnz iie_ramrd_main_80store_on
|
||||
andl $~(SS_TEXTRD|SS_HGRRD), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_textrd)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrrd)
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
iie_ramrd_main_80store_on:
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jnz ram_nop
|
||||
andl $~SS_HGRRD, SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrrd)
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
|
||||
/* RAMRD aux. if 80STORE off then text/hires display pages are in aux
|
||||
memory. */
|
||||
E(iie_ramrd_aux)
|
||||
testl $SS_RAMRD, SN(softswitches) # already on?
|
||||
jnz ram_nop
|
||||
orl $SS_RAMRD, SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_ramrd)
|
||||
testl $SS_80STORE, SN(softswitches) # 80store?
|
||||
jnz iie_ramrd_aux_80store_on
|
||||
orl $(SS_TEXTRD|SS_HGRRD), SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_textrd)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrrd)
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
iie_ramrd_aux_80store_on:
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jnz ram_nop # already set
|
||||
orl $(SS_HGRRD), SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrrd)
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
|
||||
E(iie_check_ramrd)
|
||||
testl $SS_RAMRD, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al,%al
|
||||
ret
|
||||
|
||||
/* RAMWRT main. if 80STORE off then text/hires display pages are in
|
||||
main memory. */
|
||||
E(iie_ramwrt_main)
|
||||
testl $SS_RAMWRT, SN(softswitches) # already off?
|
||||
jz ram_nop
|
||||
andl $~SS_RAMWRT, SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_ramwrt) # main RAM
|
||||
testl $SS_80STORE, SN(softswitches) # 80store?
|
||||
jnz iie_ramwrt_main_80store_on
|
||||
andl $~(SS_TEXTWRT|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_textwrt)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrwrt)
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
iie_ramwrt_main_80store_on:
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jnz ram_nop
|
||||
andl $~SS_HGRWRT, SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_hgrwrt)
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
|
||||
/* RAMWRT aux. if 80STORE off then write to text/hires display pages
|
||||
are in aux memory. */
|
||||
E(iie_ramwrt_aux)
|
||||
testl $SS_RAMWRT, SN(softswitches) # already on?
|
||||
jnz ram_nop
|
||||
orl $SS_RAMWRT, SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_ramwrt) # aux RAM
|
||||
testl $SS_80STORE, SN(softswitches) # 80store?
|
||||
jnz iie_ramwrt_aux_80store_on
|
||||
orl $(SS_TEXTWRT|SS_HGRWRT), SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_textwrt)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrwrt)
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
iie_ramwrt_aux_80store_on:
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jnz ram_nop
|
||||
orl $SS_HGRWRT, SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_hgrwrt)
|
||||
/* call SN(video_redraw) # redraw */
|
||||
ret
|
||||
|
||||
E(iie_check_ramwrt)
|
||||
testl $SS_RAMWRT, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_altzp_main)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jz 1f /* test if ALTZP already off -
|
||||
* due to d000-bank issues it is
|
||||
* *needed*, not just a shortcut */
|
||||
andl $~SS_ALTZP, SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_stackzp)
|
||||
andl $0xFFFF, SP_Reg
|
||||
testl $SS_LCRAM|SS_LCWRT, SN(softswitches)
|
||||
jz 1f /* shortest path for common case */
|
||||
testl $SS_LCRAM, SN(softswitches)
|
||||
jz 2f
|
||||
subl $0x2000, SN(base_d000_rd)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_rd)
|
||||
2: testl $SS_LCWRT, SN(softswitches)
|
||||
jz 1f
|
||||
subl $0x2000, SN(base_d000_wrt)
|
||||
movl $SN(language_card)-0xE000, SN(base_e000_wrt)
|
||||
1: ret
|
||||
|
||||
E(iie_altzp_aux)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jnz 1f /* test if ALTZP already on -
|
||||
* due to d000-bank issues it is
|
||||
* *needed*, not just a shortcut */
|
||||
orl $SS_ALTZP, SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_stackzp)
|
||||
orl $BANK2, SP_Reg
|
||||
testl $SS_LCRAM|SS_LCWRT, SN(softswitches)
|
||||
jz 1f /* shortest path for common case */
|
||||
lc_to_auxmem: /* called by lc routines */
|
||||
testl $SS_LCRAM, SN(softswitches)
|
||||
jz 2f
|
||||
addl $0x2000, SN(base_d000_rd)
|
||||
movl $SN(language_card)-0xC000, SN(base_e000_rd)
|
||||
2: testl $SS_LCWRT, SN(softswitches)
|
||||
jz 1f
|
||||
addl $0x2000, SN(base_d000_wrt)
|
||||
movl $SN(language_card)-0xC000, SN(base_e000_wrt)
|
||||
1: ret
|
||||
|
||||
E(iie_check_altzp)
|
||||
testl $SS_ALTZP, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_80col_off)
|
||||
testl $SS_80COL, SN(softswitches)
|
||||
jz ram_nop
|
||||
andl $~SS_80COL, SN(softswitches)
|
||||
testl $(SS_TEXT|SS_MIXED|SS_DHIRES), SN(softswitches)
|
||||
jnz SN(video_redraw)
|
||||
ret
|
||||
|
||||
E(iie_80col_on)
|
||||
testl $SS_80COL, SN(softswitches)
|
||||
jnz ram_nop
|
||||
orl $SS_80COL, SN(softswitches)
|
||||
testl $(SS_TEXT|SS_MIXED|SS_DHIRES), SN(softswitches)
|
||||
jnz SN(video_redraw)
|
||||
ret
|
||||
|
||||
E(iie_check_80col)
|
||||
testl $SS_80COL, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_altchar_off)
|
||||
testl $SS_ALTCHAR, SN(softswitches)
|
||||
jz ram_nop
|
||||
andl $~SS_ALTCHAR, SN(softswitches)
|
||||
pushal
|
||||
call SN(c_set_primary_char)
|
||||
popal
|
||||
ret
|
||||
|
||||
E(iie_altchar_on)
|
||||
testl $SS_ALTCHAR, SN(softswitches)
|
||||
jnz ram_nop
|
||||
orl $SS_ALTCHAR, SN(softswitches)
|
||||
pushal
|
||||
call SN(c_set_altchar)
|
||||
popal
|
||||
ret
|
||||
|
||||
E(iie_check_altchar)
|
||||
testl $SS_ALTCHAR, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
/* unset ioudis flag and read_gc_strobe */
|
||||
E(iie_ioudis_off)
|
||||
andl $~SS_IOUDIS, SN(softswitches)
|
||||
jmp SN(read_gc_strobe)
|
||||
|
||||
/* set ioudis flag and read_gc_strobe */
|
||||
E(iie_ioudis_on)
|
||||
orl $SS_IOUDIS, SN(softswitches)
|
||||
jmp SN(read_gc_strobe)
|
||||
|
||||
/* check ioudis flag and read_gc_strobe */
|
||||
E(iie_check_ioudis)
|
||||
call SN(read_gc_strobe)
|
||||
testl $SS_IOUDIS, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_dhires_on)
|
||||
testl $SS_IOUDIS, SN(softswitches)
|
||||
jz ram_nop
|
||||
orl $SS_DHIRES, SN(softswitches)
|
||||
call SN(video_redraw)
|
||||
ret
|
||||
|
||||
E(iie_dhires_off)
|
||||
testl $SS_IOUDIS, SN(softswitches)
|
||||
jz ram_nop
|
||||
andl $~SS_DHIRES, SN(softswitches)
|
||||
call SN(video_redraw)
|
||||
ret
|
||||
|
||||
/* check dhires flag and read_gc_strobe */
|
||||
E(iie_check_dhires)
|
||||
call SN(read_gc_strobe)
|
||||
testl $SS_DHIRES, SN(softswitches)
|
||||
jnz return80
|
||||
ret
|
||||
|
||||
E(iie_check_text)
|
||||
testl $SS_TEXT, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_check_mixed)
|
||||
testl $SS_MIXED, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_check_page2)
|
||||
testl $SS_PAGE2, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_check_hires)
|
||||
testl $SS_HIRES, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_check_bank)
|
||||
testl $SS_BANK2, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_check_lcram)
|
||||
testl $SS_LCRAM, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
/* HACK not doing anything... */
|
||||
E(iie_check_vbl)
|
||||
ret
|
||||
|
||||
/* ---------------------------------- */
|
||||
|
||||
E(iie_c3rom_peripheral)
|
||||
andl $~SS_C3ROM, SN(softswitches)
|
||||
testl $SS_CXROM, SN(softswitches)
|
||||
jnz 1f /* CXROM-internal preempts C3ROM */
|
||||
movl $SN(apple_ii_64k), SN(base_c3rom)
|
||||
1: ret
|
||||
|
||||
E(iie_c3rom_internal)
|
||||
orl $SS_C3ROM, SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_c3rom)
|
||||
ret
|
||||
|
||||
E(iie_check_c3rom)
|
||||
testl $SS_C3ROM, SN(softswitches)
|
||||
jz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
E(iie_cxrom_peripheral)
|
||||
andl $~SS_CXROM, SN(softswitches)
|
||||
movl $SN(apple_ii_64k), SN(base_cxrom)
|
||||
testl $SS_C3ROM, SN(softswitches)
|
||||
jnz 1f
|
||||
movl $SN(apple_ii_64k), SN(base_c3rom)
|
||||
1: ret
|
||||
|
||||
E(iie_cxrom_internal)
|
||||
orl $SS_CXROM, SN(softswitches)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_cxrom)
|
||||
movl $SN(apple_ii_64k)+BANK2, SN(base_c3rom)
|
||||
ret
|
||||
|
||||
E(iie_check_cxrom)
|
||||
testl $SS_CXROM, SN(softswitches)
|
||||
jnz return80
|
||||
xorb %al, %al
|
||||
ret
|
||||
|
||||
/* HACK!!!!! - how does the expansion slot get referenced? need to handle other roms requesting to use this area!!!! */
|
||||
E(iie_read_slot_expansion)
|
||||
orl SN(c8rom_offset), EffectiveAddr_E
|
||||
movb SN(apple_ii_64k)(,EffectiveAddr_E,1), %al
|
||||
andl $0xFFFF, EffectiveAddr_E
|
||||
ret
|
||||
|
||||
/* HACK!!!!! - how does the expansion slot get referenced? */
|
||||
E(iie_disable_slot_expansion)
|
||||
ret
|
||||
|
||||
#endif /* APPLE_IIE */
|
745
src/misc.c
Normal file
745
src/misc.c
Normal file
@ -0,0 +1,745 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Miscellaneous support
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "video.h"
|
||||
#include "disk.h"
|
||||
#include "interface.h"
|
||||
#include "keys.h"
|
||||
#ifdef DEBUGGER
|
||||
#include "debug.h"
|
||||
#endif
|
||||
#include "cpu.h"
|
||||
#include "glue.h"
|
||||
#include "prefs.h"
|
||||
|
||||
const struct itimerval timer_off = {{0,0},{0,0}};
|
||||
const struct itimerval timer_on = {{0,TIMER_DELAY},{0,TIMER_DELAY}};
|
||||
|
||||
/* ----------------------------------
|
||||
internal apple2 variables
|
||||
---------------------------------- */
|
||||
|
||||
static unsigned char apple_ii_rom[12288];
|
||||
#ifdef APPLE_IIE
|
||||
static unsigned char apple_iie_rom[32768]; /* //e */
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGGER
|
||||
/* in debugger.c */
|
||||
extern int breakpoints[];
|
||||
extern int watchpoints[];
|
||||
extern int op_breakpoints[256];
|
||||
#endif
|
||||
|
||||
GLUE_FIXED_READ(read_ram_default,apple_ii_64k)
|
||||
GLUE_FIXED_WRITE(write_ram_default,apple_ii_64k)
|
||||
GLUE_BANK_READ(read_ram_bank,base_d000_rd)
|
||||
GLUE_BANK_MAYBEWRITE(write_ram_bank,base_d000_wrt)
|
||||
GLUE_BANK_READ(read_ram_lc,base_e000_rd)
|
||||
GLUE_BANK_MAYBEWRITE(write_ram_lc,base_e000_wrt)
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
|
||||
GLUE_BANK_READ(iie_read_ram_default,base_ramrd)
|
||||
GLUE_BANK_WRITE(iie_write_ram_default,base_ramwrt)
|
||||
GLUE_BANK_READ(iie_read_ram_text_page0,base_textrd)
|
||||
GLUE_BANK_WRITE(iie_write_screen_hole_text_page0,base_textwrt)
|
||||
GLUE_BANK_READ(iie_read_ram_hires_page0,base_hgrrd)
|
||||
GLUE_BANK_WRITE(iie_write_screen_hole_hires_page0,base_hgrwrt)
|
||||
|
||||
GLUE_BANK_READ(iie_read_ram_zpage_and_stack,base_stackzp)
|
||||
GLUE_BANK_WRITE(iie_write_ram_zpage_and_stack,base_stackzp)
|
||||
|
||||
GLUE_BANK_READ(iie_read_slot3,base_c3rom)
|
||||
GLUE_BANK_READ(iie_read_slotx,base_cxrom)
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_set_altchar() - set alternate character set
|
||||
------------------------------------------------------------------------- */
|
||||
void c_set_altchar()
|
||||
{
|
||||
video_loadfont(0x40,0x20,mousetext_glyphs,1);
|
||||
video_loadfont(0x60,0x20,lcase_glyphs,2);
|
||||
|
||||
video_redraw();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_set_primary_char() - set primary character set
|
||||
------------------------------------------------------------------------- */
|
||||
void c_set_primary_char()
|
||||
{
|
||||
video_loadfont(0x40,0x40,ucase_glyphs,3);
|
||||
|
||||
video_redraw();
|
||||
}
|
||||
|
||||
#endif/* APPLE_IIE */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_font(): Initialize ROM character table to primary char set
|
||||
------------------------------------------------------------------------- */
|
||||
void c_initialize_font()
|
||||
{
|
||||
video_loadfont(0x00,0x40,ucase_glyphs,2);
|
||||
video_loadfont(0x40,0x40,ucase_glyphs,3);
|
||||
video_loadfont(0x80,0x40,ucase_glyphs,0);
|
||||
video_loadfont(0xC0,0x20,ucase_glyphs,0);
|
||||
video_loadfont(0xE0,0x20,lcase_glyphs,0);
|
||||
|
||||
video_redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_tables()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void c_initialize_tables() {
|
||||
|
||||
int i;
|
||||
|
||||
pre_compact(); /* Prepare for VM compression */
|
||||
|
||||
/* reset everything */
|
||||
for (i = 0; i < 0x10000; i++) {
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[i].r = iie_read_ram_default;
|
||||
cpu65_vmem[i].w = iie_write_ram_default;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
cpu65_vmem[i].r = read_ram_default;
|
||||
cpu65_vmem[i].w = write_ram_default;
|
||||
}
|
||||
}
|
||||
|
||||
/* language card read/write area */
|
||||
for (i = 0xD000; i < 0xE000; i++) {
|
||||
{
|
||||
cpu65_vmem[i].w =
|
||||
write_ram_bank;
|
||||
cpu65_vmem[i].r =
|
||||
read_ram_bank;
|
||||
}
|
||||
}
|
||||
for (i = 0xE000; i < 0x10000; i++) {
|
||||
{
|
||||
cpu65_vmem[i].w =
|
||||
write_ram_lc;
|
||||
cpu65_vmem[i].r =
|
||||
read_ram_lc;
|
||||
}
|
||||
}
|
||||
/* done common initialization */
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* initialize zero-page, //e specific */
|
||||
if (apple_mode == IIE_MODE) {
|
||||
for (i = 0; i < 0x200; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
iie_read_ram_zpage_and_stack;
|
||||
cpu65_vmem[i].w =
|
||||
iie_write_ram_zpage_and_stack;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* initialize first text & hires page, which are specially bank switched
|
||||
*
|
||||
* video_set() substitutes it's own hooks for all visible write locations
|
||||
* affect the display, leaving our write-functions in place only at the
|
||||
* `screen holes', hence the name.
|
||||
*/
|
||||
for (i = 0x400; i < 0x800; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
iie_read_ram_text_page0;
|
||||
cpu65_vmem[i].w =
|
||||
iie_write_screen_hole_text_page0;
|
||||
}
|
||||
for (i = 0x2000; i < 0x4000; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
iie_read_ram_hires_page0;
|
||||
cpu65_vmem[i].w =
|
||||
iie_write_screen_hole_hires_page0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* softswich rom */
|
||||
for (i = 0xC000; i < 0xC100; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
read_unmapped_softswitch;
|
||||
cpu65_vmem[i].w =
|
||||
write_unmapped_softswitch;
|
||||
}
|
||||
|
||||
/* slot rom */
|
||||
for (i = 0xC100; i < 0xD000; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
#ifdef APPLE_IIE
|
||||
iie_read_ram_default;
|
||||
#else
|
||||
read_ram_default;
|
||||
#endif
|
||||
cpu65_vmem[i].w =
|
||||
ram_nop;
|
||||
}
|
||||
|
||||
/* keyboard data and strobe (READ) */
|
||||
for (i = 0xC000; i < 0xC010; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
read_keyboard;
|
||||
}
|
||||
for (i = 0xC010; i < 0xC020; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
cpu65_vmem[i].w =
|
||||
read_keyboard_strobe;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
|
||||
/* RDBNK2 switch */
|
||||
cpu65_vmem[0xC011].r =
|
||||
iie_check_bank;
|
||||
|
||||
/* RDLCRAM switch */
|
||||
cpu65_vmem[0xC012].r =
|
||||
iie_check_lcram;
|
||||
|
||||
/* 80STORE switch */
|
||||
cpu65_vmem[0xC000].w = iie_80store_off;
|
||||
cpu65_vmem[0xC001].w = iie_80store_on;
|
||||
cpu65_vmem[0xC018].r = iie_check_80store;
|
||||
|
||||
/* RAMRD switch */
|
||||
cpu65_vmem[0xC002].w = iie_ramrd_main;
|
||||
cpu65_vmem[0xC003].w = iie_ramrd_aux;
|
||||
cpu65_vmem[0xC013].r = iie_check_ramrd;
|
||||
|
||||
/* RAMWRT switch */
|
||||
cpu65_vmem[0xC004].w = iie_ramwrt_main;
|
||||
cpu65_vmem[0xC005].w = iie_ramwrt_aux;
|
||||
cpu65_vmem[0xC014].r = iie_check_ramwrt;
|
||||
|
||||
/* ALTZP switch */
|
||||
cpu65_vmem[0xC008].w = iie_altzp_main;
|
||||
cpu65_vmem[0xC009].w = iie_altzp_aux;
|
||||
cpu65_vmem[0xC016].r = iie_check_altzp;
|
||||
|
||||
/* 80COL switch */
|
||||
cpu65_vmem[0xC00C].w = iie_80col_off;
|
||||
cpu65_vmem[0xC00D].w = iie_80col_on;
|
||||
cpu65_vmem[0xC01F].r = iie_check_80col;
|
||||
|
||||
/* ALTCHAR switch */
|
||||
cpu65_vmem[0xC00E].w = iie_altchar_off;
|
||||
cpu65_vmem[0xC00F].w = iie_altchar_on;
|
||||
cpu65_vmem[0xC01E].r = iie_check_altchar;
|
||||
|
||||
/* SLOTC3ROM switch */
|
||||
cpu65_vmem[0xC00A].w = iie_c3rom_internal;
|
||||
cpu65_vmem[0xC00B].w = iie_c3rom_peripheral;
|
||||
cpu65_vmem[0xC017].r = iie_check_c3rom;
|
||||
|
||||
/* SLOTCXROM switch */
|
||||
cpu65_vmem[0xC006].w = iie_cxrom_peripheral;
|
||||
cpu65_vmem[0xC007].w = iie_cxrom_internal;
|
||||
cpu65_vmem[0xC015].r = iie_check_cxrom;
|
||||
|
||||
/* RDVBLBAR switch */
|
||||
cpu65_vmem[0xC019].r =
|
||||
iie_check_vbl;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* random number generator */
|
||||
for (i = 0xC020; i < 0xC030; i++)
|
||||
cpu65_vmem[i].r =
|
||||
cpu65_vmem[i].w =
|
||||
read_random;
|
||||
|
||||
/* TEXT switch */
|
||||
cpu65_vmem[0xC050].r =
|
||||
cpu65_vmem[0xC050].w =
|
||||
read_switch_graphics;
|
||||
cpu65_vmem[0xC051].r =
|
||||
cpu65_vmem[0xC051].w =
|
||||
read_switch_text;
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[0xC01A].r =
|
||||
iie_check_text;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* MIXED switch */
|
||||
cpu65_vmem[0xC052].r =
|
||||
cpu65_vmem[0xC052].w =
|
||||
read_switch_no_mixed;
|
||||
cpu65_vmem[0xC053].r =
|
||||
cpu65_vmem[0xC053].w =
|
||||
read_switch_mixed;
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[0xC01B].r =
|
||||
iie_check_mixed;
|
||||
}
|
||||
/* PAGE2 switch */
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[0xC054].r =
|
||||
cpu65_vmem[0xC054].w =
|
||||
iie_page2_off;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
cpu65_vmem[0xC054].r =
|
||||
cpu65_vmem[0xC054].w =
|
||||
read_switch_primary_page;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[0xC01C].r =
|
||||
iie_check_page2;
|
||||
}
|
||||
/* PAGE2 switch */
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[0xC055].r =
|
||||
cpu65_vmem[0xC055].w =
|
||||
iie_page2_on;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
cpu65_vmem[0xC055].r =
|
||||
cpu65_vmem[0xC055].w =
|
||||
read_switch_secondary_page;
|
||||
}
|
||||
|
||||
/* HIRES switch */
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[0xC01D].r =
|
||||
iie_check_hires;
|
||||
cpu65_vmem[0xC056].r =
|
||||
cpu65_vmem[0xC056].w =
|
||||
iie_hires_off;
|
||||
cpu65_vmem[0xC057].r =
|
||||
cpu65_vmem[0xC057].w =
|
||||
iie_hires_on;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cpu65_vmem[0xC056].r =
|
||||
cpu65_vmem[0xC056].w =
|
||||
read_switch_lores;
|
||||
cpu65_vmem[0xC057].r =
|
||||
cpu65_vmem[0xC057].w =
|
||||
read_switch_hires;
|
||||
}
|
||||
|
||||
/* game I/O switches */
|
||||
cpu65_vmem[0xC061].r =
|
||||
cpu65_vmem[0xC069].r =
|
||||
read_button0;
|
||||
cpu65_vmem[0xC062].r =
|
||||
cpu65_vmem[0xC06A].r =
|
||||
read_button1;
|
||||
cpu65_vmem[0xC063].r =
|
||||
cpu65_vmem[0xC06B].r =
|
||||
read_button2;
|
||||
cpu65_vmem[0xC064].r =
|
||||
cpu65_vmem[0xC06C].r =
|
||||
read_gc0;
|
||||
cpu65_vmem[0xC065].r =
|
||||
cpu65_vmem[0xC06D].r =
|
||||
read_gc1;
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[0xC066].r =
|
||||
iie_read_gc2;
|
||||
cpu65_vmem[0xC067].r =
|
||||
iie_read_gc3;
|
||||
}
|
||||
#endif
|
||||
for (i = 0xC070; i < 0xC080; i++)
|
||||
cpu65_vmem[i].r =
|
||||
cpu65_vmem[i].w =
|
||||
read_gc_strobe;
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
/* IOUDIS switch & read_gc_strobe */
|
||||
cpu65_vmem[0xC07E].w =
|
||||
iie_ioudis_on;
|
||||
cpu65_vmem[0xC07F].w =
|
||||
iie_ioudis_off;
|
||||
cpu65_vmem[0xC07E].r =
|
||||
iie_check_ioudis;
|
||||
cpu65_vmem[0xC07F].r =
|
||||
iie_check_dhires;
|
||||
|
||||
/* DHIRES/Annunciator switches */
|
||||
cpu65_vmem[0xC05E].w =
|
||||
cpu65_vmem[0xC05E].r =
|
||||
iie_dhires_on;
|
||||
cpu65_vmem[0xC05F].w =
|
||||
cpu65_vmem[0xC05F].r =
|
||||
iie_dhires_off;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* language card softswitches */
|
||||
cpu65_vmem[0xC080].r = cpu65_vmem[0xC080].w =
|
||||
cpu65_vmem[0xC084].r = cpu65_vmem[0xC084].w =
|
||||
(apple_mode == IIE_MODE) ? iie_c080 : lc_c080;
|
||||
cpu65_vmem[0xC081].r = cpu65_vmem[0xC081].w =
|
||||
cpu65_vmem[0xC085].r = cpu65_vmem[0xC085].w =
|
||||
(apple_mode == IIE_MODE) ? iie_c081 : lc_c081;
|
||||
cpu65_vmem[0xC082].r = cpu65_vmem[0xC082].w =
|
||||
cpu65_vmem[0xC086].r = cpu65_vmem[0xC086].w =
|
||||
lc_c082;
|
||||
cpu65_vmem[0xC083].r = cpu65_vmem[0xC083].w =
|
||||
cpu65_vmem[0xC087].r = cpu65_vmem[0xC087].w =
|
||||
(apple_mode == IIE_MODE) ? iie_c083 : lc_c083;
|
||||
|
||||
cpu65_vmem[0xC088].r = cpu65_vmem[0xC088].w =
|
||||
cpu65_vmem[0xC08C].r = cpu65_vmem[0xC08C].w =
|
||||
(apple_mode == IIE_MODE) ? iie_c088 : lc_c088;
|
||||
cpu65_vmem[0xC089].r = cpu65_vmem[0xC089].w =
|
||||
cpu65_vmem[0xC08D].r = cpu65_vmem[0xC08D].w =
|
||||
(apple_mode == IIE_MODE) ? iie_c089 : lc_c089;
|
||||
cpu65_vmem[0xC08A].r = cpu65_vmem[0xC08A].w =
|
||||
cpu65_vmem[0xC08E].r = cpu65_vmem[0xC08E].w =
|
||||
lc_c08a;
|
||||
cpu65_vmem[0xC08B].r = cpu65_vmem[0xC08B].w =
|
||||
cpu65_vmem[0xC08F].r = cpu65_vmem[0xC08F].w =
|
||||
(apple_mode == IIE_MODE) ? iie_c08b : lc_c08b;
|
||||
#else /* !APPLE_IIE */
|
||||
/* language card softswitches */
|
||||
cpu65_vmem[0xC080].r = cpu65_vmem[0xC080].w =
|
||||
cpu65_vmem[0xC084].r = cpu65_vmem[0xC084].w =
|
||||
lc_c080;
|
||||
cpu65_vmem[0xC081].r = cpu65_vmem[0xC081].w =
|
||||
cpu65_vmem[0xC085].r = cpu65_vmem[0xC085].w =
|
||||
lc_c081;
|
||||
cpu65_vmem[0xC082].r = cpu65_vmem[0xC082].w =
|
||||
cpu65_vmem[0xC086].r = cpu65_vmem[0xC086].w =
|
||||
lc_c082;
|
||||
cpu65_vmem[0xC083].r = cpu65_vmem[0xC083].w =
|
||||
cpu65_vmem[0xC087].r = cpu65_vmem[0xC087].w =
|
||||
lc_c083;
|
||||
|
||||
cpu65_vmem[0xC088].r = cpu65_vmem[0xC088].w =
|
||||
cpu65_vmem[0xC08C].r = cpu65_vmem[0xC08C].w =
|
||||
lc_c088;
|
||||
cpu65_vmem[0xC089].r = cpu65_vmem[0xC089].w =
|
||||
cpu65_vmem[0xC08D].r = cpu65_vmem[0xC08D].w =
|
||||
lc_c089;
|
||||
cpu65_vmem[0xC08A].r = cpu65_vmem[0xC08A].w =
|
||||
cpu65_vmem[0xC08E].r = cpu65_vmem[0xC08E].w =
|
||||
lc_c08a;
|
||||
cpu65_vmem[0xC08B].r = cpu65_vmem[0xC08B].w =
|
||||
cpu65_vmem[0xC08F].r = cpu65_vmem[0xC08F].w =
|
||||
lc_c08b;
|
||||
#endif /* !APPLE_IIE */
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* slot i/o area */
|
||||
for (i = 0xC100; i < 0xC300; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
iie_read_slotx; /* slots 1 & 2 (x) */
|
||||
}
|
||||
for (i = 0xC300; i < 0xC400; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
iie_read_slot3; /* slot 3 (80col) */
|
||||
}
|
||||
for (i = 0xC400; i < 0xC800; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
iie_read_slotx; /* slots 4 - 7 (x) */
|
||||
}
|
||||
for (i = 0xC800; i < 0xD000; i++) {
|
||||
cpu65_vmem[i].r =
|
||||
iie_read_slot_expansion; /* expansion rom */
|
||||
}
|
||||
cpu65_vmem[0xCFFF].r =
|
||||
cpu65_vmem[0xCFFF].w =
|
||||
iie_disable_slot_expansion;
|
||||
#endif
|
||||
|
||||
video_set(0); /* must be done here, between pre_compact & compact */
|
||||
|
||||
disk_install(6); /* Put a Disk ][ Controller in slot 6 */
|
||||
|
||||
compact(); /* Compress memory so that identical pages share storage */
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_apple_ii_memory()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void c_initialize_apple_ii_memory()
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
static int ii_rom_loaded = 0;
|
||||
#ifdef APPLE_IIE
|
||||
static int iie_rom_loaded = 0;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 0x10000; i++) {
|
||||
apple_ii_64k[0][i] = 0;
|
||||
apple_ii_64k[1][i] = 0;
|
||||
}
|
||||
for (i = 0; i < 8192; i++)
|
||||
language_card[0][i] = language_card[1][i] = 0;
|
||||
for (i = 0; i < 8192; i++)
|
||||
language_banks[0][i] = language_banks[1][i] = 0;
|
||||
|
||||
if (!ii_rom_loaded)
|
||||
{
|
||||
snprintf(temp, TEMPSIZE, "%s/apple_II.rom", system_path);
|
||||
if ((f = fopen(temp, "r")) == NULL) {
|
||||
printf("OOPS!\n");
|
||||
printf("Cannot find file '%s'.\n",temp);
|
||||
exit(0);
|
||||
}
|
||||
fread(apple_ii_rom, 0x3000, 1, f);
|
||||
fclose(f);
|
||||
ii_rom_loaded = 1;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (!iie_rom_loaded) {
|
||||
snprintf(temp, TEMPSIZE, "%s/apple_IIe.rom", system_path);
|
||||
if ((f = fopen(temp, "r")) == NULL) {
|
||||
printf("Cannot find file '%s'.\n",temp);
|
||||
exit(0);
|
||||
}
|
||||
fread(apple_iie_rom, 32768, 1, f);
|
||||
fclose(f);
|
||||
iie_rom_loaded = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0xD000; i < 0x10000; i++)
|
||||
apple_ii_64k[0][i] = apple_ii_rom[i - 0xD000];
|
||||
for (i = 0; i < 0x1000; i++)
|
||||
language_banks[0][i] = apple_ii_rom[i];
|
||||
for (i = 0; i < 0x2000; i++)
|
||||
language_card[0][i] = apple_ii_rom[i + 0x1000];
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
/* load the rom from 0xC000, slot rom main, internal rom aux */
|
||||
for (i = 0xC000; i < 0x10000; i++) {
|
||||
apple_ii_64k[0][i] = apple_iie_rom[i - 0xC000];
|
||||
apple_ii_64k[1][i] = apple_iie_rom[i - 0x8000];
|
||||
}
|
||||
for (i = 0; i < 0x1000; i++) {
|
||||
language_banks[0][i] = apple_iie_rom[i + 0x1000];
|
||||
language_banks[1][i] = apple_iie_rom[i + 0x5000];
|
||||
}
|
||||
for (i = 0; i < 0x2000; i++) {
|
||||
language_card[0][i] = apple_iie_rom[i + 0x2000];
|
||||
language_card[1][i] = apple_iie_rom[i + 0x6000];
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* softswitch memory HACK - why this? */
|
||||
{
|
||||
for (i = 0xC100; i < 0xD000; i++) {
|
||||
apple_ii_64k[0][i] = i & 0xFF;
|
||||
apple_ii_64k[1][i] = i & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
apple_ii_64k[0][0xC000] = 0x00;
|
||||
apple_ii_64k[1][0xC000] = 0x00;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
void c_initialize_sound()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void c_initialize_sound()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0xC030; i < 0xC040; i++)
|
||||
cpu65_vmem[i].r = cpu65_vmem[i].w =
|
||||
(sound_mode && soundAllowed) ? read_speaker_toggle_pc : ram_nop;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_iie_switches
|
||||
------------------------------------------------------------------------- */
|
||||
void c_initialize_iie_switches() {
|
||||
|
||||
base_stackzp = apple_ii_64k[0];
|
||||
base_d000_rd = apple_ii_64k[0];
|
||||
base_d000_wrt = language_banks[0] - 0xD000;
|
||||
base_e000_rd = apple_ii_64k[0];
|
||||
base_e000_wrt = language_card[0] - 0xE000;
|
||||
|
||||
base_ramrd = apple_ii_64k[0];
|
||||
base_ramwrt = apple_ii_64k[0];
|
||||
base_textrd = apple_ii_64k[0];
|
||||
base_textwrt = apple_ii_64k[0];
|
||||
base_hgrrd = apple_ii_64k[0];
|
||||
base_hgrwrt= apple_ii_64k[0];
|
||||
|
||||
base_c3rom = apple_ii_64k[1]; /* c3rom internal */
|
||||
c8rom_offset = 0x10000; /* c8rom internal */
|
||||
base_cxrom = apple_ii_64k[0]; /* cxrom peripheral */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
void c_initialize_vm()
|
||||
------------------------------------------------------------------------- */
|
||||
void c_initialize_vm() {
|
||||
c_initialize_font(); /* font already read in */
|
||||
c_initialize_apple_ii_memory(); /* read in rom memory */
|
||||
c_initialize_tables(); /* read/write memory jump tables */
|
||||
c_initialize_sound(); /* sound system */
|
||||
c_init_6(); /* drive ][, slot 6 */
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
c_initialize_iie_switches(); /* set the //e softswitches */
|
||||
#endif
|
||||
|
||||
#ifdef MOUSE_EMULATION
|
||||
c_initialize_mouse();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
void c_initialize_firsttime()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
static void reinitialize(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef DEBUGGER
|
||||
/* reset the watchpoints and breakpoints */
|
||||
for (i=0; i<MAX_BRKPTS; i++) {
|
||||
breakpoints[i] = -1;
|
||||
watchpoints[i] = -1;
|
||||
}
|
||||
for (i=0; i<0x100; i++) {
|
||||
op_breakpoints[(unsigned char)i] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
c_initialize_vm();
|
||||
|
||||
softswitches = SS_TEXT | SS_IOUDIS | SS_C3ROM | SS_LCWRT | SS_LCSEC;
|
||||
|
||||
video_setpage( 0 );
|
||||
|
||||
video_redraw();
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE)
|
||||
cpu65_set(CPU65_C02);
|
||||
else
|
||||
#endif
|
||||
if (apple_mode == IIU_MODE)
|
||||
cpu65_set(CPU65_NMOS);
|
||||
else
|
||||
cpu65_set(CPU65_NMOS|CPU65_FAULT);
|
||||
|
||||
}
|
||||
|
||||
static void c_initialize_firsttime()
|
||||
{
|
||||
/* get IO permission for speaker port. */
|
||||
if (/*ioperm(0x42, 1, 1) ||*/ ioperm(0x61, 1, 1)) {
|
||||
perror("ioperm");
|
||||
printf("cannot get port access to PC speaker.\n");
|
||||
printf("sound will not be used.\n");
|
||||
soundAllowed=0;
|
||||
} else
|
||||
soundAllowed=1;
|
||||
|
||||
/* read in system files and calculate system defaults */
|
||||
c_load_interface_font();
|
||||
|
||||
/* initialize the video system */
|
||||
video_init();
|
||||
|
||||
/* Enable periodic updates */
|
||||
signal(SIGVTALRM,c_periodic_update);
|
||||
setitimer(ITIMER_VIRTUAL,&timer_on,0);
|
||||
|
||||
reinitialize();
|
||||
}
|
||||
|
||||
void c_read_random() {
|
||||
random_value = (unsigned char)(rand() >> 8);
|
||||
}
|
||||
|
||||
int main(int sargc, char *sargv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
argc = sargc;
|
||||
argv = sargv;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
/*
|
||||
if (strcmp(argv[i], "-vga") == 0)
|
||||
force_vga_mode = 1;
|
||||
*/
|
||||
}
|
||||
|
||||
load_settings(); /* user prefs */
|
||||
c_initialize_firsttime(); /* init svga graphics and vm */
|
||||
|
||||
for (;;) {
|
||||
/* execute the emulator */
|
||||
cpu65_run();
|
||||
|
||||
reinitialize();
|
||||
}
|
||||
/* never reached */
|
||||
}
|
261
src/misc.h
Normal file
261
src/misc.h
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Miscellaneous defines
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MISC_H
|
||||
#define MISC_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define SW_TEXT 0xC050
|
||||
#define SW_MIXED 0xC052
|
||||
#define SW_PAGE2 0xC054
|
||||
#define SW_HIRES 0xC056
|
||||
#ifdef APPLE_IIE
|
||||
#define SW_80STORE 0xC000
|
||||
#define SW_RAMRD 0xC002
|
||||
#define SW_RAMWRT 0xC004
|
||||
#define SW_ALTZP 0xC008
|
||||
#define SW_80COL 0xC00C
|
||||
#define SW_ALTCHAR 0xC00E
|
||||
#define SW_SLOTC3ROM 0xC00B /* anomaly */
|
||||
#define SW_SLOTCXROM 0xC006
|
||||
#define SW_DHIRES 0xC05E
|
||||
#define SW_IOUDIS 0xC07E
|
||||
#endif
|
||||
|
||||
extern const struct itimerval timer_on,timer_off;
|
||||
|
||||
/* Text characters */
|
||||
extern const unsigned char ucase_glyphs[0x200];
|
||||
extern const unsigned char lcase_glyphs[0x100];
|
||||
extern const unsigned char mousetext_glyphs[0x100];
|
||||
extern const unsigned char interface_glyphs[88];
|
||||
|
||||
unsigned char apple_ii_64k[2][65536]; /* 128k memory */
|
||||
|
||||
/* language card memory and settings */
|
||||
unsigned char language_card[2][8192], language_banks[2][8192];
|
||||
|
||||
/* misc stuff */
|
||||
int soundAllowed;
|
||||
unsigned char random_value;
|
||||
|
||||
/* global ref to commandline args */
|
||||
char **argv;
|
||||
int argc;
|
||||
|
||||
/* misc arrays */
|
||||
#define TEMPSIZE 4096
|
||||
unsigned char temp[ TEMPSIZE ];/* should be >=4096 (stuff depends on this) */
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
/* memory offsets from softswitches */
|
||||
int c8rom_offset;
|
||||
|
||||
extern unsigned char *base_ramrd;
|
||||
extern unsigned char *base_ramwrt;
|
||||
extern unsigned char *base_textrd;
|
||||
extern unsigned char *base_textwrt;
|
||||
extern unsigned char *base_hgrrd;
|
||||
extern unsigned char *base_hgrwrt;
|
||||
|
||||
extern unsigned char *base_stackzp;
|
||||
extern unsigned char *base_d000_rd;
|
||||
extern unsigned char *base_e000_rd;
|
||||
extern unsigned char *base_d000_wrt;
|
||||
extern unsigned char *base_e000_wrt;
|
||||
|
||||
extern unsigned char *base_c3rom;
|
||||
extern unsigned char *base_cxrom;
|
||||
|
||||
#endif /* APPLE_IIE */
|
||||
|
||||
/* softswitches */
|
||||
|
||||
extern int softswitches;
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#define SS_TEXT 0x00000001
|
||||
#define SS_MIXED 0x00000002
|
||||
#define SS_HIRES 0x00000004
|
||||
#define SS_PAGE2 0x00000008
|
||||
#define SS_BANK2 0x00000010
|
||||
#define SS_LCRAM 0x00000020
|
||||
#define SS_LCSEC 0x00000040 /* check for double read */
|
||||
#define SS_LCWRT 0x00000080 /* LC write enable */
|
||||
#define SS_80STORE 0x00000100
|
||||
#define SS_80COL 0x00000200
|
||||
#define SS_RAMRD 0x00000400
|
||||
#define SS_RAMWRT 0x00000800
|
||||
#define SS_ALTZP 0x00001000
|
||||
#define SS_DHIRES 0x00002000
|
||||
#define SS_IOUDIS 0x00004000
|
||||
#define SS_CXROM 0x00008000
|
||||
#define SS_C3ROM 0x00010000
|
||||
#define SS_ALTCHAR 0x00020000
|
||||
|
||||
/* Pseudo soft switches. These are actually functions of other SSes, but are
|
||||
* tiresome to calculate as needed.
|
||||
*
|
||||
*/
|
||||
#define SS_SCREEN 0x00040000 /* PAGE2 && !80STORE */
|
||||
#define SS_TEXTRD 0x00080000 /* (PAGE2 && 80STORE) ||
|
||||
(RAMRD && !80STORE) */
|
||||
#define SS_TEXTWRT 0x00100000 /* (PAGE2 && 80STORE) ||
|
||||
(RAMWRT && !80STORE) */
|
||||
#define SS_HGRRD 0x00200000 /* (PAGE2 && 80STORE && HIRES) ||
|
||||
(RAMRD && !(80STORE && HIRES) */
|
||||
#define SS_HGRWRT 0x00400000 /* (PAGE2 && 80STORE && HIRES) ||
|
||||
(RAMWRT && !(80STORE && HIRES)) */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
/* -------------------------------------------------------------------------
|
||||
misc.c functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void c_initialize_sound();
|
||||
void c_initialize_font();
|
||||
void c_initialize_vm();
|
||||
void c_read_random();
|
||||
|
||||
/* virtual memory compacter */
|
||||
|
||||
void pre_compact(void);
|
||||
void compact(void);
|
||||
|
||||
/* vm hooks */
|
||||
|
||||
void ram_nop(),
|
||||
|
||||
write_ram_default(),
|
||||
write_unmapped_softswitch(),
|
||||
|
||||
read_ram_default(),
|
||||
read_random(),
|
||||
read_unmapped_softswitch(),
|
||||
read_keyboard(),
|
||||
read_keyboard_strobe(),
|
||||
read_speaker_toggle_pc(),
|
||||
read_switch_primary_page(),
|
||||
read_switch_secondary_page(),
|
||||
read_switch_graphics(),
|
||||
read_switch_text(),
|
||||
read_switch_no_mixed(),
|
||||
read_switch_mixed(),
|
||||
read_switch_lores(),
|
||||
read_switch_hires(),
|
||||
|
||||
read_button0(),
|
||||
read_button1(),
|
||||
read_button2(),
|
||||
read_gc0(),
|
||||
read_gc1(),
|
||||
read_gc_strobe(),
|
||||
|
||||
lc_c080(),
|
||||
lc_c081(),
|
||||
lc_c082(),
|
||||
lc_c083(),
|
||||
lc_c088(),
|
||||
lc_c089(),
|
||||
lc_c08a(),
|
||||
lc_c08b(),
|
||||
write_ram_bank(),
|
||||
read_ram_bank(),
|
||||
write_ram_lc(),
|
||||
read_ram_lc();
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
void iie_write_ram_default(),
|
||||
iie_read_ram_default(),
|
||||
|
||||
/* //e text pages */
|
||||
iie_read_ram_text_page0(),
|
||||
iie_write_screen_hole_text_page0(),
|
||||
|
||||
/* //e hires page 0 */
|
||||
iie_read_ram_hires_page0(),
|
||||
iie_write_screen_hole_hires_page0(),
|
||||
|
||||
/* //e zpage,stack, ram banks */
|
||||
iie_read_ram_zpage_and_stack(),
|
||||
iie_write_ram_zpage_and_stack(),
|
||||
iie_read_slot3(),
|
||||
iie_read_slotx(),
|
||||
iie_read_slot_expansion(),
|
||||
iie_disable_slot_expansion(),
|
||||
iie_read_gc2(),
|
||||
iie_read_gc3(),
|
||||
|
||||
iie_c080(),
|
||||
iie_c081(),
|
||||
iie_c083(),
|
||||
iie_c088(),
|
||||
iie_c089(),
|
||||
iie_c08b(),
|
||||
|
||||
/* //e toggle softswitches */
|
||||
iie_ramrd_main(),
|
||||
iie_ramrd_aux(),
|
||||
iie_ramwrt_main(),
|
||||
iie_ramwrt_aux(),
|
||||
iie_80store_off(),
|
||||
iie_80store_on(),
|
||||
iie_altzp_main(),
|
||||
iie_altzp_aux(),
|
||||
iie_80col_off(),
|
||||
iie_80col_on(),
|
||||
iie_altchar_off(),
|
||||
iie_altchar_on(),
|
||||
iie_c3rom_peripheral(),
|
||||
iie_c3rom_internal(),
|
||||
iie_cxrom_peripheral(),
|
||||
iie_cxrom_internal(),
|
||||
iie_ioudis_on(),
|
||||
iie_ioudis_off(),
|
||||
iie_dhires_on(),
|
||||
iie_dhires_off(),
|
||||
iie_hires_off(),
|
||||
iie_hires_on(),
|
||||
iie_page2_on(),
|
||||
iie_page2_off(),
|
||||
|
||||
/* //e check softswitche settings */
|
||||
iie_check_80store(),
|
||||
iie_check_bank(),
|
||||
iie_check_lcram(),
|
||||
iie_check_ramrd(),
|
||||
iie_check_ramwrt(),
|
||||
iie_check_altzp(),
|
||||
iie_check_c3rom(),
|
||||
iie_check_cxrom(),
|
||||
iie_check_80col(),
|
||||
iie_check_altchar(),
|
||||
iie_check_text(),
|
||||
iie_check_mixed(),
|
||||
iie_check_hires(),
|
||||
iie_check_page2(),
|
||||
iie_check_ioudis(),
|
||||
iie_check_dhires(),
|
||||
iie_check_vbl();
|
||||
#endif /* APPLE_IIE */
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#endif
|
820
src/opcodes.c
Normal file
820
src/opcodes.c
Normal file
@ -0,0 +1,820 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Opcode tables for debugger
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
const char * const disasm_templates[15] =
|
||||
{
|
||||
"",
|
||||
"A",
|
||||
"#$%02X",
|
||||
"$%02X",
|
||||
"$%02X,X",
|
||||
"$%02X,Y",
|
||||
"$%02X%02X",
|
||||
"$%02X%02X,X",
|
||||
"$%02X%02X,Y",
|
||||
"($%02X)",
|
||||
"($%02X,X)",
|
||||
"($%02X),Y",
|
||||
"($%02X%02X)",
|
||||
"($%02X%02X),X",
|
||||
"$%04X (%c%02X)"
|
||||
};
|
||||
|
||||
const struct opcode_struct opcodes_6502[256] =
|
||||
{
|
||||
{"BRK", addr_implied},
|
||||
{"ORA", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"ORA", addr_zeropage},
|
||||
{"ASL", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"PHP", addr_implied},
|
||||
{"ORA", addr_immediate},
|
||||
{"ASL", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"ORA", addr_absolute},
|
||||
{"ASL", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BPL", addr_relative},
|
||||
{"ORA", addr_indirect_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"ORA", addr_zeropage_x},
|
||||
{"ASL", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"CLC", addr_implied},
|
||||
{"ORA", addr_absolute_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"ORA", addr_absolute_x},
|
||||
{"ASL", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"JSR", addr_absolute},
|
||||
{"AND", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"BIT", addr_zeropage},
|
||||
{"AND", addr_zeropage},
|
||||
{"ROL", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"PLP", addr_implied},
|
||||
{"AND", addr_immediate},
|
||||
{"ROL", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"BIT", addr_absolute},
|
||||
{"AND", addr_absolute},
|
||||
{"ROL", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BMI", addr_relative},
|
||||
{"AND", addr_indirect_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"AND", addr_zeropage_x},
|
||||
{"ROL", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"SEC", addr_implied},
|
||||
{"AND", addr_absolute_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"AND", addr_absolute_x},
|
||||
{"ROL", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"RTI", addr_implied},
|
||||
{"EOR", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"EOR", addr_zeropage},
|
||||
{"LSR", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"PHA", addr_implied},
|
||||
{"EOR", addr_immediate},
|
||||
{"LSR", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"JMP", addr_absolute},
|
||||
{"EOR", addr_absolute},
|
||||
{"LSR", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BVC", addr_relative},
|
||||
{"EOR", addr_indirect_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"EOR", addr_zeropage_x},
|
||||
{"LSR", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"CLI", addr_implied},
|
||||
{"EOR", addr_absolute_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"EOR", addr_absolute_x},
|
||||
{"LSR", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"RTS", addr_implied},
|
||||
{"ADC", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"ADC", addr_zeropage},
|
||||
{"ROR", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"PLA", addr_implied},
|
||||
{"ADC", addr_immediate},
|
||||
{"ROR", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"JMP", addr_j_indirect},
|
||||
{"ADC", addr_absolute},
|
||||
{"ROR", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BVS", addr_relative},
|
||||
{"ADC", addr_indirect_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"ADC", addr_zeropage_x},
|
||||
{"ROR", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"SEI", addr_implied},
|
||||
{"ADC", addr_absolute_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"ADC", addr_absolute_x},
|
||||
{"ROR", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STA", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STY", addr_zeropage},
|
||||
{"STA", addr_zeropage},
|
||||
{"STX", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"DEY", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"TXA", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STY", addr_absolute},
|
||||
{"STA", addr_absolute},
|
||||
{"STX", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BCC", addr_relative},
|
||||
{"STA", addr_indirect_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STY", addr_zeropage_x},
|
||||
{"STA", addr_zeropage_x},
|
||||
{"STX", addr_zeropage_y},
|
||||
{"???", addr_implied},
|
||||
{"TYA", addr_implied},
|
||||
{"STA", addr_absolute_y},
|
||||
{"TXS", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STA", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_immediate},
|
||||
{"LDA", addr_indirect_x},
|
||||
{"LDX", addr_immediate},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_zeropage},
|
||||
{"LDA", addr_zeropage},
|
||||
{"LDX", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"TAY", addr_implied},
|
||||
{"LDA", addr_immediate},
|
||||
{"TAX", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_absolute},
|
||||
{"LDA", addr_absolute},
|
||||
{"LDX", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BCS", addr_relative},
|
||||
{"LDA", addr_indirect_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_zeropage_x},
|
||||
{"LDA", addr_zeropage_x},
|
||||
{"LDX", addr_zeropage_y},
|
||||
{"???", addr_implied},
|
||||
{"CLV", addr_implied},
|
||||
{"LDA", addr_absolute_y},
|
||||
{"TSX", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_absolute_x},
|
||||
{"LDA", addr_absolute_x},
|
||||
{"LDX", addr_absolute_y},
|
||||
{"???", addr_implied},
|
||||
{"CPY", addr_immediate},
|
||||
{"CMP", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CPY", addr_zeropage},
|
||||
{"CMP", addr_zeropage},
|
||||
{"DEC", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"INY", addr_implied},
|
||||
{"CMP", addr_immediate},
|
||||
{"DEX", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CPY", addr_absolute},
|
||||
{"CMP", addr_absolute},
|
||||
{"DEC", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BNE", addr_relative},
|
||||
{"CMP", addr_indirect_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CMP", addr_zeropage_x},
|
||||
{"DEC", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"CLD", addr_implied},
|
||||
{"CMP", addr_absolute_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CMP", addr_absolute_x},
|
||||
{"DEC", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"CPX", addr_immediate},
|
||||
{"SBC", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CPX", addr_zeropage},
|
||||
{"SBC", addr_zeropage},
|
||||
{"INC", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"INX", addr_implied},
|
||||
{"SBC", addr_immediate},
|
||||
{"NOP", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CPX", addr_absolute},
|
||||
{"SBC", addr_absolute},
|
||||
{"INC", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BEQ", addr_relative},
|
||||
{"SBC", addr_indirect_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"SBC", addr_zeropage_x},
|
||||
{"INC", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"SED", addr_implied},
|
||||
{"SBC", addr_absolute_y},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"SBC", addr_absolute_x},
|
||||
{"INC", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
};
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
|
||||
const struct opcode_struct opcodes_65c02[256] =
|
||||
{
|
||||
{"BRK", addr_implied},
|
||||
{"ORA", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"TSB", addr_zeropage},
|
||||
{"ORA", addr_zeropage},
|
||||
{"ASL", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"PHP", addr_implied},
|
||||
{"ORA", addr_immediate},
|
||||
{"ASL", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"TSB", addr_absolute},
|
||||
{"ORA", addr_absolute},
|
||||
{"ASL", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BPL", addr_relative},
|
||||
{"ORA", addr_indirect_y},
|
||||
{"ORA", addr_indirect},
|
||||
{"???", addr_implied},
|
||||
{"TRB", addr_zeropage},
|
||||
{"ORA", addr_zeropage_x},
|
||||
{"ASL", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"CLC", addr_implied},
|
||||
{"ORA", addr_absolute_y},
|
||||
{"INC", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"TRB", addr_absolute},
|
||||
{"ORA", addr_absolute_x},
|
||||
{"ASL", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"JSR", addr_absolute},
|
||||
{"AND", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"BIT", addr_zeropage},
|
||||
{"AND", addr_zeropage},
|
||||
{"ROL", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"PLP", addr_implied},
|
||||
{"AND", addr_immediate},
|
||||
{"ROL", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"BIT", addr_absolute},
|
||||
{"AND", addr_absolute},
|
||||
{"ROL", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BMI", addr_relative},
|
||||
{"AND", addr_indirect_y},
|
||||
{"AND", addr_indirect},
|
||||
{"???", addr_implied},
|
||||
{"BIT", addr_zeropage_x},
|
||||
{"AND", addr_zeropage_x},
|
||||
{"ROL", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"SEC", addr_implied},
|
||||
{"AND", addr_absolute_y},
|
||||
{"DEC", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"BIT", addr_absolute_x},
|
||||
{"AND", addr_absolute_x},
|
||||
{"ROL", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"RTI", addr_implied},
|
||||
{"EOR", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"EOR", addr_zeropage},
|
||||
{"LSR", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"PHA", addr_implied},
|
||||
{"EOR", addr_immediate},
|
||||
{"LSR", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"JMP", addr_absolute},
|
||||
{"EOR", addr_absolute},
|
||||
{"LSR", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BVC", addr_relative},
|
||||
{"EOR", addr_indirect_y},
|
||||
{"EOR", addr_indirect},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"EOR", addr_zeropage_x},
|
||||
{"LSR", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"CLI", addr_implied},
|
||||
{"EOR", addr_absolute_y},
|
||||
{"PHY", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"EOR", addr_absolute_x},
|
||||
{"LSR", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"RTS", addr_implied},
|
||||
{"ADC", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STZ", addr_zeropage},
|
||||
{"ADC", addr_zeropage},
|
||||
{"ROR", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"PLA", addr_implied},
|
||||
{"ADC", addr_immediate},
|
||||
{"ROR", addr_accumulator},
|
||||
{"???", addr_implied},
|
||||
{"JMP", addr_j_indirect},
|
||||
{"ADC", addr_absolute},
|
||||
{"ROR", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BVS", addr_relative},
|
||||
{"ADC", addr_indirect_y},
|
||||
{"ADC", addr_indirect},
|
||||
{"???", addr_implied},
|
||||
{"STZ", addr_zeropage_x},
|
||||
{"ADC", addr_zeropage_x},
|
||||
{"ROR", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"SEI", addr_implied},
|
||||
{"ADC", addr_absolute_y},
|
||||
{"PLY", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"JMP", addr_j_indirect_x},
|
||||
{"ADC", addr_absolute_x},
|
||||
{"ROR", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"BRA", addr_relative},
|
||||
{"STA", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STY", addr_zeropage},
|
||||
{"STA", addr_zeropage},
|
||||
{"STX", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"DEY", addr_implied},
|
||||
{"BIT", addr_immediate},
|
||||
{"TXA", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STY", addr_absolute},
|
||||
{"STA", addr_absolute},
|
||||
{"STX", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BCC", addr_relative},
|
||||
{"STA", addr_indirect_y},
|
||||
{"STA", addr_indirect},
|
||||
{"???", addr_implied},
|
||||
{"STY", addr_zeropage_x},
|
||||
{"STA", addr_zeropage_x},
|
||||
{"STX", addr_zeropage_y},
|
||||
{"???", addr_implied},
|
||||
{"TYA", addr_implied},
|
||||
{"STA", addr_absolute_y},
|
||||
{"TXS", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"STZ", addr_absolute},
|
||||
{"STA", addr_absolute_x},
|
||||
{"STZ", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_immediate},
|
||||
{"LDA", addr_indirect_x},
|
||||
{"LDX", addr_immediate},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_zeropage},
|
||||
{"LDA", addr_zeropage},
|
||||
{"LDX", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"TAY", addr_implied},
|
||||
{"LDA", addr_immediate},
|
||||
{"TAX", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_absolute},
|
||||
{"LDA", addr_absolute},
|
||||
{"LDX", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BCS", addr_relative},
|
||||
{"LDA", addr_indirect_y},
|
||||
{"LDA", addr_indirect},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_zeropage_x},
|
||||
{"LDA", addr_zeropage_x},
|
||||
{"LDX", addr_zeropage_y},
|
||||
{"???", addr_implied},
|
||||
{"CLV", addr_implied},
|
||||
{"LDA", addr_absolute_y},
|
||||
{"TSX", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"LDY", addr_absolute_x},
|
||||
{"LDA", addr_absolute_x},
|
||||
{"LDX", addr_absolute_y},
|
||||
{"???", addr_implied},
|
||||
{"CPY", addr_immediate},
|
||||
{"CMP", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CPY", addr_zeropage},
|
||||
{"CMP", addr_zeropage},
|
||||
{"DEC", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"INY", addr_implied},
|
||||
{"CMP", addr_immediate},
|
||||
{"DEX", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CPY", addr_absolute},
|
||||
{"CMP", addr_absolute},
|
||||
{"DEC", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BNE", addr_relative},
|
||||
{"CMP", addr_indirect_y},
|
||||
{"CMP", addr_indirect},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CMP", addr_zeropage_x},
|
||||
{"DEC", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"CLD", addr_implied},
|
||||
{"CMP", addr_absolute_y},
|
||||
{"PHX", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CMP", addr_absolute_x},
|
||||
{"DEC", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
{"CPX", addr_immediate},
|
||||
{"SBC", addr_indirect_x},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CPX", addr_zeropage},
|
||||
{"SBC", addr_zeropage},
|
||||
{"INC", addr_zeropage},
|
||||
{"???", addr_implied},
|
||||
{"INX", addr_implied},
|
||||
{"SBC", addr_immediate},
|
||||
{"NOP", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"CPX", addr_absolute},
|
||||
{"SBC", addr_absolute},
|
||||
{"INC", addr_absolute},
|
||||
{"???", addr_implied},
|
||||
{"BEQ", addr_relative},
|
||||
{"SBC", addr_indirect_y},
|
||||
{"SBC", addr_indirect},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"SBC", addr_zeropage_x},
|
||||
{"INC", addr_zeropage_x},
|
||||
{"???", addr_implied},
|
||||
{"SED", addr_implied},
|
||||
{"SBC", addr_absolute_y},
|
||||
{"PLX", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"???", addr_implied},
|
||||
{"SBC", addr_absolute_x},
|
||||
{"INC", addr_absolute_x},
|
||||
{"???", addr_implied},
|
||||
};
|
||||
|
||||
#endif /* APPLE_IIE */
|
||||
|
||||
const struct opcode_struct opcodes_undoc[256] =
|
||||
{
|
||||
{"BRK", addr_implied},
|
||||
{"ORA", addr_indirect_x},
|
||||
{"hang", addr_implied},
|
||||
{"lor", addr_indirect_x},
|
||||
{"nop", addr_zeropage},
|
||||
{"ORA", addr_zeropage},
|
||||
{"ASL", addr_zeropage},
|
||||
{"lor", addr_zeropage},
|
||||
{"PHP", addr_implied},
|
||||
{"ORA", addr_immediate},
|
||||
{"ASL", addr_accumulator},
|
||||
{"ana", addr_immediate},
|
||||
{"nop", addr_absolute},
|
||||
{"ORA", addr_absolute},
|
||||
{"ASL", addr_absolute},
|
||||
{"lor", addr_absolute},
|
||||
{"BPL", addr_relative},
|
||||
{"ORA", addr_indirect_y},
|
||||
{"hang", addr_implied},
|
||||
{"lor", addr_indirect_y},
|
||||
{"nop", addr_zeropage_x},
|
||||
{"ORA", addr_zeropage_x},
|
||||
{"ASL", addr_zeropage_x},
|
||||
{"lor", addr_zeropage_x},
|
||||
{"CLC", addr_implied},
|
||||
{"ORA", addr_absolute_y},
|
||||
{"nop", addr_implied},
|
||||
{"lor", addr_absolute_y},
|
||||
{"nop", addr_absolute_x},
|
||||
{"ORA", addr_absolute_x},
|
||||
{"ASL", addr_absolute_x},
|
||||
{"lor", addr_absolute},
|
||||
{"JSR", addr_absolute},
|
||||
{"AND", addr_indirect_x},
|
||||
{"hang", addr_implied},
|
||||
{"lan", addr_indirect_x},
|
||||
{"BIT", addr_zeropage},
|
||||
{"AND", addr_zeropage},
|
||||
{"ROL", addr_zeropage},
|
||||
{"lan", addr_zeropage},
|
||||
{"PLP", addr_implied},
|
||||
{"AND", addr_immediate},
|
||||
{"ROL", addr_accumulator},
|
||||
{"anb", addr_immediate},
|
||||
{"BIT", addr_absolute},
|
||||
{"AND", addr_absolute},
|
||||
{"ROL", addr_absolute},
|
||||
{"lan", addr_absolute},
|
||||
{"BMI", addr_relative},
|
||||
{"AND", addr_indirect_y},
|
||||
{"hang", addr_implied},
|
||||
{"lan", addr_indirect_y},
|
||||
{"nop", addr_zeropage_x},
|
||||
{"AND", addr_zeropage_x},
|
||||
{"ROL", addr_zeropage_x},
|
||||
{"lan", addr_zeropage_x},
|
||||
{"SEC", addr_implied},
|
||||
{"AND", addr_absolute_y},
|
||||
{"nop", addr_implied},
|
||||
{"lan", addr_absolute_y},
|
||||
{"nop", addr_absolute_x},
|
||||
{"AND", addr_absolute_x},
|
||||
{"ROL", addr_absolute_x},
|
||||
{"lan", addr_absolute_x},
|
||||
{"RTI", addr_implied},
|
||||
{"EOR", addr_indirect_x},
|
||||
{"hang", addr_implied},
|
||||
{"reo", addr_indirect_x},
|
||||
{"nop", addr_zeropage},
|
||||
{"EOR", addr_zeropage},
|
||||
{"LSR", addr_zeropage},
|
||||
{"reo", addr_zeropage},
|
||||
{"PHA", addr_implied},
|
||||
{"EOR", addr_immediate},
|
||||
{"LSR", addr_accumulator},
|
||||
{"ram", addr_immediate},
|
||||
{"JMP", addr_absolute},
|
||||
{"EOR", addr_absolute},
|
||||
{"LSR", addr_absolute},
|
||||
{"reo", addr_absolute},
|
||||
{"BVC", addr_relative},
|
||||
{"EOR", addr_indirect_y},
|
||||
{"hang", addr_implied},
|
||||
{"reo", addr_indirect_y},
|
||||
{"nop", addr_zeropage_x},
|
||||
{"EOR", addr_zeropage_x},
|
||||
{"LSR", addr_zeropage_x},
|
||||
{"reo", addr_zeropage_x},
|
||||
{"CLI", addr_implied},
|
||||
{"EOR", addr_absolute_y},
|
||||
{"nop", addr_implied},
|
||||
{"reo", addr_absolute_y},
|
||||
{"nop", addr_absolute_x},
|
||||
{"EOR", addr_absolute_x},
|
||||
{"LSR", addr_absolute_x},
|
||||
{"reo", addr_absolute_x},
|
||||
{"RTS", addr_implied},
|
||||
{"ADC", addr_indirect_x},
|
||||
{"hang", addr_implied},
|
||||
{"rad", addr_indirect_x},
|
||||
{"nop", addr_zeropage},
|
||||
{"ADC", addr_zeropage},
|
||||
{"ROR", addr_zeropage},
|
||||
{"rad", addr_zeropage},
|
||||
{"PLA", addr_implied},
|
||||
{"ADC", addr_immediate},
|
||||
{"ROR", addr_accumulator},
|
||||
{"rbm", addr_immediate},
|
||||
{"JMP", addr_j_indirect},
|
||||
{"ADC", addr_absolute},
|
||||
{"ROR", addr_absolute},
|
||||
{"rad", addr_absolute},
|
||||
{"BVS", addr_relative},
|
||||
{"ADC", addr_indirect_y},
|
||||
{"hang", addr_implied},
|
||||
{"rad", addr_indirect_y},
|
||||
{"nop", addr_zeropage_x},
|
||||
{"ADC", addr_zeropage_x},
|
||||
{"ROR", addr_zeropage_x},
|
||||
{"rad", addr_zeropage_x},
|
||||
{"SEI", addr_implied},
|
||||
{"ADC", addr_absolute_y},
|
||||
{"nop", addr_implied},
|
||||
{"rad", addr_absolute_y},
|
||||
{"nop", addr_absolute_x},
|
||||
{"ADC", addr_absolute_x},
|
||||
{"ROR", addr_absolute_x},
|
||||
{"rad", addr_absolute_x},
|
||||
{"nop", addr_immediate},
|
||||
{"STA", addr_indirect_x},
|
||||
{"nop", addr_immediate},
|
||||
{"aax", addr_indirect_x},
|
||||
{"STY", addr_zeropage},
|
||||
{"STA", addr_zeropage},
|
||||
{"STX", addr_zeropage},
|
||||
{"aax", addr_zeropage},
|
||||
{"DEY", addr_implied},
|
||||
{"nop", addr_immediate},
|
||||
{"TXA", addr_implied},
|
||||
{"xma", addr_immediate},
|
||||
{"STY", addr_absolute},
|
||||
{"STA", addr_absolute},
|
||||
{"STX", addr_absolute},
|
||||
{"aax", addr_absolute},
|
||||
{"BCC", addr_relative},
|
||||
{"STA", addr_indirect_y},
|
||||
{"hang", addr_implied},
|
||||
{"aax", addr_indirect_y},
|
||||
{"STY", addr_zeropage_x},
|
||||
{"STA", addr_zeropage_x},
|
||||
{"STX", addr_zeropage_y},
|
||||
{"aax", addr_zeropage_y},
|
||||
{"TYA", addr_implied},
|
||||
{"STA", addr_absolute_y},
|
||||
{"TXS", addr_implied},
|
||||
{"axs", addr_absolute_y},
|
||||
{"tey", addr_absolute_x},
|
||||
{"STA", addr_absolute_x},
|
||||
{"tex", addr_absolute_y},
|
||||
{"tea", addr_absolute_y},
|
||||
{"LDY", addr_immediate},
|
||||
{"LDA", addr_indirect_x},
|
||||
{"LDX", addr_immediate},
|
||||
{"lax", addr_indirect_x},
|
||||
{"LDY", addr_zeropage},
|
||||
{"LDA", addr_zeropage},
|
||||
{"LDX", addr_zeropage},
|
||||
{"lax", addr_zeropage},
|
||||
{"TAY", addr_implied},
|
||||
{"LDA", addr_immediate},
|
||||
{"TAX", addr_implied},
|
||||
{"ama", addr_immediate},
|
||||
{"LDY", addr_absolute},
|
||||
{"LDA", addr_absolute},
|
||||
{"LDX", addr_absolute},
|
||||
{"lax", addr_absolute},
|
||||
{"BCS", addr_relative},
|
||||
{"LDA", addr_indirect_y},
|
||||
{"hang", addr_implied},
|
||||
{"lax", addr_indirect_y},
|
||||
{"LDY", addr_zeropage_x},
|
||||
{"LDA", addr_zeropage_x},
|
||||
{"LDX", addr_zeropage_y},
|
||||
{"laz", addr_zeropage_y},
|
||||
{"CLV", addr_implied},
|
||||
{"LDA", addr_absolute_y},
|
||||
{"TSX", addr_implied},
|
||||
{"las", addr_absolute_y},
|
||||
{"LDY", addr_absolute_x},
|
||||
{"LDA", addr_absolute_x},
|
||||
{"LDX", addr_absolute_y},
|
||||
{"lax", addr_absolute_y},
|
||||
{"CPY", addr_immediate},
|
||||
{"CMP", addr_indirect_x},
|
||||
{"nop", addr_immediate},
|
||||
{"dcp", addr_indirect_x},
|
||||
{"CPY", addr_zeropage},
|
||||
{"CMP", addr_zeropage},
|
||||
{"DEC", addr_zeropage},
|
||||
{"dcp", addr_zeropage},
|
||||
{"INY", addr_implied},
|
||||
{"CMP", addr_immediate},
|
||||
{"DEX", addr_implied},
|
||||
{"axm", addr_immediate},
|
||||
{"CPY", addr_absolute},
|
||||
{"CMP", addr_absolute},
|
||||
{"DEC", addr_absolute},
|
||||
{"dcp", addr_absolute},
|
||||
{"BNE", addr_relative},
|
||||
{"CMP", addr_indirect_y},
|
||||
{"hang", addr_implied},
|
||||
{"dcp", addr_indirect_y},
|
||||
{"nop", addr_zeropage_x},
|
||||
{"CMP", addr_zeropage_x},
|
||||
{"DEC", addr_zeropage_x},
|
||||
{"dcp", addr_zeropage_x},
|
||||
{"CLD", addr_implied},
|
||||
{"CMP", addr_absolute_y},
|
||||
{"nop", addr_implied},
|
||||
{"dcp", addr_absolute_y},
|
||||
{"nop", addr_absolute_x},
|
||||
{"CMP", addr_absolute_x},
|
||||
{"DEC", addr_absolute_x},
|
||||
{"dcp", addr_absolute_x},
|
||||
{"CPX", addr_immediate},
|
||||
{"SBC", addr_indirect_x},
|
||||
{"nop", addr_immediate},
|
||||
{"isb", addr_indirect_x},
|
||||
{"CPX", addr_zeropage},
|
||||
{"SBC", addr_zeropage},
|
||||
{"INC", addr_zeropage},
|
||||
{"isb", addr_zeropage},
|
||||
{"INX", addr_implied},
|
||||
{"SBC", addr_immediate},
|
||||
{"NOP", addr_implied},
|
||||
{"zbc", addr_immediate},
|
||||
{"CPX", addr_absolute},
|
||||
{"SBC", addr_absolute},
|
||||
{"INC", addr_absolute},
|
||||
{"isb", addr_absolute},
|
||||
{"BEQ", addr_relative},
|
||||
{"SBC", addr_indirect_y},
|
||||
{"hang", addr_implied},
|
||||
{"isb", addr_indirect_y},
|
||||
{"nop", addr_zeropage_x},
|
||||
{"SBC", addr_zeropage_x},
|
||||
{"INC", addr_zeropage_x},
|
||||
{"isb", addr_zeropage_x},
|
||||
{"SED", addr_implied},
|
||||
{"SBC", addr_absolute_y},
|
||||
{"nop", addr_implied},
|
||||
{"isb", addr_absolute_y},
|
||||
{"nop", addr_absolute_x},
|
||||
{"SBC", addr_absolute_x},
|
||||
{"INC", addr_absolute_x},
|
||||
{"isb", addr_absolute_x},
|
||||
};
|
412
src/prefs.c
Normal file
412
src/prefs.c
Normal file
@ -0,0 +1,412 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Preferences file maintenance
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "prefs.h"
|
||||
#include "keys.h"
|
||||
#include "interface.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define PRM_NONE 0
|
||||
#define PRM_SPEED 1
|
||||
#define PRM_MODE 2
|
||||
#define PRM_DISK_PATH 3
|
||||
#define PRM_HIRES_COLOR 4
|
||||
#define PRM_SOUND 5
|
||||
#define PRM_JOY_INPUT 6
|
||||
#define PRM_JOY_RANGE 7
|
||||
#define PRM_JOY_OX 8
|
||||
#define PRM_JOY_OY 9
|
||||
#define PRM_JOY_PC_CALIBRATE 10
|
||||
#define PRM_JOY_KYBD_SENSITIVITY 11
|
||||
#define PRM_ROM_PATH 12
|
||||
|
||||
|
||||
char system_path[SYSSIZE];
|
||||
char disk_path[DISKSIZE];
|
||||
|
||||
int apple_mode;
|
||||
int sound_mode;
|
||||
int color_mode;
|
||||
short joy_mode;
|
||||
short joy_step;
|
||||
short joy_center_x;
|
||||
short joy_center_y;
|
||||
short joy_range;
|
||||
short half_joy_range;
|
||||
|
||||
#ifdef PC_JOYSTICK
|
||||
int js_center_x;
|
||||
int js_center_y;
|
||||
long js_timelimit;
|
||||
int js_max_x;
|
||||
int js_max_y;
|
||||
int js_min_x;
|
||||
int js_min_y;
|
||||
#endif /* PC_JOYSTICK */
|
||||
|
||||
static char *config_filename;
|
||||
|
||||
struct match_table
|
||||
{
|
||||
const char *tag;
|
||||
int value;
|
||||
};
|
||||
|
||||
static const struct match_table prefs_table[] =
|
||||
{
|
||||
{"speed", PRM_SPEED},
|
||||
{"mode", PRM_MODE},
|
||||
{"path", PRM_DISK_PATH},
|
||||
{"disk path", PRM_DISK_PATH},
|
||||
{"disk_path", PRM_DISK_PATH},
|
||||
{"path", PRM_DISK_PATH},
|
||||
{"color", PRM_HIRES_COLOR},
|
||||
{"sound", PRM_SOUND},
|
||||
{"joystick", PRM_JOY_INPUT},
|
||||
{"joy range", PRM_JOY_RANGE},
|
||||
{"joystick range", PRM_JOY_RANGE},
|
||||
{"joy_range", PRM_JOY_RANGE},
|
||||
{"origin_x", PRM_JOY_OX},
|
||||
{"origin_y", PRM_JOY_OY},
|
||||
{"pc joystick parms", PRM_JOY_PC_CALIBRATE},
|
||||
{"pc_joystick_parms", PRM_JOY_PC_CALIBRATE},
|
||||
{"sensitivity", PRM_JOY_KYBD_SENSITIVITY},
|
||||
{"system path", PRM_ROM_PATH},
|
||||
{"system_path", PRM_ROM_PATH},
|
||||
{0, PRM_NONE}
|
||||
};
|
||||
|
||||
static const struct match_table modes_table[] =
|
||||
{
|
||||
{"][+", II_MODE},
|
||||
{"][+ undocumented", IIU_MODE},
|
||||
#ifdef APPLE_IIE
|
||||
{"//e", IIE_MODE},
|
||||
{0, IIE_MODE}
|
||||
#else /* !APPLE_IIE */
|
||||
{0, IIU_MODE}
|
||||
#endif /* !APPLE_IIE */
|
||||
};
|
||||
|
||||
static const struct match_table color_table[] =
|
||||
{
|
||||
{"black/white", NO_COLOR},
|
||||
{"lazy color", LAZY_COLOR},
|
||||
{"color", COLOR},
|
||||
{"lazy interpolated", LAZY_INTERP},
|
||||
{"interpolated", INTERP},
|
||||
{"off", 0},
|
||||
{"on", COLOR},
|
||||
{0, COLOR}
|
||||
};
|
||||
|
||||
static const struct match_table sound_table[] =
|
||||
{
|
||||
{"off", 0},
|
||||
{"pc_speaker", 1},
|
||||
{"on", 1},
|
||||
{0, 1},
|
||||
};
|
||||
|
||||
static const struct match_table joy_input_table[] =
|
||||
{
|
||||
{"off", JOY_OFF},
|
||||
{"keyboard", JOY_KYBD},
|
||||
{"linear", JOY_KYBD},
|
||||
#ifdef PC_JOYSTICK
|
||||
{"pc joystick", JOY_PCJOY},
|
||||
{"pc_joystick", JOY_PCJOY},
|
||||
#endif /* PC_JOYSTICK */
|
||||
#if 0
|
||||
{"digital", JOY_DIGITAL},
|
||||
#endif /* 0 */
|
||||
{0, JOY_KYBD}
|
||||
};
|
||||
|
||||
/* Find the number assigned to KEYWORD in a match table PARADIGM. If no match,
|
||||
* then the value associated with the terminating entry is used as a
|
||||
* default. */
|
||||
static int
|
||||
match (const struct match_table *paradigm, const char *keyword)
|
||||
{
|
||||
while (paradigm->tag && strcasecmp (paradigm->tag, keyword))
|
||||
paradigm++;
|
||||
return paradigm->value;
|
||||
}
|
||||
|
||||
/* Reverse match -- find a keyword associated with number KEY in
|
||||
* PARADIGM. The first match is used -- synonym keywords appearing later
|
||||
* in the table are not chosen.
|
||||
*
|
||||
* A null is returned for no match.
|
||||
*/
|
||||
static const char *reverse_match (const struct match_table *paradigm, int key)
|
||||
{
|
||||
while (paradigm->tag && key != paradigm->value)
|
||||
paradigm++;
|
||||
return paradigm->tag;
|
||||
}
|
||||
|
||||
/* Eat leading and trailing whitespace of string X. The old string is
|
||||
* overwritten and a new pointer is returned.
|
||||
*/
|
||||
static char *
|
||||
clean_string (char *x)
|
||||
{
|
||||
size_t y;
|
||||
|
||||
/* Leading white space */
|
||||
while (isspace (*x)) x++;
|
||||
|
||||
/* Trailing white space */
|
||||
y = strlen (x);
|
||||
while (y && x[y--] == ' ');
|
||||
x[y] = 0;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Load the configuration. Must be called *once* at start. */
|
||||
void
|
||||
load_settings (void)
|
||||
{
|
||||
/* set system defaults before user defaults. */
|
||||
strcpy (disk_path, "./disks");
|
||||
strcpy (system_path, "./rom");
|
||||
|
||||
{
|
||||
const char *homedir;
|
||||
|
||||
homedir = getenv ("HOME");
|
||||
config_filename = malloc (strlen (homedir) + 9);
|
||||
strcpy (config_filename, homedir);
|
||||
strcat (config_filename, "/.apple2");
|
||||
|
||||
/* config_filename is left allocated for convinence in
|
||||
* save_settings */
|
||||
}
|
||||
|
||||
{
|
||||
FILE *config_file;
|
||||
char *buffer = 0;
|
||||
size_t size = 0;
|
||||
|
||||
config_file = fopen (config_filename, "r");
|
||||
if (config_file == NULL)
|
||||
{
|
||||
printf (
|
||||
"Warning. Cannot open the .apple2 system defaults file.\n"
|
||||
"Make sure it's readable in your home directory.");
|
||||
printf ("Press RETURN to continue...");
|
||||
getchar ();
|
||||
return;
|
||||
}
|
||||
|
||||
while (getline (&buffer, &size, config_file) != -1)
|
||||
{
|
||||
char *parameter;
|
||||
char *argument;
|
||||
|
||||
/* Split line between parameter and argument */
|
||||
|
||||
parameter = buffer;
|
||||
argument = strchr (buffer, '=');
|
||||
argument[0] = 0;
|
||||
argument++;
|
||||
|
||||
parameter = clean_string (parameter);
|
||||
argument = clean_string (argument);
|
||||
|
||||
switch (match (prefs_table, parameter))
|
||||
{
|
||||
case PRM_NONE:
|
||||
fprintf (stderr, "Unrecognized config parameter `%s'", parameter);
|
||||
break;
|
||||
|
||||
case PRM_SPEED:
|
||||
{
|
||||
int x;
|
||||
|
||||
x = strtol (argument, 0, 0);
|
||||
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
|
||||
cpu65_delay = MAX_APPLE_DELAY - x + 1;
|
||||
if (cpu65_delay < 1)
|
||||
cpu65_delay = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRM_MODE:
|
||||
apple_mode = match (modes_table, argument);
|
||||
break;
|
||||
|
||||
case PRM_DISK_PATH:
|
||||
strncpy (disk_path, argument, DISKSIZE);
|
||||
break;
|
||||
|
||||
case PRM_HIRES_COLOR:
|
||||
color_mode = match (color_table, argument);
|
||||
break;
|
||||
|
||||
case PRM_SOUND:
|
||||
sound_mode = match (sound_table, argument);
|
||||
break;
|
||||
|
||||
case PRM_JOY_INPUT:
|
||||
joy_mode = match (joy_input_table, argument);
|
||||
break;
|
||||
|
||||
case PRM_JOY_RANGE:
|
||||
joy_range = strtol (argument, 0, 0);
|
||||
if (joy_range < 10)
|
||||
joy_range = 10;
|
||||
else if (joy_range > 256)
|
||||
joy_range = 256;
|
||||
half_joy_range = joy_range / 2;
|
||||
|
||||
if (joy_center_x > joy_range)
|
||||
joy_center_x = half_joy_range;
|
||||
if (joy_center_y > joy_range)
|
||||
joy_center_y = half_joy_range;
|
||||
break;
|
||||
|
||||
case PRM_JOY_OX:
|
||||
joy_center_x = strtol (argument, 0, 0);
|
||||
if (joy_center_x < 0)
|
||||
joy_center_x = 0;
|
||||
else if (joy_center_x > 255)
|
||||
joy_center_x = 255;
|
||||
|
||||
if (joy_center_x > joy_range)
|
||||
joy_center_x = half_joy_range;
|
||||
break;
|
||||
|
||||
case PRM_JOY_OY:
|
||||
joy_center_y = strtol (argument, 0, 0);
|
||||
if (joy_center_y < 0)
|
||||
joy_center_y = 0;
|
||||
else if (joy_center_y > 255)
|
||||
joy_center_y = 255;
|
||||
|
||||
if (joy_center_y > joy_range)
|
||||
joy_center_y = half_joy_range;
|
||||
break;
|
||||
|
||||
case PRM_JOY_PC_CALIBRATE:
|
||||
#ifdef PC_JOYSTICK
|
||||
/* pc joystick parms generated by the calibration routine
|
||||
(shouldn't need to hand tweak these) = origin_x origin_y max_x
|
||||
min_x max_y min_y js_timelimit */
|
||||
js_center_x = strtol (argument, &argument, 10);
|
||||
js_center_y = strtol (argument, &argument, 10);
|
||||
js_max_x = strtol (argument, &argument, 10);
|
||||
if (js_max_x < 0)
|
||||
js_max_x = 0;
|
||||
js_min_x = strtol (argument, &argument, 10);
|
||||
if (js_min_x < 0)
|
||||
js_min_x = 0;
|
||||
|
||||
js_max_y = strtol (argument, &argument, 10);
|
||||
if (js_max_y < 0)
|
||||
js_max_y = 0;
|
||||
js_min_y = strtol (argument, &argument, 10);
|
||||
if (js_min_y < 0)
|
||||
js_min_y = 0;
|
||||
|
||||
js_timelimit = strtol (argument, &argument, 10);
|
||||
if (js_timelimit < 2)
|
||||
js_timelimit = 2;
|
||||
|
||||
c_open_joystick ();
|
||||
c_calculate_joystick_parms (); /* calculate the associated parms */
|
||||
#endif
|
||||
|
||||
case PRM_JOY_KYBD_SENSITIVITY:
|
||||
joy_step = strtol (argument, 0, 0);
|
||||
if (joy_step < 1)
|
||||
joy_step = 1;
|
||||
else if (joy_step > 100)
|
||||
joy_step = 100;
|
||||
break;
|
||||
|
||||
case PRM_ROM_PATH:
|
||||
strncpy (system_path, argument, SYSSIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose (config_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Save the configuration */
|
||||
void
|
||||
save_settings (void)
|
||||
{
|
||||
FILE *config_file;
|
||||
|
||||
config_file = fopen (config_filename, "w");
|
||||
if (config_file == NULL)
|
||||
{
|
||||
printf (
|
||||
"Cannot open the .apple2 system defaults file for writing.\n"
|
||||
"Make sure it has rw permission in your home directory.");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf (config_file,
|
||||
"speed = %d\n"
|
||||
"mode = %s\n"
|
||||
"disk path = %s\n"
|
||||
"color = %s\n"
|
||||
"sound = %s\n"
|
||||
"joystick = %s\n"
|
||||
"joystick range = %d\n"
|
||||
"origin_x = %d\n"
|
||||
"origin_y = %d\n"
|
||||
"sensitivity = %d%%\n"
|
||||
"system path = %s\n",
|
||||
MAX_APPLE_DELAY + 1 - cpu65_delay,
|
||||
reverse_match (modes_table, apple_mode),
|
||||
disk_path,
|
||||
reverse_match (color_table, color_mode),
|
||||
reverse_match (sound_table, sound_mode),
|
||||
reverse_match (joy_input_table, joy_mode),
|
||||
joy_range,
|
||||
joy_center_x,
|
||||
joy_center_y,
|
||||
joy_step,
|
||||
system_path);
|
||||
|
||||
#ifdef PC_JOYSTICK
|
||||
fprintf (config_file,
|
||||
"pc joystick parms = %d %d %d %d %d %d %ld\n",
|
||||
js_center_x, js_center_y, js_max_x, js_min_x,
|
||||
js_max_y, js_min_y, js_timelimit);
|
||||
#endif
|
||||
|
||||
fclose (config_file);
|
||||
}
|
74
src/prefs.h
Normal file
74
src/prefs.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Configuration defines
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PREFS_H
|
||||
#define PREFS_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#define SYSSIZE 4096
|
||||
extern char system_path[SYSSIZE];
|
||||
#define DISKSIZE 4096
|
||||
extern char disk_path[DISKSIZE];
|
||||
|
||||
extern int apple_mode; /* undocumented instructions or //e mode */
|
||||
extern int sound_mode; /* PC speaker or OFF */
|
||||
extern int color_mode;
|
||||
|
||||
/* generic joystick settings */
|
||||
extern short joy_mode;
|
||||
extern short joy_step;
|
||||
extern short joy_center_x;
|
||||
extern short joy_center_y;
|
||||
extern short joy_range;
|
||||
extern short half_joy_range;
|
||||
|
||||
#ifdef PC_JOYSTICK
|
||||
/* real joystick settings */
|
||||
extern int js_center_x;
|
||||
extern int js_center_y;
|
||||
extern long js_timelimit;
|
||||
extern int js_max_x;
|
||||
extern int js_max_y;
|
||||
extern int js_min_x;
|
||||
extern int js_min_y;
|
||||
#endif /* PC_JOYSTICK */
|
||||
|
||||
/* functions in prefs.c */
|
||||
extern void load_settings(void);
|
||||
extern void save_settings(void);
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
/* values for apple_mode */
|
||||
#define IIE_MODE 2
|
||||
#define IIU_MODE 1
|
||||
#define II_MODE 0
|
||||
|
||||
/* values for color_mode */
|
||||
#define NO_COLOR 0
|
||||
#define LAZY_COLOR 1
|
||||
#define COLOR 2
|
||||
#define LAZY_INTERP 3
|
||||
#define INTERP 4
|
||||
|
||||
/* values for joy_mode */
|
||||
#define JOY_OFF 0
|
||||
#define JOY_KYBD 1
|
||||
#define JOY_DIGITAL 2
|
||||
#define JOY_PCJOY 3
|
||||
|
||||
#endif /* PREFS_H */
|
215
src/svideo.c
Normal file
215
src/svideo.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: svgalib graphics support
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <vga.h>
|
||||
#include <vgakeyboard.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/kd.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "video.h"
|
||||
#include "misc.h"
|
||||
#include "keys.h"
|
||||
|
||||
/* I need at least 560x192 for 80col. it seems that direct linear
|
||||
* framebuffer access to anything in the realm of 640x480x256 not
|
||||
* standard with vga/svga?
|
||||
* Memory sizes are hardcode here. ugly ugly ugly.
|
||||
*/
|
||||
|
||||
static unsigned char *svga_GM; /* SVGA base address of graphic area */
|
||||
static unsigned char vga_mem_page_0[64000]; /* page0 framebuffer */
|
||||
static unsigned char vga_mem_page_1[64000]; /* page1 framebuffer */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
video_setpage(p): Switch to screen page p
|
||||
------------------------------------------------------------------------- */
|
||||
void video_setpage(int p)
|
||||
{
|
||||
if (p == video__current_page) return;
|
||||
|
||||
if (p)
|
||||
{
|
||||
memcpy(vga_mem_page_0,svga_GM,64000);
|
||||
memcpy(svga_GM,vga_mem_page_1,64000);
|
||||
video__current_page = 1;
|
||||
video__fb1 = vga_mem_page_0;
|
||||
video__fb2 = svga_GM;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(vga_mem_page_1,svga_GM,64000);
|
||||
memcpy(svga_GM,vga_mem_page_0,64000);
|
||||
video__current_page = 0;
|
||||
video__fb1 = svga_GM;
|
||||
video__fb2 = vga_mem_page_1;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_colors(): Initialize color palette
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
static void c_initialize_colors()
|
||||
{
|
||||
|
||||
static unsigned int col2[ 3 ] = { 27, 40, 62 };
|
||||
|
||||
int i, j;
|
||||
|
||||
/* align the palette for hires graphics */
|
||||
for (i = 0; i < 8; i++)
|
||||
for (j = 0; j < 3; j++)
|
||||
vga_setpalette( j+i*3+32, (i & 1) ? col2[ j ] : 0,
|
||||
(i & 2) ? col2[ j ] : 0,
|
||||
(i & 4) ? col2[ j ] : 0 );
|
||||
|
||||
vga_setpalette( COLOR_FLASHING_BLACK, 0, 0, 0 );
|
||||
vga_setpalette( COLOR_FLASHING_WHITE, 63, 63, 63 );
|
||||
|
||||
/* dhires colors are bass-ackwards because it's easier for me to
|
||||
deal with the endianness. */
|
||||
vga_setpalette( 0x0, 0, 0, 0 ); /* (0) Black */
|
||||
vga_setpalette( 0x1, 0, 0, 32 ); /* (2) Dark Blue */
|
||||
vga_setpalette( 0x2, 0, 36, 0 ); /* (4) Dark Green */
|
||||
vga_setpalette( 0x3, 28, 6, 63 ); /* (6) Medium Blue */
|
||||
vga_setpalette( 0x4, 37, 21, 10 ); /* (8) Brown */
|
||||
vga_setpalette( 0x5, 37, 42, 42 ); /* (a) Light Grey */
|
||||
vga_setpalette( 0x6, 0, 63, 0 ); /* (c) Green */
|
||||
vga_setpalette( 0x7, 32, 63, 32 ); /* (e) Aqua */
|
||||
vga_setpalette( 0x8, 48, 0, 12 ); /* (1) Magenta */
|
||||
vga_setpalette( 0x9, 41, 13, 42 ); /* (3) Purple */
|
||||
vga_setpalette( 0xa, 26, 26, 26 ); /* (5) Light Grey */
|
||||
vga_setpalette( 0xb, 3, 47, 58 ); /* (7) Light Blue */
|
||||
vga_setpalette( 0xc, 63, 6, 11 ); /* (9) Orange */
|
||||
vga_setpalette( 0xd, 63, 39, 37 ); /* (b) Pink */
|
||||
vga_setpalette( 0xe, 63, 63, 0 ); /* (d) Yellow */
|
||||
vga_setpalette( 0xf, 63, 63, 63 ); /* (f) White */
|
||||
|
||||
/* lores colors (<<4) */
|
||||
vga_setpalette(0x10, 48, 0, 12 ); /* Magenta */
|
||||
vga_setpalette(0x20, 0, 0, 32 ); /* Dark Blue */
|
||||
vga_setpalette(0x30, 41, 13, 42 ); /* Purple */
|
||||
vga_setpalette(0x40, 0, 36, 0 ); /* Dark Green */
|
||||
vga_setpalette(0x50, 26, 26, 26 ); /* Dark Gray */
|
||||
vga_setpalette(0x60, 28, 6, 63 ); /* Medium Blue */
|
||||
vga_setpalette(0x70, 3, 47, 58 ); /* Light Blue */
|
||||
vga_setpalette(0x80, 37, 21, 10 ); /* Brown */
|
||||
vga_setpalette(0x90, 63, 6, 11 ); /* Orange */
|
||||
vga_setpalette(0xa0, 37, 42, 42 ); /* Light Grey */
|
||||
vga_setpalette(0xb0, 63, 39, 37 ); /* Pink */
|
||||
vga_setpalette(0xc0, 0, 63, 0 ); /* Green */
|
||||
vga_setpalette(0xd0, 63, 63, 0 ); /* Yellow */
|
||||
vga_setpalette(0xe0, 32, 63, 32 ); /* Aqua */
|
||||
vga_setpalette(0xf0, 63, 63, 63 ); /* White */
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_keyboard()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
static void c_initialize_keyboard()
|
||||
{
|
||||
if (keyboard_init()) {
|
||||
printf("Error: Could not switch to RAW keyboard mode.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
keyboard_translatekeys(DONT_CATCH_CTRLC);
|
||||
keyboard_seteventhandler( c_read_raw_key );
|
||||
}
|
||||
|
||||
static void c_flash_cursor(int on) {
|
||||
if (!on) {
|
||||
vga_setpalette( COLOR_FLASHING_BLACK, 0, 0, 0 );
|
||||
vga_setpalette( COLOR_FLASHING_WHITE, 63, 63, 63 );
|
||||
} else {
|
||||
vga_setpalette( COLOR_FLASHING_BLACK, 63, 63, 63 );
|
||||
vga_setpalette( COLOR_FLASHING_WHITE, 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
video_init()
|
||||
------------------------------------------------------------------------- */
|
||||
void video_init(void) {
|
||||
/* I'm forcing VGA mode since it seems to be supported by
|
||||
* the lowest common denominator cards.
|
||||
*/
|
||||
printf("Using standard VGA 320x200 mode.\n");
|
||||
printf("Press RETURN to continue...");
|
||||
getchar();
|
||||
|
||||
vga_setchipset( VGA );
|
||||
if (vga_init()) {
|
||||
printf("Cannot initialize svgalib!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vga_setmode( G320x200x256 );
|
||||
|
||||
/* vga_claimvideomemory( 131072 );*/
|
||||
c_initialize_keyboard();
|
||||
svga_GM = video__fb1 = vga_getgraphmem();
|
||||
video__fb2 = vga_mem_page_1;
|
||||
|
||||
memset(video__fb1,0,64000); /* start as black */
|
||||
memset(video__fb2,0,64000);
|
||||
|
||||
c_initialize_colors();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void video_shutdown(void) {
|
||||
vga_setmode(TEXT);
|
||||
keyboard_close();
|
||||
}
|
||||
|
||||
void video_sync(int block)
|
||||
{
|
||||
static int flash_count;
|
||||
|
||||
if (block)
|
||||
{
|
||||
/* keyboard_waitforupdate(); --- seems to cause bad crashes... */
|
||||
usleep(TIMER_DELAY);
|
||||
keyboard_update();
|
||||
}
|
||||
else
|
||||
keyboard_update();
|
||||
|
||||
switch (++flash_count)
|
||||
{
|
||||
case 6:
|
||||
c_flash_cursor(1);
|
||||
break;
|
||||
case 12:
|
||||
c_flash_cursor(0);
|
||||
flash_count = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
232
src/video.h
Normal file
232
src/video.h
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Video definitions
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef A2_VIDEO_H
|
||||
#define A2_VIDEO_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Prepare the video system, converting console to graphics mode, or
|
||||
* opening X window, or whatever. This is called only once when the
|
||||
* emulator is run
|
||||
*/
|
||||
void video_init(void);
|
||||
|
||||
/* Undo anything done by video_init. This is called before exiting the
|
||||
* emulator.
|
||||
*/
|
||||
void video_shutdown(void);
|
||||
|
||||
/* Setup the display. This may be called multiple times in a run, and is
|
||||
* used when graphics parameters (II+ vs //e, hires color representation) may
|
||||
* have changed.
|
||||
*
|
||||
* In future, all relevant information will be communicated through
|
||||
* FLAGS. For now, however, it is ignored and global variables are used
|
||||
* instead.
|
||||
*
|
||||
* This function is responsible for inserting any needed video-specific hooks
|
||||
* into the 6502 memory indirection table. It should *not* hook the
|
||||
* soft-switches.
|
||||
*
|
||||
*/
|
||||
void video_set(int flags);
|
||||
|
||||
/* Set the font used by the display. QTY characters are loaded starting
|
||||
* with FIRST, from DATA. DATA contains 8 bytes for each character, each
|
||||
* byte representing a row (top-to-bottom). The row byte contains 7
|
||||
* pixels in little-endian format.
|
||||
*
|
||||
* MODE selects the colors to use
|
||||
*
|
||||
* 0 - Normal text
|
||||
* 1 - MouseText (usually treat as Normal)
|
||||
* 2 - Inverse
|
||||
* 3 - Flash
|
||||
*
|
||||
* The extra MouseText mode is in case we want to emulate certain RGB
|
||||
* adaptors which color normal text and MouseText differently. I had one
|
||||
* once for a //c.
|
||||
*/
|
||||
void video_loadfont(int first,
|
||||
int qty,
|
||||
const unsigned char *data,
|
||||
int mode);
|
||||
|
||||
/* Redraw the display. This is called after exiting an interface display,
|
||||
* when changes have been made to the Apple's emulated framebuffer that
|
||||
* bypass the driver's hooks, or when the video mode has changed.
|
||||
*/
|
||||
void video_redraw(void);
|
||||
|
||||
/* Change the displayed video page to PAGE
|
||||
* 0 - Page 1: $400-$7ff/$2000-$3fff
|
||||
* 1 - Page 2: $800-$bff/$4000-$5fff
|
||||
*/
|
||||
void video_setpage(int page);
|
||||
|
||||
/* Like loadfont, but writes to a seperate 256 character table used by
|
||||
* video_plotchar and not the apple text-mode display.
|
||||
*/
|
||||
void video_loadfont_int(int first, int qty, const unsigned char *data);
|
||||
|
||||
/* Plot a character to the text mode screen, *not* writing to apple
|
||||
* memory. This is used by the interface screens.
|
||||
*
|
||||
* ROW, COL, and CODE are self-expanatory. COLOR gives the color scheme
|
||||
* to use:
|
||||
*
|
||||
* 0 - Green text on Black background
|
||||
* 1 - Green text on Blue background
|
||||
* 2 - Red text on Black background
|
||||
*/
|
||||
void video_plotchar(int row, int col, int color, unsigned char code);
|
||||
|
||||
/* Called at about 30Hz (this may change in future), and when waiting in
|
||||
* the interface screens.
|
||||
*
|
||||
* Should flush any video data to the real screen (if any kind of caching
|
||||
* is in use), check for keyboard input (presently reported via
|
||||
* c_read_raw_key), and handle flashing text characters.
|
||||
*/
|
||||
void video_sync(int block);
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
/**** Private stuff follows *****/
|
||||
|
||||
#ifdef _640x400
|
||||
/* 640x400 mode really isn't what it advertises. It's really 560x384 with 4
|
||||
* extra bytes on each side for color interpolation hack. This is yet another
|
||||
* area where I've traded the optimization gain (especially on older slower
|
||||
* machines) for a standard resolution.
|
||||
*/
|
||||
#define SCANWIDTH 568
|
||||
#define SCANHEIGHT 384
|
||||
#define SCANSTEP SCANWIDTH-12
|
||||
#else /* !_640x400 */
|
||||
#define SCANWIDTH 320
|
||||
#define SCANHEIGHT 200
|
||||
#define SCANSTEP SCANWIDTH-6
|
||||
#endif /* !_640x400 */
|
||||
|
||||
#define COLOR_BLACK 0
|
||||
|
||||
#define COLOR_DARK_RED 35
|
||||
#define COLOR_MEDIUM_RED 36
|
||||
#define COLOR_LIGHT_RED 37 /* hgr used */
|
||||
|
||||
#define COLOR_DARK_GREEN 38
|
||||
#define COLOR_MEDIUM_GREEN 39
|
||||
#define COLOR_LIGHT_GREEN 40 /* hgr used */
|
||||
|
||||
#define COLOR_DARK_YELLOW 41
|
||||
#define COLOR_MEDIUM_YELLOW 42
|
||||
#define COLOR_LIGHT_YELLOW 43
|
||||
|
||||
#define COLOR_DARK_BLUE 44
|
||||
#define COLOR_MEDIUM_BLUE 45
|
||||
#define COLOR_LIGHT_BLUE 46 /* hgr used */
|
||||
|
||||
#define COLOR_DARK_PURPLE 47
|
||||
#define COLOR_MEDIUM_PURPLE 48
|
||||
#define COLOR_LIGHT_PURPLE 49 /* hgr used */
|
||||
|
||||
#define COLOR_DARK_CYAN 50
|
||||
#define COLOR_MEDIUM_CYAN 51
|
||||
#define COLOR_LIGHT_CYAN 52
|
||||
|
||||
#define COLOR_DARK_WHITE 53
|
||||
#define COLOR_MEDIUM_WHITE 54
|
||||
#define COLOR_LIGHT_WHITE 55
|
||||
|
||||
#define COLOR_FLASHING_BLACK 56
|
||||
#define COLOR_FLASHING_WHITE 57
|
||||
#define COLOR_FLASHING_UNGREEN 58
|
||||
#define COLOR_FLASHING_GREEN 59
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
/* ----------------------------------
|
||||
generic graphics globals
|
||||
---------------------------------- */
|
||||
|
||||
/* Pointers to framebuffer (can be VGA memory or host buffer)
|
||||
*/
|
||||
|
||||
extern unsigned char *video__fb1,*video__fb2;
|
||||
|
||||
#ifdef _640x400
|
||||
extern unsigned char video__wider_hires_even[0x1000];
|
||||
extern unsigned char video__wider_hires_odd[0x1000];
|
||||
#endif /* _640x400 */
|
||||
|
||||
extern unsigned char video__hires_even[0x800];
|
||||
extern unsigned char video__hires_odd[0x800];
|
||||
|
||||
extern unsigned char video__dhires1[256];
|
||||
extern unsigned char video__dhires2[256];
|
||||
|
||||
extern int video__current_page; /* Current visual page */
|
||||
|
||||
extern int video__strictcolors;
|
||||
|
||||
#ifdef _640x400
|
||||
extern unsigned char video__wider_int_font[3][0x8000];
|
||||
#else /* _640x400 */
|
||||
extern unsigned char video__int_font[3][0x4000];
|
||||
#endif /* _640x400 */
|
||||
|
||||
/* --- Precalculated hi-res page offsets given addr --- */
|
||||
extern unsigned int video__screen_addresses[8192];
|
||||
extern unsigned char video__columns[8192];
|
||||
|
||||
extern unsigned char video__odd_colors[2];
|
||||
extern unsigned char video__even_colors[2];
|
||||
|
||||
/* Hooks */
|
||||
|
||||
void video__write_text0(),
|
||||
video__write_text0_mixed(),
|
||||
video__write_text1(),
|
||||
video__write_text1_mixed(),
|
||||
video__write_even0(),
|
||||
video__write_odd0(),
|
||||
video__write_even0_mixed(),
|
||||
video__write_odd0_mixed(),
|
||||
video__write_even1(),
|
||||
video__write_odd1(),
|
||||
video__write_even1_mixed(),
|
||||
video__write_odd1_mixed();
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
void video__write_2e_text0(),
|
||||
video__write_2e_text0_mixed(),
|
||||
video__write_2e_text1(),
|
||||
video__write_2e_text1_mixed(),
|
||||
video__write_2e_odd0(),
|
||||
video__write_2e_even0(),
|
||||
video__write_2e_odd0_mixed(),
|
||||
video__write_2e_even0_mixed(),
|
||||
video__write_2e_odd1(),
|
||||
video__write_2e_even1(),
|
||||
video__write_2e_odd1_mixed(),
|
||||
video__write_2e_even1_mixed();
|
||||
#endif /* APPLE_IIE */
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#endif /* !A2_VIDEO_H */
|
679
src/vidsup.c
Normal file
679
src/vidsup.c
Normal file
@ -0,0 +1,679 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: Video support
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "video.h"
|
||||
#include "cpu.h"
|
||||
#include "misc.h"
|
||||
#include "prefs.h"
|
||||
|
||||
#ifdef _640x400
|
||||
unsigned char video__wider_font[0x8000];
|
||||
#endif /* _640x400 */
|
||||
|
||||
unsigned char video__font[0x4000];
|
||||
|
||||
/* --- Precalculated hi-res page offsets given addr --- */
|
||||
unsigned int video__screen_addresses[8192];
|
||||
unsigned char video__columns[8192];
|
||||
|
||||
unsigned char *video__fb1,*video__fb2;
|
||||
|
||||
#ifdef _640x400
|
||||
unsigned char video__wider_hires_even[0x1000];
|
||||
unsigned char video__wider_hires_odd[0x1000];
|
||||
#endif
|
||||
unsigned char video__hires_even[0x800];
|
||||
unsigned char video__hires_odd[0x800];
|
||||
|
||||
unsigned char video__dhires1[256];
|
||||
unsigned char video__dhires2[256];
|
||||
|
||||
/* Interface font:
|
||||
* (probably could be made static)
|
||||
*
|
||||
* Unlike the normal font, only one version is stored, since the interface
|
||||
* is always displayed in forty columns.
|
||||
*/
|
||||
#ifdef _640x400
|
||||
unsigned char video__wider_int_font[3][0x8000];
|
||||
#else /* _640x400 */
|
||||
unsigned char video__int_font[3][0x4000];
|
||||
#endif /* _640x400 */
|
||||
|
||||
int video__current_page; /* Current visual page */
|
||||
|
||||
int video__strictcolors;
|
||||
|
||||
void video_loadfont(int first,
|
||||
int quantity,
|
||||
const unsigned char *data,
|
||||
int mode)
|
||||
{
|
||||
int i,j;
|
||||
unsigned char x,y,fg,bg;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case 2:
|
||||
fg = COLOR_BLACK; bg = COLOR_LIGHT_WHITE; break;
|
||||
case 3:
|
||||
fg = COLOR_FLASHING_WHITE; bg = COLOR_FLASHING_BLACK; break;
|
||||
default:
|
||||
fg = COLOR_LIGHT_WHITE; bg = COLOR_BLACK; break;
|
||||
}
|
||||
|
||||
i = quantity * 8;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
j = 8;
|
||||
x = data[i];
|
||||
while (j--)
|
||||
{
|
||||
y = (x & 128) ? fg : bg;
|
||||
|
||||
#ifdef _640x400
|
||||
video__wider_font[(first << 7) + (i << 4) + (j << 1)] =
|
||||
video__wider_font[(first << 7) + (i << 4) + (j << 1) + 1] =
|
||||
#endif /* _640x400 */
|
||||
video__font[(first << 6) + (i << 3) + j] = y;
|
||||
x <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char video__odd_colors[2] = {COLOR_LIGHT_PURPLE, COLOR_LIGHT_BLUE};
|
||||
unsigned char video__even_colors[2] = {COLOR_LIGHT_GREEN, COLOR_LIGHT_RED};
|
||||
|
||||
/* 40col/80col/lores/hires/dhires line offsets */
|
||||
unsigned short video__line_offset[24] =
|
||||
{ 0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380,
|
||||
0x028, 0x0A8, 0x128, 0x1A8, 0x228, 0x2A8, 0x328, 0x3A8,
|
||||
0x050, 0x0D0, 0x150, 0x1D0, 0x250, 0x2D0, 0x350, 0x3D0 };
|
||||
|
||||
unsigned char video__dhires1[256] = {
|
||||
0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,
|
||||
0x0,0x1,0x3,0x3,0x5,0x5,0x7,0x7,0x9,0x9,0xb,0xb,0xd,0xd,0xf,0xf,
|
||||
0x0,0x1,0x2,0x3,0x6,0x5,0x6,0x7,0xa,0x9,0xa,0xb,0xe,0xd,0xe,0xf,
|
||||
0x0,0x1,0x3,0x3,0x7,0x5,0x7,0x7,0xb,0x9,0xb,0xb,0xf,0xd,0xf,0xf,
|
||||
0x0,0x1,0x2,0x3,0x4,0x4,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,
|
||||
0x0,0x1,0x3,0x3,0x5,0x5,0x7,0x7,0xd,0x9,0xb,0xb,0xd,0xd,0xf,0xf,
|
||||
0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0xe,0x9,0xa,0xb,0xe,0xd,0xe,0xf,
|
||||
0x0,0x1,0x7,0x3,0x7,0x5,0x7,0x7,0xf,0x9,0xb,0xb,0xf,0xd,0xf,0xf,
|
||||
};
|
||||
|
||||
unsigned char video__dhires2[256] = {
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x8,0x0,0xb,0x8,0xd,0x0,0x0,
|
||||
0x1,0x1,0x1,0x1,0x0,0x5,0x1,0x1,0x0,0x9,0xb,0xb,0x0,0xd,0xf,0xf,
|
||||
0x0,0x1,0x2,0x2,0x2,0x5,0x2,0x2,0x0,0xa,0xa,0xa,0xe,0xd,0x2,0x2,
|
||||
0x3,0x3,0x3,0x3,0x7,0x5,0x7,0x7,0x0,0xb,0xb,0xb,0xf,0xd,0xf,0xf,
|
||||
0x0,0x0,0x4,0x0,0x4,0x4,0x4,0x4,0xc,0x8,0x4,0x8,0xc,0xd,0x4,0x4,
|
||||
0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0xd,0x4,0x4,0x4,0xd,0xd,0x4,0x4,
|
||||
0x6,0x6,0x6,0x2,0xe,0x6,0x6,0x6,0xe,0xe,0xa,0xa,0xe,0x6,0xe,0x6,
|
||||
0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0xf,0xf,0xb,0xb,0xf,0xf,0xf,0xf,
|
||||
};
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_dhires_values()
|
||||
------------------------------------------------------------------------- */
|
||||
static void c_initialize_dhires_values(void) {
|
||||
int i;
|
||||
/* int value, v; */
|
||||
/* unsigned char locolor, hicolor; */
|
||||
|
||||
/* precalculate the colors for all the 256*8 bit combinations. */
|
||||
/* for (value = 0x00, v = 0; value <= 0xFF; value++) { */
|
||||
/* locolor = (value & 0x0F) | 0x10; */
|
||||
/* hicolor = (value << 4) | 0x10; */
|
||||
|
||||
/* dhires_colors[v++] = locolor; */
|
||||
/* dhires_colors[v++] = locolor; */
|
||||
/* dhires_colors[v++] = locolor; */
|
||||
/* dhires_colors[v++] = locolor; */
|
||||
|
||||
/* dhires_colors[v++] = hicolor; */
|
||||
/* dhires_colors[v++] = hicolor; */
|
||||
/* dhires_colors[v++] = hicolor; */
|
||||
/* dhires_colors[v++] = hicolor; */
|
||||
/* } */
|
||||
|
||||
for (i = 0; i < 0x80; i++) {
|
||||
video__dhires1[i+0x80] = video__dhires1[i];
|
||||
video__dhires2[i+0x80] = video__dhires2[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_hires_values()
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
static void c_initialize_hires_values(void)
|
||||
{
|
||||
int value, b, v, e, /*color_toggle,*/ last_not_black;
|
||||
|
||||
/* precalculate the colors for all the 256*8 bit combinations. */
|
||||
for (value = 0x00; value <= 0xFF; value++) {
|
||||
for (e = value * 8, last_not_black = 0, v = value, b = 0;
|
||||
b < 7; b++, v >>= 1, e++)
|
||||
{
|
||||
if (v & 1)
|
||||
{
|
||||
video__hires_even[ e ] = last_not_black ?
|
||||
COLOR_LIGHT_WHITE :
|
||||
((b & 1) ?
|
||||
((value & 0x80) ?
|
||||
COLOR_LIGHT_RED :
|
||||
COLOR_LIGHT_GREEN) :
|
||||
((value & 0x80) ?
|
||||
COLOR_LIGHT_BLUE :
|
||||
COLOR_LIGHT_PURPLE));
|
||||
|
||||
video__hires_odd[ e ] = last_not_black ?
|
||||
COLOR_LIGHT_WHITE :
|
||||
((b & 1) ?
|
||||
((value & 0x80) ?
|
||||
COLOR_LIGHT_BLUE :
|
||||
COLOR_LIGHT_PURPLE) :
|
||||
((value & 0x80) ?
|
||||
COLOR_LIGHT_RED :
|
||||
COLOR_LIGHT_GREEN));
|
||||
|
||||
if (last_not_black && b > 0)
|
||||
video__hires_even[ e - 1 ] = COLOR_LIGHT_WHITE,
|
||||
video__hires_odd[ e - 1 ] = COLOR_LIGHT_WHITE;
|
||||
|
||||
last_not_black = 1;
|
||||
}
|
||||
else
|
||||
video__hires_even[ e ] = COLOR_BLACK,
|
||||
video__hires_odd[ e ] = COLOR_BLACK,
|
||||
last_not_black = 0;
|
||||
}
|
||||
}
|
||||
if (color_mode == 0) { /* Black and White */
|
||||
for (value = 0x00; value <= 0xFF; value++) {
|
||||
for (b = 0, e = value * 8; b < 7; b++, e++) {
|
||||
if (video__hires_even[ e ] != COLOR_BLACK)
|
||||
video__hires_even[ e ] = COLOR_LIGHT_WHITE;
|
||||
if (video__hires_odd[ e ] != COLOR_BLACK)
|
||||
video__hires_odd[ e ] = COLOR_LIGHT_WHITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (color_mode == LAZY_INTERP) /* Lazy Interpolated color */
|
||||
{
|
||||
for (value = 0x00; value <= 0xFF; value++)
|
||||
{
|
||||
for (b = 1, e = value * 8 + 1; b <= 5; b += 2, e += 2)
|
||||
{
|
||||
if (video__hires_even[ e ] == COLOR_BLACK &&
|
||||
video__hires_even[ e - 1 ] != COLOR_BLACK &&
|
||||
video__hires_even[ e + 1 ] != COLOR_BLACK)
|
||||
video__hires_even[ e ] =
|
||||
video__hires_even[ e - 1 ];
|
||||
|
||||
if (video__hires_odd[ e ] == COLOR_BLACK &&
|
||||
video__hires_odd[ e - 1 ] != COLOR_BLACK &&
|
||||
video__hires_odd[ e + 1 ] != COLOR_BLACK)
|
||||
video__hires_odd[ e ] =
|
||||
video__hires_odd[ e - 1 ];
|
||||
}
|
||||
|
||||
for (b = 0, e = value * 8; b <= 6; b += 2, e += 2) {
|
||||
if (video__hires_odd[ e ] == COLOR_BLACK) {
|
||||
if (b > 0 && b < 6) {
|
||||
if (video__hires_even[e+1] != COLOR_BLACK &&
|
||||
video__hires_even[e-1] != COLOR_BLACK &&
|
||||
video__hires_even[e+1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e-1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] =
|
||||
video__hires_even[e-1];
|
||||
} else if (b == 0) {
|
||||
if (video__hires_even[e+1] != COLOR_BLACK &&
|
||||
video__hires_even[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] =
|
||||
video__hires_even[e+1];
|
||||
} else {
|
||||
if (video__hires_even[e-1] != COLOR_BLACK &&
|
||||
video__hires_even[e-1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_even[ e ] =
|
||||
video__hires_even[ e - 1 ];
|
||||
}
|
||||
}
|
||||
|
||||
if (video__hires_odd[ e ] == COLOR_BLACK) {
|
||||
if (b > 0 && b < 6) {
|
||||
if (video__hires_odd[e+1] != COLOR_BLACK &&
|
||||
video__hires_odd[e-1] != COLOR_BLACK &&
|
||||
video__hires_odd[e+1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e-1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e-1];
|
||||
}
|
||||
else if (b == 0) {
|
||||
if (video__hires_odd[e+1] != COLOR_BLACK &&
|
||||
video__hires_odd[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e+1];
|
||||
}
|
||||
else if
|
||||
(video__hires_odd[e-1] != COLOR_BLACK &&
|
||||
video__hires_odd[e-1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (color_mode == INTERP) { /* Color and strict interpolation */
|
||||
for (value = 0x00; value <= 0xFF; value++) {
|
||||
for (b = 1, e = value * 8 + 1; b <= 5; b += 2, e += 2) {
|
||||
if (video__hires_even[e] == COLOR_BLACK) {
|
||||
if (video__hires_even[e-1] != COLOR_BLACK &&
|
||||
video__hires_even[e+1] != COLOR_BLACK &&
|
||||
video__hires_even[e-1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] =
|
||||
video__hires_even[e-1];
|
||||
|
||||
else if (
|
||||
video__hires_even[e-1] != COLOR_BLACK &&
|
||||
video__hires_even[e+1] != COLOR_BLACK &&
|
||||
video__hires_even[e-1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e+1] == COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] =
|
||||
video__hires_even[e-1];
|
||||
|
||||
else if (
|
||||
video__hires_even[e-1] != COLOR_BLACK &&
|
||||
video__hires_even[e+1] != COLOR_BLACK &&
|
||||
video__hires_even[e-1] == COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] =
|
||||
video__hires_even[e+1];
|
||||
|
||||
else if (
|
||||
video__hires_even[e-1] == COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e+1] == COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] = (value & 0x80)
|
||||
? COLOR_LIGHT_BLUE : COLOR_LIGHT_PURPLE;
|
||||
|
||||
}
|
||||
if (video__hires_odd[e] == COLOR_BLACK) {
|
||||
if (video__hires_odd[e-1] != COLOR_BLACK &&
|
||||
video__hires_odd[e+1] != COLOR_BLACK &&
|
||||
video__hires_odd[e-1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e-1];
|
||||
|
||||
else if (
|
||||
video__hires_odd[e-1] != COLOR_BLACK &&
|
||||
video__hires_odd[e+1] != COLOR_BLACK &&
|
||||
video__hires_odd[e-1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e+1] == COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e-1];
|
||||
|
||||
else if (
|
||||
video__hires_odd[e-1] != COLOR_BLACK &&
|
||||
video__hires_odd[e+1] != COLOR_BLACK &&
|
||||
video__hires_odd[e-1] == COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e+1];
|
||||
|
||||
else if (
|
||||
video__hires_odd[e-1] == COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e+1] == COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] = (value & 0x80)
|
||||
? COLOR_LIGHT_RED : COLOR_LIGHT_GREEN;
|
||||
}
|
||||
}
|
||||
|
||||
for (b = 0, e = value * 8; b <= 6; b += 2, e += 2) {
|
||||
if (video__hires_even[ e ] == COLOR_BLACK) {
|
||||
if (b > 0 && b < 6) {
|
||||
if (video__hires_even[e-1] != COLOR_BLACK &&
|
||||
video__hires_even[e+1] != COLOR_BLACK &&
|
||||
video__hires_even[e-1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] =
|
||||
video__hires_even[e-1];
|
||||
|
||||
else if (
|
||||
video__hires_even[e-1] != COLOR_BLACK &&
|
||||
video__hires_even[e+1] != COLOR_BLACK &&
|
||||
video__hires_even[e-1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e+1] == COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] =
|
||||
video__hires_even[e-1];
|
||||
|
||||
else if (
|
||||
video__hires_even[e-1] != COLOR_BLACK &&
|
||||
video__hires_even[e+1] != COLOR_BLACK &&
|
||||
video__hires_even[e-1] == COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] =
|
||||
video__hires_even[e+1];
|
||||
|
||||
else if (
|
||||
video__hires_even[e-1] == COLOR_LIGHT_WHITE &&
|
||||
video__hires_even[e+1] == COLOR_LIGHT_WHITE)
|
||||
video__hires_even[e] = (value & 0x80)
|
||||
? COLOR_LIGHT_RED : COLOR_LIGHT_GREEN;
|
||||
}
|
||||
}
|
||||
|
||||
if (video__hires_odd[e] == COLOR_BLACK) {
|
||||
if (b > 0 && b < 6) {
|
||||
if (video__hires_odd[e-1] != COLOR_BLACK &&
|
||||
video__hires_odd[e+1] != COLOR_BLACK &&
|
||||
video__hires_odd[e-1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e-1];
|
||||
|
||||
else if (
|
||||
video__hires_odd[e-1] != COLOR_BLACK &&
|
||||
video__hires_odd[e+1] != COLOR_BLACK &&
|
||||
video__hires_odd[e-1] != COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e+1] == COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e-1];
|
||||
|
||||
else if (
|
||||
video__hires_odd[e-1] != COLOR_BLACK &&
|
||||
video__hires_odd[e+1] != COLOR_BLACK &&
|
||||
video__hires_odd[e-1] == COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e+1] != COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] =
|
||||
video__hires_odd[e+1];
|
||||
|
||||
else if (
|
||||
video__hires_odd[e-1] == COLOR_LIGHT_WHITE &&
|
||||
video__hires_odd[e+1] == COLOR_LIGHT_WHITE)
|
||||
video__hires_odd[e] = (value & 0x80)
|
||||
? COLOR_LIGHT_BLUE : COLOR_LIGHT_PURPLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef _640x400
|
||||
/* *2 for 640x400 */
|
||||
for (b=0, e=0; b<4096; b++, e++) {
|
||||
video__wider_hires_even[b] = video__hires_even[e];
|
||||
video__wider_hires_odd[b] = video__hires_odd[e];
|
||||
b++;
|
||||
video__wider_hires_even[b] = video__hires_even[e];
|
||||
video__wider_hires_odd[b] = video__hires_odd[e];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
c_initialize_row_col_tables()
|
||||
------------------------------------------------------------------------- */
|
||||
static void c_initialize_row_col_tables(void)
|
||||
{
|
||||
int x, y, off, i;
|
||||
|
||||
/* hires page offsets. initialize to invalid values. */
|
||||
for (i = 0; i < 8192; i++) {
|
||||
(long)(video__screen_addresses[i]) = -1;
|
||||
}
|
||||
|
||||
for (y = 0; y < 24; y++) {
|
||||
for (off = 0; off < 8; off++) {
|
||||
for (x = 0; x < 40; x++) {
|
||||
#ifdef _640x400
|
||||
video__screen_addresses[video__line_offset[y] + 0x400*off + x ] =
|
||||
(y*16 + 2*off/* + 8*/) * SCANWIDTH + x*14 + 4;
|
||||
#else
|
||||
video__screen_addresses[video__line_offset[y] + 0x400*off + x ] =
|
||||
(y*8 + off + 4) * 320 + x*7 + 20;
|
||||
#endif
|
||||
video__columns[video__line_offset[y] + 0x400*off + x] =
|
||||
(unsigned char)x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void c_initialize_tables_video(void) {
|
||||
int x, y, i;
|
||||
|
||||
/* initialize text/lores & hires graphics */
|
||||
for (y = 0; y < 24; y++) { /* 24 rows */
|
||||
for (x = 0; x < 40; x++) /* 40 cols */
|
||||
{
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
/* //e mode: text/lores page 0 */
|
||||
cpu65_vmem[ video__line_offset[ y ] + x + 0x400].w =
|
||||
(y < 20) ? video__write_2e_text0 :
|
||||
video__write_2e_text0_mixed;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* ][+ modes: text/lores page 0 */
|
||||
cpu65_vmem[ video__line_offset[ y ] + x + 0x400].w =
|
||||
(y < 20) ? video__write_text0 :
|
||||
video__write_text0_mixed;
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[ video__line_offset[ y ] + x + 0x800].w =
|
||||
(y < 20) ? video__write_2e_text1 :
|
||||
video__write_2e_text1_mixed;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* ][+ modes: text/lores page 1 in main memory */
|
||||
cpu65_vmem[ video__line_offset[ y ] + x + 0x800].w =
|
||||
(y < 20) ? video__write_text1 :
|
||||
video__write_text1_mixed;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
/* //e mode: hires/double hires page 0 */
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[ 0x2000 + video__line_offset[ y ]
|
||||
+ 0x400 * i + x ].w =
|
||||
(y < 20) ? ((x & 1) ? video__write_2e_odd0 :
|
||||
video__write_2e_even0)
|
||||
: ((x & 1) ? video__write_2e_odd0_mixed :
|
||||
video__write_2e_even0_mixed);
|
||||
}
|
||||
|
||||
/* ][+ modes: hires page 0 */
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cpu65_vmem[ 0x2000 + video__line_offset[ y ]
|
||||
+ 0x400 * i + x ].w =
|
||||
(y < 20) ? ((x & 1) ? video__write_odd0 :
|
||||
video__write_even0)
|
||||
: ((x & 1) ? video__write_odd0_mixed :
|
||||
video__write_even0_mixed);
|
||||
}
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
if (apple_mode == IIE_MODE) {
|
||||
cpu65_vmem[ 0x4000 + video__line_offset[ y ]
|
||||
+ 0x400 * i + x ].w =
|
||||
(y < 20) ? ((x & 1) ? video__write_2e_odd1 :
|
||||
video__write_2e_even1)
|
||||
: ((x & 1) ? video__write_2e_odd1_mixed :
|
||||
video__write_2e_even1_mixed);
|
||||
}
|
||||
|
||||
/* ][+ modes: hires page 1 */
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cpu65_vmem[ 0x4000 + video__line_offset[ y ]
|
||||
+ 0x400 * i + x ].w =
|
||||
(y < 20) ? ((x & 1) ? video__write_odd1 :
|
||||
video__write_even1)
|
||||
: ((x & 1) ? video__write_odd1_mixed :
|
||||
video__write_even1_mixed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void video_set(int flags)
|
||||
{
|
||||
if (color_mode == COLOR)
|
||||
video__strictcolors = 1; /* strict colors */
|
||||
else if (color_mode == INTERP)
|
||||
video__strictcolors = 2; /* strict interpolation */
|
||||
else
|
||||
video__strictcolors = 0; /* lazy coloration */
|
||||
|
||||
c_initialize_hires_values(); /* precalculate hires values */
|
||||
c_initialize_row_col_tables(); /* precalculate hires offsets */
|
||||
c_initialize_tables_video(); /* memory jump tables for video */
|
||||
|
||||
#ifdef APPLE_IIE
|
||||
c_initialize_dhires_values(); /* set up dhires colors */
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_loadfont_int(int first, int quantity, const unsigned char *data)
|
||||
{
|
||||
int i,j;
|
||||
unsigned char x;
|
||||
int y;
|
||||
|
||||
i = quantity * 8;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
j = 8;
|
||||
x = data[i];
|
||||
while (j--)
|
||||
{
|
||||
|
||||
#ifdef _640x400
|
||||
y = (first << 7) + (i << 4) + (j << 1);
|
||||
if (x & 128)
|
||||
{
|
||||
video__wider_int_font[0][y] =
|
||||
video__wider_int_font[0][y+1] =
|
||||
video__wider_int_font[1][y] =
|
||||
video__wider_int_font[1][y+1] = COLOR_LIGHT_GREEN;
|
||||
video__wider_int_font[2][y] =
|
||||
video__wider_int_font[2][y+1] = COLOR_LIGHT_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
video__wider_int_font[0][y] =
|
||||
video__wider_int_font[0][y+1] =
|
||||
video__wider_int_font[2][y] =
|
||||
video__wider_int_font[2][y+1] = COLOR_BLACK;
|
||||
video__wider_int_font[1][y] =
|
||||
video__wider_int_font[1][y+1] = COLOR_MEDIUM_BLUE;
|
||||
}
|
||||
#else
|
||||
y = (first << 6) + (i << 3) + j;
|
||||
if (x & 128)
|
||||
{
|
||||
video__int_font[0][y] =
|
||||
video__int_font[1][y] = COLOR_LIGHT_GREEN;
|
||||
video__int_font[2][y] = COLOR_LIGHT_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
video__int_font[0][y] =
|
||||
video__int_font[2][y] = COLOR_BLACK;
|
||||
video__int_font[1][y] = COLOR_MEDIUM_BLUE;
|
||||
}
|
||||
#endif /* _640x400 */
|
||||
x <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Should probably move this to assembly... */
|
||||
|
||||
static void c_interface_print_char40_line(
|
||||
unsigned char **d, unsigned char **s)
|
||||
{
|
||||
#ifdef _640x400
|
||||
*((unsigned int *)(*d)) = *((unsigned int *)(*s));/*32bits*/
|
||||
*d += 4, *s += 4;
|
||||
*((unsigned int *)(*d)) = *((unsigned int *)(*s));/*32bits*/
|
||||
*d += 4, *s += 4;
|
||||
*((unsigned int *)(*d)) = *((unsigned int *)(*s));/*32bits*/
|
||||
*d += 4, *s += 4;
|
||||
*((unsigned short *)(*d)) = *((unsigned short *)(*s));/*16bits*/
|
||||
*d += SCANSTEP, *s -= 12;
|
||||
*((unsigned int *)(*d)) = *((unsigned int *)(*s));/*32bits*/
|
||||
*d += 4, *s += 4;
|
||||
*((unsigned int *)(*d)) = *((unsigned int *)(*s));/*32bits*/
|
||||
*d += 4, *s += 4;
|
||||
*((unsigned int *)(*d)) = *((unsigned int *)(*s));/*32bits*/
|
||||
*d += 4, *s += 4;
|
||||
*((unsigned short *)(*d)) = *((unsigned short *)(*s));/*16bits*/
|
||||
*d += SCANSTEP, *s += 4;
|
||||
#else
|
||||
*((unsigned int *)(*d)) = *((unsigned int *)(*s));/*32bits*/
|
||||
*d += 4, *s += 4;
|
||||
*((unsigned short *)(*d)) = *((unsigned short *)(*s));/*16bits*/
|
||||
*d += 2, *s += 2;
|
||||
*((unsigned char *)(*d)) = *((unsigned char *)(*s));/*8bits*/
|
||||
*d += SCANSTEP, *s += 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_plotchar( int x, int y, int scheme, unsigned char c )
|
||||
{
|
||||
int off;
|
||||
unsigned char *d;
|
||||
unsigned char *s;
|
||||
|
||||
#ifdef _640x400
|
||||
off = y * SCANWIDTH * 16 + x * 14 + 4;
|
||||
s = video__wider_int_font[scheme] + c * 128;
|
||||
#else
|
||||
off = y * 320 * 8 + x * 7 + 1300;
|
||||
s = video__int_font[scheme] + c * 64;
|
||||
#endif
|
||||
d = video__fb1 + off;
|
||||
|
||||
c_interface_print_char40_line(&d,&s);
|
||||
c_interface_print_char40_line(&d,&s);
|
||||
c_interface_print_char40_line(&d,&s);
|
||||
c_interface_print_char40_line(&d,&s);
|
||||
c_interface_print_char40_line(&d,&s);
|
||||
c_interface_print_char40_line(&d,&s);
|
||||
c_interface_print_char40_line(&d,&s);
|
||||
c_interface_print_char40_line(&d,&s);
|
||||
}
|
851
src/xvideo.c
Normal file
851
src/xvideo.c
Normal file
@ -0,0 +1,851 @@
|
||||
/*
|
||||
* Apple // emulator for Linux: X-Windows graphics support
|
||||
*
|
||||
* Copyright 1994 Alexander Jean-Claude Bottema
|
||||
* Copyright 1995 Stephen Lee
|
||||
* Copyright 1997, 1998 Aaron Culliney
|
||||
* Copyright 1998, 1999, 2000 Michael Deutschmann
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/extensions/XShm.h>/* MITSHM! */
|
||||
|
||||
|
||||
#include "video.h"
|
||||
#include "misc.h"
|
||||
#include "keys.h"
|
||||
|
||||
/* copied from svideo.c (didn't bother to rename!) */
|
||||
static unsigned char *svga_GM;
|
||||
static unsigned char vga_mem_page_0[SCANWIDTH*SCANHEIGHT]; /* page0 framebuffer */
|
||||
static unsigned char vga_mem_page_1[SCANWIDTH*SCANHEIGHT]; /* page1 framebuffer */
|
||||
|
||||
static Display *display;
|
||||
static Window win;
|
||||
static GC gc;
|
||||
static unsigned int width, height; /* window size */
|
||||
|
||||
static int screen_num;
|
||||
static Visual* visual;
|
||||
static XVisualInfo visualinfo;
|
||||
static XColor colors[256];
|
||||
XImage *image;
|
||||
static Colormap cmap;
|
||||
XEvent xevent;
|
||||
|
||||
int doShm = 1;/* assume true */
|
||||
XShmSegmentInfo xshminfo;
|
||||
int xshmeventtype;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
video_setpage(p): Switch to screen page p
|
||||
------------------------------------------------------------------------- */
|
||||
void video_setpage(int p)
|
||||
{
|
||||
if (p == video__current_page) return;
|
||||
|
||||
if (p)
|
||||
{
|
||||
memcpy(vga_mem_page_0,svga_GM,SCANWIDTH*SCANHEIGHT);
|
||||
memcpy(svga_GM,vga_mem_page_1,SCANWIDTH*SCANHEIGHT);
|
||||
video__current_page = 1;
|
||||
video__fb1 = vga_mem_page_0;
|
||||
video__fb2 = svga_GM;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(vga_mem_page_1,svga_GM,SCANWIDTH*SCANHEIGHT);
|
||||
memcpy(svga_GM,vga_mem_page_0,SCANWIDTH*SCANHEIGHT);
|
||||
video__current_page = 0;
|
||||
video__fb1 = svga_GM;
|
||||
video__fb2 = vga_mem_page_1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XShm code influenced from the DOOM source code.
|
||||
* This tries to find some shared memory to use. It checks for stale segments
|
||||
* (maybe due to an emulator crash) and tries to remove them or use them.
|
||||
*/
|
||||
static void getshm(int size) {
|
||||
int key = ('a'<<24) | ('p'<<16) | ('p'<<8) | 'l';
|
||||
struct shmid_ds shminfo;
|
||||
int id;
|
||||
int rc;
|
||||
int counter=5;
|
||||
|
||||
/* Try to allocate shared memory segment. Use stale segments if any are
|
||||
* found.
|
||||
*/
|
||||
do
|
||||
{
|
||||
id = shmget((key_t) key, 0, 0777);
|
||||
if (id != -1)
|
||||
{
|
||||
/* we got someone else's ID. check if it's stale. */
|
||||
printf("Found shared memory key=`%c%c%c%c', id=%d\n",
|
||||
(key & 0xff000000)>>24,
|
||||
(key & 0xff0000)>>16,
|
||||
(key & 0xff00)>>8,
|
||||
(key & 0xff),
|
||||
id
|
||||
);
|
||||
rc=shmctl(id, IPC_STAT, &shminfo); /* get stats */
|
||||
if (!rc) {
|
||||
/* someone's using the emulator */
|
||||
if (shminfo.shm_nattch) {
|
||||
printf( "User uid=%d, key=`%c%c%c%c' appears to be running "
|
||||
"the emulator.\n",
|
||||
shminfo.shm_perm.cuid,
|
||||
(key & 0xff000000)>>24,
|
||||
(key & 0xff0000)>>16,
|
||||
(key & 0xff00)>>8,
|
||||
(key & 0xff)
|
||||
);
|
||||
++key; /* increase the key count */
|
||||
}
|
||||
|
||||
/* found a stale ID. */
|
||||
else {
|
||||
/* it's my stale ID */
|
||||
if (getuid() == shminfo.shm_perm.cuid) {
|
||||
rc = shmctl(id, IPC_RMID, 0);
|
||||
if (!rc)
|
||||
printf("Was able to kill my old shared memory\n");
|
||||
else {
|
||||
perror("shmctl");
|
||||
printf("Was NOT able to kill my old shared memory\n");
|
||||
}
|
||||
|
||||
id = shmget((key_t)key, size, IPC_CREAT|0777);
|
||||
if (id == -1) {
|
||||
perror("shmget");
|
||||
printf("Could not get shared memory\n");
|
||||
}
|
||||
|
||||
rc=shmctl(id, IPC_STAT, &shminfo);
|
||||
if (rc) {
|
||||
perror("shmctl");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
/* not my ID, but maybe we can use it */
|
||||
if (size == shminfo.shm_segsz) {
|
||||
printf( "Will use stale shared memory of uid=%d\n",
|
||||
shminfo.shm_perm.cuid);
|
||||
break;
|
||||
}
|
||||
/* not my ID, and we can't use it */
|
||||
else {
|
||||
printf( "Can't use stale shared memory belonging to uid=%d, "
|
||||
"key=`%c%c%c%c', id=%d\n",
|
||||
shminfo.shm_perm.cuid,
|
||||
(key & 0xff000000)>>24,
|
||||
(key & 0xff0000)>>16,
|
||||
(key & 0xff00)>>8,
|
||||
(key & 0xff),
|
||||
id
|
||||
);
|
||||
++key;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* oops. what to do now? */
|
||||
perror("shmctl");
|
||||
printf( "Could not get stats on key=`%c%c%c%c', id=%d\n",
|
||||
(key & 0xff000000)>>24,
|
||||
(key & 0xff0000)>>16,
|
||||
(key & 0xff00)>>8,
|
||||
(key & 0xff),
|
||||
id
|
||||
);
|
||||
++key;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no stale ID's */
|
||||
id = shmget((key_t)key, size, IPC_CREAT|0777);
|
||||
if (id == -1) {
|
||||
perror("shmget");
|
||||
printf("Could not get shared memory\n");
|
||||
++key;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (--counter);
|
||||
|
||||
if (!counter)
|
||||
{
|
||||
printf( "System has too many stale/used "
|
||||
"shared memory segments!\n");
|
||||
}
|
||||
|
||||
xshminfo.shmid = id;
|
||||
|
||||
/* attach to the shared memory segment */
|
||||
image->data = xshminfo.shmaddr = shmat(id, 0, 0);
|
||||
|
||||
if (image->data == -1) {
|
||||
perror("shmat");
|
||||
printf("Could not attach to shared memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf( "Using shared memory key=`%c%c%c%c', id=%d, addr=0x%x\n",
|
||||
(key & 0xff000000)>>24,
|
||||
(key & 0xff0000)>>16,
|
||||
(key & 0xff00)>>8,
|
||||
(key & 0xff),
|
||||
id,
|
||||
(int) (image->data));
|
||||
}
|
||||
|
||||
|
||||
static void c_initialize_colors() {
|
||||
static unsigned char col2[ 3 ] = {255,255,255};
|
||||
static int firstcall = 1;
|
||||
int c,i,j;
|
||||
|
||||
if (visualinfo.class == PseudoColor && visualinfo.depth == 8)
|
||||
{
|
||||
/* initialize the colormap */
|
||||
if (firstcall) {
|
||||
firstcall = 0;
|
||||
for (i=0; i<256; i++) {
|
||||
colors[i].pixel = i;
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
}
|
||||
}
|
||||
|
||||
/* align the palette for hires graphics */
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
c = (i & 1) ? col2[ j ] : 0;
|
||||
colors[ j+i*3+32].red = (c<<8) + c;
|
||||
c = (i & 2) ? col2[ j ] : 0;
|
||||
colors[ j+i*3+32].green = (c<<8) + c;
|
||||
c = (i & 4) ? col2[ j ] : 0;
|
||||
colors[ j+i*3+32].blue = (c<<8) + c;
|
||||
}
|
||||
}
|
||||
colors[ COLOR_FLASHING_BLACK].red = 0;
|
||||
colors[ COLOR_FLASHING_BLACK].green = 0;
|
||||
colors[ COLOR_FLASHING_BLACK].blue = 0;
|
||||
|
||||
colors[ COLOR_LIGHT_WHITE].red = (255<<8)|255;
|
||||
colors[ COLOR_LIGHT_WHITE].green = (255<<8)|255;
|
||||
colors[ COLOR_LIGHT_WHITE].blue = (255<<8)|255;
|
||||
|
||||
colors[ COLOR_FLASHING_WHITE].red = (255<<8)|255;
|
||||
colors[ COLOR_FLASHING_WHITE].green = (255<<8)|255;
|
||||
colors[ COLOR_FLASHING_WHITE].blue = (255<<8)|255;
|
||||
|
||||
colors[0x00].red = 0; colors[0x00].green = 0;
|
||||
colors[0x00].blue = 0; /* Black */
|
||||
colors[0x10].red = 195; colors[0x10].green = 0;
|
||||
colors[0x10].blue = 48; /* Magenta */
|
||||
colors[0x20].red = 0; colors[0x20].green = 0;
|
||||
colors[0x20].blue = 130; /* Dark Blue */
|
||||
colors[0x30].red = 166; colors[0x30].green = 52;
|
||||
colors[0x30].blue = 170; /* Purple */
|
||||
colors[0x40].red = 0; colors[0x40].green = 146;
|
||||
colors[0x40].blue = 0; /* Dark Green */
|
||||
colors[0x50].red = 105; colors[0x50].green = 105;
|
||||
colors[0x50].blue = 105; /* Dark Grey*/
|
||||
colors[0x60].red = 113; colors[0x60].green = 24;
|
||||
colors[0x60].blue = 255; /* Medium Blue */
|
||||
colors[0x70].red = 12; colors[0x70].green = 190;
|
||||
colors[0x70].blue = 235; /* Light Blue */
|
||||
colors[0x80].red = 150; colors[0x80].green = 85;
|
||||
colors[0x80].blue = 40; /* Brown */
|
||||
colors[0x90].red = 255; colors[0xa0].green = 24;
|
||||
colors[0x90].blue = 44; /* Orange */
|
||||
colors[0xa0].red = 150; colors[0xa0].green = 170;
|
||||
colors[0xa0].blue = 170; /* Light Gray */
|
||||
colors[0xb0].red = 255; colors[0xb0].green = 158;
|
||||
colors[0xb0].blue = 150; /* Pink */
|
||||
colors[0xc0].red = 0; colors[0xc0].green = 255;
|
||||
colors[0xc0].blue = 0; /* Green */
|
||||
colors[0xd0].red = 255; colors[0xd0].green = 255;
|
||||
colors[0xd0].blue = 0; /* Yellow */
|
||||
colors[0xe0].red = 130; colors[0xe0].green = 255;
|
||||
colors[0xe0].blue = 130; /* Aqua */
|
||||
colors[0xf0].red = 255; colors[0xf0].green = 255;
|
||||
colors[0xf0].blue = 255; /* White */
|
||||
|
||||
/* mirror of lores colors optimized for dhires code */
|
||||
colors[0x00].red = 0; colors[0x00].green = 0;
|
||||
colors[0x00].blue = 0; /* Black */
|
||||
colors[0x08].red = 195; colors[0x08].green = 0;
|
||||
colors[0x08].blue = 48; /* Magenta */
|
||||
colors[0x01].red = 0; colors[0x01].green = 0;
|
||||
colors[0x01].blue = 130; /* Dark Blue */
|
||||
colors[0x09].red = 166; colors[0x09].green = 52;
|
||||
colors[0x09].blue = 170; /* Purple */
|
||||
colors[0x02].red = 0; colors[0x02].green = 146;
|
||||
colors[0x02].blue = 0; /* Dark Green */
|
||||
colors[0x0a].red = 105; colors[0x0A].green = 105;
|
||||
colors[0x0a].blue = 105; /* Dark Grey*/
|
||||
colors[0x03].red = 113; colors[0x03].green = 24;
|
||||
colors[0x03].blue = 255; /* Medium Blue */
|
||||
colors[0x0b].red = 12; colors[0x0b].green = 190;
|
||||
colors[0x0b].blue = 235; /* Light Blue */
|
||||
colors[0x04].red = 150; colors[0x04].green = 85;
|
||||
colors[0x04].blue = 40; /* Brown */
|
||||
colors[0x0c].red = 255; colors[0x0c].green = 24;
|
||||
colors[0x0c].blue = 44; /* Orange */
|
||||
colors[0x05].red = 150; colors[0x05].green = 170;
|
||||
colors[0x05].blue = 170; /* Light Gray */
|
||||
colors[0x0d].red = 255; colors[0x0d].green = 158;
|
||||
colors[0x0d].blue = 150; /* Pink */
|
||||
colors[0x06].red = 0; colors[0x06].green = 255;
|
||||
colors[0x06].blue = 0; /* Green */
|
||||
colors[0x0e].red = 255; colors[0x0e].green = 255;
|
||||
colors[0x0e].blue = 0; /* Yellow */
|
||||
colors[0x07].red = 130; colors[0x07].green = 255;
|
||||
colors[0x07].blue = 130; /* Aqua */
|
||||
colors[0x0f].red = 255; colors[0x0f].green = 255;
|
||||
colors[0x0f].blue = 255; /* White */
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
colors[i].red = (colors[i].red<<8) | colors[i].red;
|
||||
colors[i].green = (colors[i].green<<8) | colors[i].green;
|
||||
colors[i].blue = (colors[i].blue<<8) | colors[i].blue;
|
||||
|
||||
colors[i<<4].red = (colors[i<<4].red<<8) | colors[i<<4].red;
|
||||
colors[i<<4].green = (colors[i<<4].green<<8) | colors[i<<4].green;
|
||||
colors[i<<4].blue = (colors[i<<4].blue<<8) | colors[i<<4].blue;
|
||||
}
|
||||
// store the colors to the current colormap
|
||||
XStoreColors(display, cmap, colors, 256);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* HACK: this is incredibly broken.
|
||||
* Map the X keysyms back into scancodes so the routines in keys.c can deal
|
||||
* with it. We do this to be compatible with what the SVGAlib version does.
|
||||
*/
|
||||
static int keysym_to_scancode(void) {
|
||||
static int rc = 0xFF;
|
||||
|
||||
switch(rc = XKeycodeToKeysym(display, xevent.xkey.keycode, 0))
|
||||
{
|
||||
case XK_F1:
|
||||
rc = 59; break;
|
||||
case XK_F2:
|
||||
rc = 60; break;
|
||||
case XK_F3:
|
||||
rc = 61; break;
|
||||
case XK_F4:
|
||||
rc = 62; break;
|
||||
case XK_F5:
|
||||
rc = 63; break;
|
||||
case XK_F6:
|
||||
rc = 64; break;
|
||||
case XK_F7:
|
||||
rc = 65; break;
|
||||
case XK_F8:
|
||||
rc = 66; break;
|
||||
case XK_F9:
|
||||
rc = 67; break;
|
||||
case XK_F10:
|
||||
rc = 68; break;
|
||||
case XK_Left:
|
||||
rc = 105; break;
|
||||
case XK_Right:
|
||||
rc = 106; break;
|
||||
case XK_Down:
|
||||
rc = 108; break;
|
||||
case XK_Up:
|
||||
rc = 103; break;
|
||||
case XK_Escape:
|
||||
rc = 1; break;
|
||||
case XK_Return:
|
||||
rc = 28; break;
|
||||
case XK_Tab:
|
||||
rc = 15; break;
|
||||
case XK_Shift_L:
|
||||
rc = SCODE_L_SHIFT; break;
|
||||
case XK_Shift_R:
|
||||
rc = SCODE_R_SHIFT; break;
|
||||
case XK_Control_L:
|
||||
rc = SCODE_L_CTRL; break;
|
||||
case XK_Control_R:
|
||||
rc = SCODE_R_CTRL; break;
|
||||
case XK_Caps_Lock:
|
||||
rc = SCODE_CAPS; break;
|
||||
case XK_BackSpace:
|
||||
rc = 14; break;
|
||||
case XK_Insert:
|
||||
rc = 110; break;
|
||||
case XK_Pause:
|
||||
rc = 119; break;
|
||||
case XK_Break:
|
||||
/* Pause and Break are the same key, but have different
|
||||
* scancodes (on PC keyboards). Ctrl makes the difference.
|
||||
*
|
||||
* We assume the X server is passing along the distinction to us,
|
||||
* rather than making us check Ctrl manually.
|
||||
*/
|
||||
rc = 101; break;
|
||||
case XK_Print:
|
||||
rc = 99; break;
|
||||
case XK_Delete:
|
||||
rc = 111; break;
|
||||
case XK_End:
|
||||
rc = 107; break;
|
||||
case XK_Home:
|
||||
rc = 102; break;
|
||||
case XK_Page_Down:
|
||||
rc = 109; break;
|
||||
case XK_Page_Up:
|
||||
rc = 104; break;
|
||||
|
||||
// keypad joystick movement
|
||||
case XK_KP_5:
|
||||
case XK_KP_Begin:
|
||||
rc = SCODE_J_C; break;
|
||||
case XK_KP_4:
|
||||
case XK_KP_Left:
|
||||
rc = SCODE_J_L; break;
|
||||
case XK_KP_8:
|
||||
case XK_KP_Up:
|
||||
rc = SCODE_J_U; break;
|
||||
case XK_KP_6:
|
||||
case XK_KP_Right:
|
||||
rc = SCODE_J_R; break;
|
||||
case XK_KP_2:
|
||||
case XK_KP_Down:
|
||||
rc = SCODE_J_D; break;
|
||||
|
||||
case XK_Alt_L:
|
||||
rc = 56; break;
|
||||
case XK_Alt_R:
|
||||
rc = 100; break;
|
||||
|
||||
default:
|
||||
if ((rc >= XK_space) && (rc <= XK_asciitilde))
|
||||
rc = xevent.xkey.keycode - 8;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc & 0xFF;/* normalize */
|
||||
}
|
||||
|
||||
static void post_image() {
|
||||
if (doShm) {
|
||||
if (!XShmPutImage(
|
||||
display,
|
||||
win,
|
||||
gc,
|
||||
image,
|
||||
0, 0,
|
||||
0, 0,
|
||||
SCANWIDTH, SCANHEIGHT,
|
||||
True))
|
||||
fprintf(stderr, "XShmPutImage() failed\n");
|
||||
} else {
|
||||
if (XPutImage(
|
||||
display,
|
||||
win,
|
||||
gc,
|
||||
image,
|
||||
0, 0,
|
||||
0, 0,
|
||||
SCANWIDTH, SCANHEIGHT
|
||||
))
|
||||
fprintf(stderr, "XPutImage() failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void c_flash_cursor(int on) {
|
||||
// flash only if it's text or mixed modes.
|
||||
if (softswitches & (SS_TEXT|SS_MIXED)) {
|
||||
if (!on) {
|
||||
colors[ COLOR_FLASHING_BLACK].red = 0;
|
||||
colors[ COLOR_FLASHING_BLACK].green = 0;
|
||||
colors[ COLOR_FLASHING_BLACK].blue = 0;
|
||||
|
||||
colors[ COLOR_FLASHING_WHITE].red = 0xffff;
|
||||
colors[ COLOR_FLASHING_WHITE].green = 0xffff;
|
||||
colors[ COLOR_FLASHING_WHITE].blue = 0xffff;
|
||||
} else {
|
||||
colors[ COLOR_FLASHING_WHITE].red = 0;
|
||||
colors[ COLOR_FLASHING_WHITE].green = 0;
|
||||
colors[ COLOR_FLASHING_WHITE].blue = 0;
|
||||
|
||||
colors[ COLOR_FLASHING_BLACK].red = 0xffff;
|
||||
colors[ COLOR_FLASHING_BLACK].green = 0xffff;
|
||||
colors[ COLOR_FLASHING_BLACK].blue = 0xffff;
|
||||
}
|
||||
|
||||
// store the colors to the current colormap
|
||||
XStoreColors(display, cmap, colors, 256);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: blocking not implemented... */
|
||||
void video_sync(int block) {
|
||||
static int flash_count = 0;
|
||||
// post the image and loop waiting for it to finish and
|
||||
// also process other input events
|
||||
post_image();
|
||||
LOOP:
|
||||
if (doShm)
|
||||
XNextEvent(
|
||||
display,
|
||||
&xevent);
|
||||
else if (!XCheckMaskEvent(
|
||||
display,
|
||||
KeyPressMask|KeyReleaseMask,
|
||||
&xevent))
|
||||
goto POLL_FINISHED;
|
||||
switch (xevent.type) {
|
||||
case KeyPress:
|
||||
c_read_raw_key(keysym_to_scancode(), 1);
|
||||
break;
|
||||
case KeyRelease:
|
||||
c_read_raw_key(keysym_to_scancode(), 0);
|
||||
break;
|
||||
default:
|
||||
if (xevent.type == xshmeventtype)
|
||||
goto POLL_FINISHED;
|
||||
break;
|
||||
}
|
||||
goto LOOP;
|
||||
|
||||
POLL_FINISHED:
|
||||
|
||||
switch (++flash_count)
|
||||
{
|
||||
case 6:
|
||||
c_flash_cursor(1);
|
||||
break;
|
||||
case 12:
|
||||
c_flash_cursor(0);
|
||||
flash_count = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Cursor hidecursor() {
|
||||
Pixmap cursormask;
|
||||
XGCValues xgc;
|
||||
XColor dummycolour;
|
||||
Cursor cursor;
|
||||
|
||||
cursormask = XCreatePixmap(display, win, 1, 1, 1/*depth*/);
|
||||
xgc.function = GXclear;
|
||||
gc = XCreateGC(display, cursormask, GCFunction, &xgc);
|
||||
XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
|
||||
dummycolour.pixel = 0;
|
||||
dummycolour.red = 0;
|
||||
dummycolour.flags = 04;
|
||||
cursor = XCreatePixmapCursor(display, cursormask, cursormask,
|
||||
&dummycolour,&dummycolour, 0,0);
|
||||
XFreePixmap(display,cursormask);
|
||||
XFreeGC(display,gc);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static void parseArgs() {
|
||||
int i;
|
||||
for (i=0; i<argc; i++) {
|
||||
if (strstr(argv[i], "-noshm"))
|
||||
doShm=0;
|
||||
}
|
||||
}
|
||||
|
||||
void video_init() {
|
||||
XSetWindowAttributes attribs;
|
||||
unsigned long attribmask;
|
||||
int x, y; /* window position */
|
||||
int drawingok;
|
||||
unsigned int display_width, display_height;
|
||||
XGCValues xgcvalues;
|
||||
int valuemask;
|
||||
char *window_name = "Apple ][";
|
||||
char *icon_name = window_name;
|
||||
XSizeHints *size_hints;
|
||||
XWMHints *wm_hints;
|
||||
XClassHint *class_hints;
|
||||
XTextProperty windowName, iconName;
|
||||
GC gc;
|
||||
char *progname;/* name this program was invoked by */
|
||||
char *displayname = NULL;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
/* give up root privileges. equivalent of vga_init() */
|
||||
setegid(getgid());
|
||||
seteuid(getuid());
|
||||
|
||||
parseArgs();
|
||||
|
||||
if (!(size_hints = XAllocSizeHints())) {
|
||||
fprintf(stderr, "cannot allocate memory for SizeHints\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!(wm_hints = XAllocWMHints())) {
|
||||
fprintf(stderr, "cannot allocate memory for WMHints\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!(class_hints = XAllocClassHint())) {
|
||||
fprintf(stderr, "cannot allocate memory for ClassHints\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* connect to X server */
|
||||
if ( (display=XOpenDisplay(displayname)) == NULL )
|
||||
{
|
||||
fprintf(stderr, "cannot connect to X server \"%s\"\n",
|
||||
XDisplayName(displayname));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get screen size from display structure macro */
|
||||
screen_num = DefaultScreen(display);
|
||||
if (!XMatchVisualInfo(display, screen_num, 8, PseudoColor, &visualinfo)) {
|
||||
fprintf(stderr,
|
||||
"Sorry bud, xapple2 only supports "
|
||||
"8bit PseudoColor displays.\n"
|
||||
"Maybe you can fix this!\n");
|
||||
exit(1);
|
||||
}
|
||||
visual = visualinfo.visual;
|
||||
display_width = DisplayWidth(display, screen_num);
|
||||
display_height = DisplayHeight(display, screen_num);
|
||||
|
||||
/* Note that in a real application, x and y would default to 0
|
||||
* but would be settable from the command line or resource database.
|
||||
*/
|
||||
x = y = 0;
|
||||
width = SCANWIDTH, height = SCANHEIGHT;
|
||||
|
||||
/* init MITSHM if we're doing it */
|
||||
if (doShm) {
|
||||
/* make sure we have it */
|
||||
doShm = XShmQueryExtension(display);
|
||||
|
||||
/* and it's a local connection */
|
||||
if (!displayname)
|
||||
displayname = getenv("DISPLAY");
|
||||
if (displayname)
|
||||
{
|
||||
if ((*displayname != ':') || !doShm) {
|
||||
printf("Cannot run MITSHM version of emulator "
|
||||
"with display \"%s\"\n"
|
||||
"Try something like \":0.0\". "
|
||||
"Reverting to regular X with no sound.\n",
|
||||
displayname);
|
||||
doShm = 0;
|
||||
soundAllowed=0;
|
||||
c_initialize_sound();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* and it's a local connection */
|
||||
if (!displayname)
|
||||
displayname = getenv("DISPLAY");
|
||||
if (displayname)
|
||||
{
|
||||
if (*displayname != ':') {
|
||||
printf("Sound not allowed for remote display \"%s\".\n",
|
||||
displayname);
|
||||
soundAllowed=0;
|
||||
c_initialize_sound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize colors */
|
||||
cmap = XCreateColormap(display, RootWindow(display, screen_num),
|
||||
visual, AllocAll);
|
||||
c_initialize_colors();
|
||||
attribs.colormap = cmap;
|
||||
attribs.border_pixel = 0;
|
||||
|
||||
/* select event types wanted */
|
||||
attribmask = CWEventMask | CWColormap | CWBorderPixel;/* HACK CWBorderPixel? */
|
||||
attribs.event_mask =
|
||||
KeyPressMask
|
||||
| KeyReleaseMask
|
||||
| ExposureMask;
|
||||
|
||||
/* create opaque window */
|
||||
win = XCreateWindow(display, RootWindow(display,screen_num),
|
||||
x, y, width, height,
|
||||
0,/* border_width */
|
||||
8,/* depth */
|
||||
InputOutput,
|
||||
visual,
|
||||
attribmask,
|
||||
&attribs);
|
||||
|
||||
|
||||
/* set size hints for window manager. We don't want the user to
|
||||
* dynamically allocate window size since we won't do the right
|
||||
* scaling in response. Whaddya want, performance or a snazzy gui?
|
||||
*/
|
||||
size_hints->flags = PPosition | PSize | PMinSize | PMaxSize;
|
||||
size_hints->min_width = width;
|
||||
size_hints->min_height = height;
|
||||
size_hints->max_width = width;
|
||||
size_hints->max_height = height;
|
||||
|
||||
/* store window_name and icon_name for niceity. */
|
||||
if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) {
|
||||
fprintf(stderr, "structure allocation for windowName failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) {
|
||||
fprintf(stderr, "structure allocation for iconName failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
wm_hints->initial_state = NormalState;
|
||||
wm_hints->input = True;
|
||||
wm_hints->flags = StateHint | IconPixmapHint/* | InputHint*/;
|
||||
|
||||
class_hints->res_name = progname;
|
||||
class_hints->res_class = "Apple2";
|
||||
|
||||
XSetWMProperties(display, win, &windowName, &iconName,
|
||||
argv, argc, size_hints, wm_hints,
|
||||
class_hints);
|
||||
|
||||
XDefineCursor(display, win, hidecursor(display, win));
|
||||
|
||||
/* create the GC */
|
||||
valuemask = GCGraphicsExposures;
|
||||
xgcvalues.graphics_exposures = False;
|
||||
gc = XCreateGC(
|
||||
display,
|
||||
win,
|
||||
valuemask,
|
||||
&xgcvalues);
|
||||
|
||||
/* display window */
|
||||
XMapWindow(display, win);
|
||||
|
||||
/* wait until it is OK to draw */
|
||||
drawingok = 0;
|
||||
while (!drawingok)
|
||||
{
|
||||
XNextEvent(display, &xevent);
|
||||
if ((xevent.type == Expose) && !xevent.xexpose.count)
|
||||
{
|
||||
drawingok = 1;
|
||||
}
|
||||
}
|
||||
|
||||
xshmeventtype = XShmGetEventBase(display) + ShmCompletion;
|
||||
|
||||
/* create the image */
|
||||
if (doShm) {
|
||||
image = XShmCreateImage(
|
||||
display,
|
||||
visual,
|
||||
8,
|
||||
ZPixmap,
|
||||
0,
|
||||
&xshminfo,
|
||||
SCANWIDTH,
|
||||
SCANHEIGHT);
|
||||
|
||||
if (!image) {
|
||||
fprintf(stderr, "XShmCreateImage failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Allocating shared memory %dx%d region\n",
|
||||
image->bytes_per_line, image->height);
|
||||
|
||||
getshm(image->bytes_per_line * image->height);
|
||||
|
||||
/* get the X server to attach to it */
|
||||
if (!XShmAttach(display, &xshminfo)) {
|
||||
fprintf(stderr, "XShmAttach() failed in InitGraphics()\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
char *data = malloc(SCANWIDTH*SCANHEIGHT*sizeof(unsigned char));
|
||||
if (!data) {
|
||||
fprintf(stderr, "no memory for image data!\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("Creating regular XImage\n");
|
||||
image = XCreateImage(
|
||||
display,
|
||||
visual,
|
||||
8,
|
||||
ZPixmap,
|
||||
0,
|
||||
data,
|
||||
SCANWIDTH,
|
||||
SCANHEIGHT,
|
||||
8/*bitmap_pad*/,
|
||||
SCANWIDTH/*bytes_per_line*/);
|
||||
|
||||
if (!image) {
|
||||
fprintf(stderr, "XCreateImage failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
svga_GM = video__fb1 = image->data;
|
||||
video__fb2 = vga_mem_page_1;
|
||||
|
||||
memset(video__fb1,0,SCANWIDTH*SCANHEIGHT);
|
||||
memset(video__fb2,0,SCANWIDTH*SCANHEIGHT);
|
||||
|
||||
}
|
||||
|
||||
void video_shutdown(void)
|
||||
{
|
||||
if (doShm) {
|
||||
// Detach from X server
|
||||
if (!XShmDetach(display, &xshminfo))
|
||||
fprintf(stderr,"XShmDetach() failed in video_shutdown()\n");
|
||||
|
||||
// Release shared memory.
|
||||
shmdt(xshminfo.shmaddr);
|
||||
shmctl(xshminfo.shmid, IPC_RMID, 0);
|
||||
|
||||
// Paranoia.
|
||||
image->data = NULL;
|
||||
} else {
|
||||
free(image->data);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user