mirror of
https://github.com/Oibaf66/fbzx-wii.git
synced 2024-11-28 02:54:15 +01:00
First release
This commit is contained in:
commit
de19c97eae
43
AMSTRAD
Normal file
43
AMSTRAD
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
Although Amstrad is the current propietary of the copyright of the original
|
||||||
|
ZX Spectrum ROMs, they have kindly given their permission for its
|
||||||
|
redistribution with Spectrum emulators.
|
||||||
|
|
||||||
|
These are the conditions put by Amstrad to use and distribute the ROM files,
|
||||||
|
extracted from
|
||||||
|
http://groups.google.com/group/comp.sys.amstrad.8bit/msg/c092cc4d4943131e
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
1) What exactly do you have to do to use Sinclair ROMs in an emulator, such
|
||||||
|
as acknowledgements etc?"
|
||||||
|
|
||||||
|
Amstrad are happy for emulator writers to include images of our copyrighted
|
||||||
|
code as long as the (c)opyright messages are not altered and we appreciate
|
||||||
|
it if the program/manual includes a note to the effect that "Amstrad have
|
||||||
|
kindly given their permission for the redistribution of their copyrighted
|
||||||
|
material but retain that copyright".
|
||||||
|
|
||||||
|
"2) Can you charge a shareware fee for an emulator that uses the Sinclair
|
||||||
|
ROMs?"
|
||||||
|
|
||||||
|
No. No one should be charging for the ROM code because (as a result of the
|
||||||
|
point above) there are loads of freely available images anyway. If I ever
|
||||||
|
thought someone was charging for the ROM images then I'd make them available
|
||||||
|
as a free download on the www.amstrad.com web site. Naturally I imagine that
|
||||||
|
some emulator writers want to charge a shareware fee for the code they have
|
||||||
|
written and we have absolutely no problem with that as long as they aren't,
|
||||||
|
in any sense, charging for the parts of the code that are (c)Amstrad and (c)
|
||||||
|
Sinclair.
|
||||||
|
|
||||||
|
"3) Can you modify the ROMs, for instance to enable tape loading and saving,
|
||||||
|
and if so what are the requirements?"
|
||||||
|
|
||||||
|
The ROM code is simply a tool to let the emulator writers make a program
|
||||||
|
that works as close to the original machine as possible. If they choose to
|
||||||
|
modify the behaviour in any way then that's entirely up to them (I guess you
|
||||||
|
could say that that is exactly what an emulator IS doing (ie modifying the
|
||||||
|
screen output and keyboard input to go via the PC bits)!!)
|
||||||
|
|
||||||
|
"4) Can you distribute modified ROMs?"
|
||||||
|
|
||||||
|
If you like (with that (c) proviso).
|
19
CAPABILITIES
Normal file
19
CAPABILITIES
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
WHAT EMULATES RIGHT IN FBZX?
|
||||||
|
|
||||||
|
-Screen timmings in 48K and 128K mode.
|
||||||
|
-Screen generation, so border efects and even attribute changing efects
|
||||||
|
should work fine.
|
||||||
|
-48K sound (included the low-pass filter efect of Tape out).
|
||||||
|
-128K sound (fully emulation of the AY-3-8912).
|
||||||
|
-Trash in the bus when reading from a non-existing port. This is right generated
|
||||||
|
(from the data being displayed in that moment) so games works right (like
|
||||||
|
SHORTCIRCUIT, that runs without flickering).
|
||||||
|
-Spectrum 48K Issue 2 and 3 efects in the EAR bit are correctly emulated.
|
||||||
|
-Priority of joystick over keyboard.
|
||||||
|
-Snow efect when I register points between 64 and 127.
|
||||||
|
-Emulation of Interface I and Microdrive (only one drive).
|
||||||
|
-Memory contention
|
||||||
|
-Emulates Spanish 128K from Investronica/Sinclair
|
||||||
|
-Allows to insert POKE values in memory (inmunity, infinite lives...)
|
||||||
|
-Can load and save SCR snapshots
|
||||||
|
-ULAPlus support
|
674
COPYING
Normal file
674
COPYING
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. 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
|
||||||
|
them 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 prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. 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.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey 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;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If 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 convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU 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 that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
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.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program 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, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU 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 Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
133
FAQ
Normal file
133
FAQ
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
FBZX CAN'T INITIALIZATE THE SDL LIBRARY.
|
||||||
|
|
||||||
|
Is possible that you don't have the '/dev/mouse' symlink, or maybe, that
|
||||||
|
symlink (or the device pointed by) has no access permissions for the user you
|
||||||
|
are using. Just try (as root):
|
||||||
|
|
||||||
|
|
||||||
|
FBZX SAYS THAT IS RUNNING WITHOUT SOUND, AND TO READ THE FAQ
|
||||||
|
|
||||||
|
Currently FBZX uses ALSA, OSS or PulseAudio to generate the sound, and that
|
||||||
|
means that there can be only one sound source at each time in the system. If
|
||||||
|
you have a MP3 playing, without the PULSEAUDIO daemon launched, FBZX won't be
|
||||||
|
able to get access to the sound.
|
||||||
|
|
||||||
|
|
||||||
|
WHAT SPEED DO I NEED TO USE FBZX?
|
||||||
|
|
||||||
|
I'm not sure what's exactly the minimum speed, but I used it in an AMD K6-II
|
||||||
|
runing at 450 MHz and it worked at fully speed. Now, with the new OSS sound
|
||||||
|
*seems* to work even better, so maybe you could use it with an smaller
|
||||||
|
computer.
|
||||||
|
|
||||||
|
|
||||||
|
FBZX CAN BE USED FROM X-WINDOWS?
|
||||||
|
|
||||||
|
Since FBZX uses the SDL library, it can be used both from console and from X,
|
||||||
|
but, of course, in X it will need more system resources due to the fact that it
|
||||||
|
needs to emulate an 8-bit screen. Of course this was problematic with 2003
|
||||||
|
computers, but current systems can run FBZX under X without problems.
|
||||||
|
|
||||||
|
If you use it from console, it is strongly reccomended to use a native
|
||||||
|
FrameBuffer driver, in order to allow FBZX to change the current video mode
|
||||||
|
(see next question).
|
||||||
|
|
||||||
|
You can use the -fb option to make FBZX work in fullscreen mode.
|
||||||
|
|
||||||
|
|
||||||
|
I'M USING VESAFB IN MY (16-24 bits) CONSOLE, BUT FBZX WORKS SLOW...
|
||||||
|
|
||||||
|
That's because SDL is emulating an 8-bit screen for FBZX. The solution is to
|
||||||
|
change it for a FrameBuffer specific for your graphic card. If there's no
|
||||||
|
native driver (or it doesn't work reliably), you can use the SuperVESAfb
|
||||||
|
driver. This is a VESA driver that allows to change the resolution on-the-fly.
|
||||||
|
You can find it in:
|
||||||
|
|
||||||
|
http://www.rastersoft.com/supervesafb.html
|
||||||
|
|
||||||
|
This driver is only for 2.4 kernels. 2.6 versions have a new VESAFB driver
|
||||||
|
capable of switching the resolution.
|
||||||
|
|
||||||
|
|
||||||
|
MY COMPUTER DOESN'T HAVE FUNCTION KEYS (F1, F2...). HOW CAN I GET ACCESS TO
|
||||||
|
THE MENUS?
|
||||||
|
|
||||||
|
Just press the TAB key and you will see the message "Function key mode on".
|
||||||
|
Now you can use the number keys (0-9) to emulate the functions keys (F10 is '0',
|
||||||
|
F1 is '1', and so on, F11 is 'o' and F12 is 'p').
|
||||||
|
|
||||||
|
|
||||||
|
THERE'S A DELAY IN THE SOUND. HOW CAN I ELIMINATE IT?
|
||||||
|
|
||||||
|
Unfortunately, you can't. I have to use at least two buffers of 4096 bytes each
|
||||||
|
one in order to have an stable sound, and this means, at 48000 samples/sec,
|
||||||
|
0'17 seconds, and that's a perceptible delay for the human ear (with lower
|
||||||
|
sample rates it would became even worse; to avoid it, at sample rates lower
|
||||||
|
than 24000 samples/sec I reduce the buffer to 2048 bytes).
|
||||||
|
|
||||||
|
|
||||||
|
THERE ARE SOME GLITCHES IN THE SOUND
|
||||||
|
|
||||||
|
Maybe your CPU is too slow to run FBZX at full speed. But you can see with top
|
||||||
|
the load of each program, and give less priority to the ones that uses more
|
||||||
|
CPU. I do this with aMule, and the glitches dissapears.
|
||||||
|
|
||||||
|
|
||||||
|
I TRIED TO LOAD A .TZX FILE, BUT THE EMULATOR SHOWS A MESSAGE THAT
|
||||||
|
TELLS: "Unsuported TZX. Contact FBZX autor". WHAT'S HAPPEN?
|
||||||
|
|
||||||
|
Just read the file README.TZX.
|
||||||
|
|
||||||
|
|
||||||
|
I CHOOSE A .TZX FILE AND TYPE LOAD "", BUT NOTHING HAPPENS.
|
||||||
|
|
||||||
|
Fast load is available only with TAP files. If you want to load a TZX file,
|
||||||
|
you must press F6 in order to play the tape.
|
||||||
|
|
||||||
|
|
||||||
|
I TRIED TO LOAD A .TAP FILE IN FAST MODE, BUT IT FAILS AND THE EMULATOR
|
||||||
|
SHOWS THE MESSAGE "Block with right flag not found". WHAT'S HAPPENNING?
|
||||||
|
|
||||||
|
Each Spectrum's tape block has a flag byte that identify each one. Flag 0 is
|
||||||
|
for headers, and flag FF is for data blocks. A programmer can define its own
|
||||||
|
flag bytes if he wants.
|
||||||
|
|
||||||
|
If the program loader wants to load a block with a flag XX, but there isn't a
|
||||||
|
block in the TAP file with that flag, the fast loader will stop and show that
|
||||||
|
message (and will return a "Tape error" to the program loader). If I don't do
|
||||||
|
this, the fast loader should be reading the tape again and again, trying to
|
||||||
|
find a block with that flag, and the emulator should hang up (not really hang,
|
||||||
|
but it wouldn't be able to respond to keystrokes, even to the ESC key).
|
||||||
|
|
||||||
|
|
||||||
|
I CREATED A NEW MDR FILE, BUT WHEN I TRY TO WRITE TO IT, OR DO A CAT 1,
|
||||||
|
IT DOESN'T WORK, AND I HAVE TO PRESS BREAK (SHIFT + SPACE) TO STOP THE
|
||||||
|
COMMAND.
|
||||||
|
|
||||||
|
When you create a MDR file, it is created "in blank", so you must format the
|
||||||
|
medium before using it. To do it, just use:
|
||||||
|
|
||||||
|
FORMAT "m";1;"name"
|
||||||
|
|
||||||
|
changing 'name' with the name you want to give to the cartridge.
|
||||||
|
|
||||||
|
You can format a cartridge too if you want to erase a MDR file.
|
||||||
|
|
||||||
|
|
||||||
|
THE SYSTEM RETURNS THE MESSAGE DRIVE 'WRITE' PROTECTED. WHAT CAN I DO TO
|
||||||
|
UNPROTECT IT?
|
||||||
|
|
||||||
|
Just press F7 and change the 'Write protection' status with F3. Remember that
|
||||||
|
the status is stored with the cartridge, so if you exit the emulator and load
|
||||||
|
a MDR file again, it will have the same status you left it.
|
||||||
|
|
||||||
|
|
||||||
|
WHERE CAN I FIND INFO ABOUT HOW TO USE THE INTERFACE I AND THE MICRODRIVES?
|
||||||
|
|
||||||
|
In:
|
||||||
|
|
||||||
|
http://www.madhippy.com/8-bit/sinclair/zxif1micro.html
|
||||||
|
|
||||||
|
you can find the HTML version of the original manual of the Interface I and
|
||||||
|
Microdrive. There's ALL what you shoul need to know to work with it.
|
||||||
|
|
32
INSTALL
Normal file
32
INSTALL
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
HOW TO INSTALL FBZX
|
||||||
|
|
||||||
|
If you want to install FBZX, you must compile your own version,
|
||||||
|
just typing as root:
|
||||||
|
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
Be sure you have the SDL, libasound2 and libpulse libraries (both runtime and
|
||||||
|
headers).
|
||||||
|
|
||||||
|
|
||||||
|
HOW TO RUN FBZX
|
||||||
|
|
||||||
|
Just type
|
||||||
|
|
||||||
|
fbzx
|
||||||
|
|
||||||
|
If you don't want sound (or you haven't a sound card), you can run it with
|
||||||
|
|
||||||
|
fbzx -nosound
|
||||||
|
|
||||||
|
To know all the other FBZX options, just type
|
||||||
|
|
||||||
|
fbzx -h
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
fbzx --help
|
||||||
|
|
||||||
|
and enjoy!
|
156
Makefile
Normal file
156
Makefile
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Clear the implicit built in rules
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITPPC)),)
|
||||||
|
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(DEVKITPPC)/wii_rules
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# TARGET is the name of the output
|
||||||
|
# BUILD is the directory where object files & intermediate files will be placed
|
||||||
|
# SOURCES is a list of directories containing source code
|
||||||
|
# INCLUDES is a list of directories containing extra header files
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
TARGET := fbzx
|
||||||
|
BUILD := build
|
||||||
|
SOURCES := src src/z80free
|
||||||
|
DATA :=
|
||||||
|
INCLUDES :=
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# options for code generation
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) -Wno-pointer-sign -DDEBUG
|
||||||
|
CXXFLAGS = $(CFLAGS)
|
||||||
|
|
||||||
|
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# any extra libraries we wish to link with the project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBS := -lSDL_mixer -lsmpeg -lvorbisidec -lSDL_image -lpng -ljpeg -lz -lSDL -lSDL_gfx -lfreetype -lfat -lwiiuse -lbte -logc -lm -lwiikeyboard
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
# include and lib
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBDIRS := $(PORTLIBS)
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# no real need to edit anything past this point unless you need to add additional
|
||||||
|
# rules for different file extensions
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
|
|
||||||
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||||
|
|
||||||
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# automatically build a list of object files for our project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
|
CFILES := $(filter-out z80free_tester.c, $(CFILES))
|
||||||
|
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
|
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
||||||
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(CPPFILES)),)
|
||||||
|
export LD := $(CC)
|
||||||
|
else
|
||||||
|
export LD := $(CXX)
|
||||||
|
endif
|
||||||
|
|
||||||
|
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||||
|
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||||
|
$(sFILES:.s=.o) $(SFILES:.S=.o)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# build a list of include paths
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
|
-I$(CURDIR)/$(BUILD) \
|
||||||
|
-I$(LIBOGC_INC)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# build a list of library paths
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
||||||
|
-L$(LIBOGC_LIB)
|
||||||
|
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
|
.PHONY: $(BUILD) clean
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(BUILD):
|
||||||
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
clean:
|
||||||
|
@echo clean ...
|
||||||
|
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol dist
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
dist: $(BUILD)
|
||||||
|
rm -fr $@
|
||||||
|
mkdir -p $@/apps/fbzx-wii
|
||||||
|
mkdir -p $@/fbzx-wii/fbzx
|
||||||
|
mkdir -p $@/fbzx-wii/spectrum-roms
|
||||||
|
mkdir -p $@/fbzx-wii/applications
|
||||||
|
mkdir -p $@/fbzx-wii/pixmaps
|
||||||
|
mkdir -p $@/fbzx-wii/doc/fbzx
|
||||||
|
cp fbzx.dol $@/apps/fbzx-wii/boot.dol
|
||||||
|
cp spectrum-roms/* $@/fbzx-wii/spectrum-roms
|
||||||
|
cp keymap.bmp $@/fbzx-wii/fbzx
|
||||||
|
cp fbzx.desktop $@/fbzx-wii/applications
|
||||||
|
cp fbzx.svg $@/fbzx-wii/pixmaps
|
||||||
|
cp AMSTRAD CAPABILITIES COPYING FAQ README README.TZX VERSIONS $@/fbzx-wii/doc/fbzx/
|
||||||
|
cd $@ && tar -czf ../fbzx-wii-bin.tar.gz *
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
run:
|
||||||
|
wiiload $(TARGET).dol
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
|
||||||
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(OUTPUT).dol: $(OUTPUT).elf
|
||||||
|
$(OUTPUT).elf: $(OFILES)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# This rule links in binary data with the .jpg extension
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.jpg.o : %.jpg
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(bin2o)
|
||||||
|
|
||||||
|
-include $(DEPENDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------
|
89
Makefile.ori
Normal file
89
Makefile.ori
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
ifdef PREFIX
|
||||||
|
PREFIX2=$(PREFIX)/usr
|
||||||
|
else
|
||||||
|
PREFIX2=/usr/local
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS += `pkg-config --cflags sdl libpulse-simple alsa` -O2 -Wno-pointer-sign -Wall -D D_SOUND_PULSE -D D_SOUND_ALSA -D D_SOUND_OSS
|
||||||
|
LDFLAGS += `pkg-config --libs sdl libpulse-simple alsa`
|
||||||
|
|
||||||
|
fbzx: computer.o Z80free.o Z80free_codes.o Z80free_codesCB.o Z80free_codesED.o Z80free_codesDD.o Z80free_codesFD.o Z80free_codesDDCB.o Z80free_codesFDCB.o emulator.o cargador.o characters.o menus.o sound.o tape.o spk_ay.o microdrive.o
|
||||||
|
|
||||||
|
$(CC) -o fbzx computer.o Z80free.o Z80free_codes.o Z80free_codesCB.o Z80free_codesED.o Z80free_codesDD.o Z80free_codesFD.o Z80free_codesDDCB.o Z80free_codesFDCB.o emulator.o cargador.o characters.o menus.o sound.o tape.o spk_ay.o microdrive.o $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm fbzx *.o *~
|
||||||
|
|
||||||
|
install:
|
||||||
|
rm -f $(PREFIX2)/bin/fbzx
|
||||||
|
cp fbzx $(PREFIX2)/bin
|
||||||
|
mkdir -p $(PREFIX2)/share/fbzx
|
||||||
|
mkdir -p $(PREFIX2)/share/spectrum-roms
|
||||||
|
mkdir -p $(PREFIX2)/share/applications
|
||||||
|
mkdir -p $(PREFIX2)/share/pixmaps
|
||||||
|
mkdir -p $(PREFIX2)/share/doc/fbzx
|
||||||
|
cp spectrum-roms/* $(PREFIX2)/share/spectrum-roms
|
||||||
|
cp keymap.bmp $(PREFIX2)/share/fbzx
|
||||||
|
cp fbzx.desktop $(PREFIX2)/share/applications
|
||||||
|
cp fbzx.svg $(PREFIX2)/share/pixmaps
|
||||||
|
cp AMSTRAD CAPABILITIES COPYING FAQ README README.TZX VERSIONS $(PREFIX2)/share/doc/fbzx/
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f $(PREFIX2)/bin/fbzx
|
||||||
|
rm -rf $(PREFIX2)/share/fbzx
|
||||||
|
rm -f $(PREFIX2)/share/applications/fbzx.desktop
|
||||||
|
rm -f $(PREFIX2)/share/pixmaps/fbzx.svg
|
||||||
|
rm -rf $(PREFIX2)/share/doc/fbzx
|
||||||
|
rm -rf $(PREFIX2)/share/spectrum-roms
|
||||||
|
|
||||||
|
spk_ay.o: spk_ay.c spk_ay.h emulator.h sound.h computer.h z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o spk_ay.o spk_ay.c
|
||||||
|
|
||||||
|
microdrive.o: microdrive.c microdrive.h z80free/Z80free.h computer.h emulator.h z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o microdrive.o microdrive.c
|
||||||
|
|
||||||
|
sound.o: sound.c sound.h computer.h emulator.h z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o sound.o sound.c
|
||||||
|
|
||||||
|
emulator.o: emulator.c z80free/Z80free.h computer.h emulator.h characters.h menus.h cargador.h sound.h tape.h microdrive.h
|
||||||
|
$(CC) $(CFLAGS) -c -o emulator.o emulator.c
|
||||||
|
|
||||||
|
computer.o: computer.c z80free/Z80free.h computer.h emulator.h characters.h menus.h cargador.h sound.h tape.h spk_ay.h microdrive.h
|
||||||
|
$(CC) $(CFLAGS) -c -o computer.o computer.c
|
||||||
|
|
||||||
|
tape.o: tape.c z80free/Z80free.h computer.h emulator.h menus.h tape.h computer.h
|
||||||
|
$(CC) $(CFLAGS) -c -o tape.o tape.c
|
||||||
|
|
||||||
|
cargador.o: cargador.c cargador.h computer.h emulator.h z80free/Z80free.h characters.h menus.h computer.h
|
||||||
|
$(CC) $(CFLAGS) -c -o cargador.o cargador.c
|
||||||
|
|
||||||
|
characters.o: characters.c characters.h emulator.h computer.h
|
||||||
|
$(CC) $(CFLAGS) -c -o characters.o characters.c
|
||||||
|
|
||||||
|
menus.o: menus.c menus.h characters.h computer.h emulator.h z80free/Z80free.h cargador.h tape.h
|
||||||
|
$(CC) $(CFLAGS) -c -o menus.o menus.c
|
||||||
|
|
||||||
|
Z80free.o: z80free/Z80free.c z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o Z80free.o z80free/Z80free.c
|
||||||
|
|
||||||
|
Z80free_codes.o: z80free/Z80free_codes.c z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o Z80free_codes.o z80free/Z80free_codes.c
|
||||||
|
|
||||||
|
Z80free_codesCB.o: z80free/Z80free_codesCB.c z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o Z80free_codesCB.o z80free/Z80free_codesCB.c
|
||||||
|
|
||||||
|
Z80free_codesED.o: z80free/Z80free_codesED.c z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o Z80free_codesED.o z80free/Z80free_codesED.c
|
||||||
|
|
||||||
|
Z80free_codesDD.o: z80free/Z80free_codesDD.c z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o Z80free_codesDD.o z80free/Z80free_codesDD.c
|
||||||
|
|
||||||
|
Z80free_codesFD.o: z80free/Z80free_codesFD.c z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o Z80free_codesFD.o z80free/Z80free_codesFD.c
|
||||||
|
|
||||||
|
Z80free_codesDDCB.o: z80free/Z80free_codesDDCB.c z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o Z80free_codesDDCB.o z80free/Z80free_codesDDCB.c
|
||||||
|
|
||||||
|
Z80free_codesFDCB.o: z80free/Z80free_codesFDCB.c z80free/Z80free.h
|
||||||
|
$(CC) $(CFLAGS) -c -o Z80free_codesFDCB.o z80free/Z80free_codesFDCB.c
|
||||||
|
|
22
PORTING
Normal file
22
PORTING
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
HOW TO PORT FBZX INTO OTHER O.S. AND ARQUITECTURES
|
||||||
|
|
||||||
|
FBZX uses the SDL library, so you must have it available in the
|
||||||
|
arquitecture/operating system where you want to port it. It's the only 'must
|
||||||
|
have'. Of course, is possible that you have to rewrite the Makefile, but that's
|
||||||
|
relatively easy (isn't it?).
|
||||||
|
|
||||||
|
The sound system is designed to be easily portable; currently it supports both
|
||||||
|
the OSS and ALSA arquitecture. In the file 'sound.c' are defined the three
|
||||||
|
functions needed to support it:
|
||||||
|
|
||||||
|
sound_init: initializates the sound system with the desired sound format,
|
||||||
|
speed, and so on, and fills the 'ordenador' struct with the parameters
|
||||||
|
needed to sincronize the emulation.
|
||||||
|
|
||||||
|
sound_play: plays the current sound buffer, and initializates
|
||||||
|
'ordenador.current_buffer' to the new buffer to be filled. It must not
|
||||||
|
return until the buffer has been played (this allows the sincronization).
|
||||||
|
|
||||||
|
sound_close: closes the sound device and frees all memory used.
|
||||||
|
|
||||||
|
That's all. Start to compile :)
|
223
README
Normal file
223
README
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
FBZX
|
||||||
|
A ZX Spectrum emulator for FrameBuffer
|
||||||
|
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
FBZX is distributed under the GPL license, version three or later, which means
|
||||||
|
that is distributed "as is", without warraty of any kind. To know more details,
|
||||||
|
read the file COPYING.
|
||||||
|
|
||||||
|
The old exception for the Z80 emulator has been removed because now FBZX uses
|
||||||
|
Z80FREE, a brand new, fully GPLv3, Z80 emulator. So finally FBZX is 100% free
|
||||||
|
software.
|
||||||
|
|
||||||
|
Amstrad have kindly given their permission for the redistribution of their
|
||||||
|
copyrighted material (the original Spectrum ROMs) but retain that copyright.
|
||||||
|
To know more details about how to distribute them, read the file AMSTRAD.
|
||||||
|
|
||||||
|
|
||||||
|
WHAT IS FBZX?
|
||||||
|
|
||||||
|
FBZX is a Sinclair ZX Spectrum emulator, designed to work in FrameBuffer under
|
||||||
|
Linux, but can work under Xwindows too, both in full screen mode and in a
|
||||||
|
window. It uses the SDL library, so it should be easily ported to other
|
||||||
|
architectures. Please, read the file PORTS to know more details about this.
|
||||||
|
|
||||||
|
FBZX is based in Z80FREE, which you can find into the folder z80free.
|
||||||
|
|
||||||
|
To work with FBZX you need:
|
||||||
|
|
||||||
|
-A FrameBuffer-capable graphic card (or compatible with X-windows)
|
||||||
|
-A Linux system with FrameBuffer configured (can use X too)
|
||||||
|
-Sound Card with ALSA or OSS drivers (optional)
|
||||||
|
|
||||||
|
In order to get the maximum performance, your FrameBuffer driver must allow to
|
||||||
|
change to 640x480 or 480x640 resolution in 8 bits. Only the old VESAFB driver can
|
||||||
|
have problems with this fact, so if you use this driver, be sure to boot your
|
||||||
|
Linux box in 640x480 in 8 bits. If you don't do this, SDL will emulate that
|
||||||
|
mode, resulting in a high performance penalty. If you use an specific Framebuffer
|
||||||
|
driver, or the VESAFB driver from kernels 2.6, just don't worry: FBZX will
|
||||||
|
automagically change the graphic mode when starts.
|
||||||
|
|
||||||
|
|
||||||
|
WHAT CAPABILITIES HAVE FBZX?
|
||||||
|
|
||||||
|
FBZX can emulate the original 48K spectrum (issue 2 and issue 3), the original
|
||||||
|
128K, the Amstrad +2, the Amstrad +2A and the Spanish 128K.
|
||||||
|
|
||||||
|
The screen and the sound are emulated in a very acuracy way, so nearly all
|
||||||
|
the sound and screen effects should work in this emulator.
|
||||||
|
|
||||||
|
128K sound is emulated too, and can be disabled in 128K mode in order to save
|
||||||
|
CPU time procesing, if your computer is slow.
|
||||||
|
|
||||||
|
It emulates the Interface I and one microdrive unit, allowing to load from and
|
||||||
|
save to MDR files.
|
||||||
|
|
||||||
|
FBZX can handle Z80 snapshots (both load and save) and SNA (only load). In a
|
||||||
|
future, more snapshot formats will be supported.
|
||||||
|
|
||||||
|
FBZX can handle TAP files (load and save), and have a fast-load mode that allows
|
||||||
|
to load in milliseconds a TAP file. This fast-load mode is enabled by default, but
|
||||||
|
can be disabled.
|
||||||
|
|
||||||
|
FBZX can also handle TZX files (see README.TZX for details).
|
||||||
|
|
||||||
|
FBZX can emulate the Kempston, Cursor, Sinclair 1 and Sinclair 2 joysticks,
|
||||||
|
with the cursor keys (fire is emulated with the right ALT key, ALT-GR
|
||||||
|
key, WINDOWS MENU key or WINDOWS SYSTEM right key), or with a real
|
||||||
|
JoyStick.
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I USE FBZX?
|
||||||
|
|
||||||
|
To run FBZX just type
|
||||||
|
|
||||||
|
fbzx
|
||||||
|
|
||||||
|
from a console.
|
||||||
|
|
||||||
|
You can load a snapshot directly with:
|
||||||
|
|
||||||
|
fbzx game.z80
|
||||||
|
fbzx game.sna
|
||||||
|
|
||||||
|
or assign a TAP or TZX file with:
|
||||||
|
|
||||||
|
fbzx game.tap
|
||||||
|
fbzx game.tzx
|
||||||
|
|
||||||
|
(in this case you still must use LOAD ""). This allows you to asociate that
|
||||||
|
file extensions to FBZX.
|
||||||
|
|
||||||
|
You can use the option -fs to run it in FullScreen mode. If you use the -rotate
|
||||||
|
option, FBZX will run in 480x640 mode (needed for some PDAs like the Zaurus)
|
||||||
|
rotating the screen 90 degrees. There's another option, -mini, that will run
|
||||||
|
FBZX in 480x640 mode but the screen won't be rotated, but will be half width
|
||||||
|
and height (very small).
|
||||||
|
|
||||||
|
You can run it without sound too, just typing:
|
||||||
|
|
||||||
|
fbzx -nosound
|
||||||
|
|
||||||
|
You can use this if you don't have a sound card, or it hasn't OSS support.
|
||||||
|
|
||||||
|
You can combine theses options as you like. An example:
|
||||||
|
|
||||||
|
fbzx -nosound -fs
|
||||||
|
|
||||||
|
fbzx -rotate -nosound
|
||||||
|
|
||||||
|
By default, FBZX will try to use ALSA sound; if it can't, it will try with OSS
|
||||||
|
sound; finally, if both fails it will use no sound and alert the user.
|
||||||
|
|
||||||
|
You can change the order with
|
||||||
|
|
||||||
|
fbzx -oss
|
||||||
|
|
||||||
|
That way it will try firts with OSS, then with ALSA.
|
||||||
|
|
||||||
|
FBZX works in X too, but it would run slower due to the penalty of the X
|
||||||
|
Window System. Fortunately this only applies to old systems. Current
|
||||||
|
computers can run FBZX under X without problem.
|
||||||
|
|
||||||
|
The PC keyboard works exactly like the Spectrum keyboard (but only numbers and
|
||||||
|
letters). ENTER key is Return, CAPS SHIFT is in both Shift keys, and SYMBOL
|
||||||
|
SHIFT is in both Control keys. Delete, ',' and '.' works too. I hope to add
|
||||||
|
'extended keys' in a near future.
|
||||||
|
|
||||||
|
Whit ESC you exit FBZX.
|
||||||
|
|
||||||
|
F1 shows a help page with all the available keys.
|
||||||
|
|
||||||
|
F2 sends you to a menu where you can load and save snapshots.
|
||||||
|
|
||||||
|
F3 sends you to a menu where you can choose a TAP/TZX file, rewind it,
|
||||||
|
choose if you want normal speed or fast speed for loading, enable or
|
||||||
|
disable the write protection, and create a new (and empty) TAP file.
|
||||||
|
|
||||||
|
F4 send you to a menu where you can choose the emulation type you want (48K,
|
||||||
|
128K, +2, +2A or spanish 128K), the joystick, enable or disable the AY
|
||||||
|
emulation and enable or disable the Interface I.
|
||||||
|
|
||||||
|
F5 stops the tape when normal speed is selected. With fast speed, it does
|
||||||
|
nothing.
|
||||||
|
|
||||||
|
F6 plays the tape when normal speed is selected. With fast speed, it does
|
||||||
|
nothing.
|
||||||
|
|
||||||
|
F7 allows to choose a MDR file (microdrive), protect and unprotect it,
|
||||||
|
and create a new (and empty) one.
|
||||||
|
|
||||||
|
F8 allows to shows a picture with the keyboard layout, or insert POKE values
|
||||||
|
|
||||||
|
F9 toggles between fullscreen/windowed mode
|
||||||
|
|
||||||
|
F10 resets the spectrum.
|
||||||
|
|
||||||
|
F11 is volume down.
|
||||||
|
|
||||||
|
F12 is volume up.
|
||||||
|
|
||||||
|
If your system doesn't have function keys, you can use TAB plus keys 0 to 9
|
||||||
|
to emulate them (F11 is TAB and O, and F12 is TAB and P).
|
||||||
|
|
||||||
|
|
||||||
|
HOW DO I CHOOSE A FILE WITH THE TAP/TZX OR Z80/SNA SELECTOR?
|
||||||
|
|
||||||
|
You can choose a file just by moving the white bar with the cursor keys. You
|
||||||
|
can use also the RePag and AvPag to jump over 12 positions.
|
||||||
|
|
||||||
|
The files are in white ink, the directories in green ink, and the upper
|
||||||
|
directory are the two red dots.
|
||||||
|
|
||||||
|
When you choose a TAP file, it is marked as "save protected", so if you want
|
||||||
|
to save programs, you must enable it. If you create a new TAP file, it is
|
||||||
|
marked as "save enabled", so you can start to save directly.
|
||||||
|
|
||||||
|
The SAVE option works only with the classic ROM routine, so you will be able
|
||||||
|
to save from programs that use them (it can save programs without header, too,
|
||||||
|
since the emulator intercepts the call to SA-BYTES). Each new block is added at
|
||||||
|
the end of the file, but only if the SAVE operation is enabled for this file.
|
||||||
|
|
||||||
|
|
||||||
|
HOW WORKS THE FAST SPEED LOAD AND SAVE FOR TAP FILES?
|
||||||
|
|
||||||
|
Just type LOAD "" in the emulator (or choose the TAPE LOADER option in the 128K
|
||||||
|
menu) and the tape will automagically load. This only works with programs that
|
||||||
|
uses the ROM to load all the blocks. If you have a TAP file with a program that
|
||||||
|
uses a custom routine to load the blocks, then you must use the NORMAL SPEED.
|
||||||
|
To do this, press F3 to go to the TAP menu and choose NORMAL SPEED. Then return
|
||||||
|
to the emulation (with ESC) and use LOAD "" (or the TAPE LOADER option).
|
||||||
|
Finally, put the tape in Play with F6. You can stop the tape with F5 and start
|
||||||
|
it again with F6 as many times you want.
|
||||||
|
|
||||||
|
When the tape ends, is automatically stoped and rewinded. You can rewind the
|
||||||
|
tape when you want with the right option in the TAP menu (F3 key).
|
||||||
|
|
||||||
|
In a near future a block manager will be added, in order to allow the user to
|
||||||
|
choose a block into the TAP file (thinking in multistage games).
|
||||||
|
|
||||||
|
Remember that the Fast Speed is available only for TAP files, not in TZX. In
|
||||||
|
the last case you can go to the SETTINGS menu (F4) and change the TURBO mode
|
||||||
|
to FAST, so the tape will load faster, and then change again to NORMAL.
|
||||||
|
|
||||||
|
The FAST SPEED applies when saving too. The SAVE operation is done ALWAYS
|
||||||
|
when SA-BYTES (in the Spectrum ROM) is called. The difference between FAST and
|
||||||
|
normal SAVE is that FAST returns inmediately, and NORMAL calls the original
|
||||||
|
routine. This means that, if you abort the save command, the block will be saved
|
||||||
|
in the TAP file anyway.
|
||||||
|
|
||||||
|
|
||||||
|
HOW WORKS THE INTERFACE I AND MICRODRIVE EMULATION?
|
||||||
|
|
||||||
|
FBZX can emulate an Interface I with one microdrive attached, but only when
|
||||||
|
working as Spectrum 48K, 128K or +2, never as +2A/+3 since it's incompatible.
|
||||||
|
|
||||||
|
You just have to choose an MDR file (or create a new MDR file) using the F7
|
||||||
|
key, and you will be able to use all the Interface I commands and programs.
|
||||||
|
Remember to format your cartridge (MDR file) after creating one.
|
||||||
|
|
||||||
|
When you save something to the cartridge, the MDR file is updated as soon as
|
||||||
|
the Spectrum stops the "motor" of the drive.
|
26
README.TZX
Normal file
26
README.TZX
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
ABOUT THE TZX SUPPORT
|
||||||
|
|
||||||
|
Currently, the support for TZX files is incomplete, in the sense it only
|
||||||
|
supports the most common tape blocks. The current implementation should
|
||||||
|
allow to load the 99% of the games, including a lot with specific load
|
||||||
|
routines (like Turbo).
|
||||||
|
|
||||||
|
I didn't add that blocks because I was able to find only a limited number of
|
||||||
|
TZX with estrange load protections, so I preferred to add only blocks that I can test
|
||||||
|
myself.
|
||||||
|
|
||||||
|
If you try to load a TZX file that contains an unsuported block, FBZX will show
|
||||||
|
you a message "Unsuported TZX. Contact FBZX autor". In that case, please,
|
||||||
|
send me by e-mail that TZX file in order to implement that new block kind in
|
||||||
|
the TZX loader.
|
||||||
|
|
||||||
|
|
||||||
|
PROBLEMS WITH SPEEDLOCK-2?
|
||||||
|
|
||||||
|
The old Z80 emulator had problems to load SpeedLock programs (turbo protection).
|
||||||
|
I haven't been unable to test the new emulator in this case, so I can't
|
||||||
|
say if it finally works or not. All comments are welcome.
|
||||||
|
|
||||||
|
Other kind of TURBO protections (like Alkatraz, the one used in Fairlight)
|
||||||
|
have been tested and work fine.
|
||||||
|
|
14
TODO
Normal file
14
TODO
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
TO-DO list (in any particular order)
|
||||||
|
|
||||||
|
-Add support for more snapshot types, like SLP, SP, ZX, ZXS, ZX82...
|
||||||
|
-Finish support for TZX tape format (see README.TZX for details).
|
||||||
|
-Discover why Speedlock-protected games doesn't work (see README.TZX for
|
||||||
|
details)
|
||||||
|
-Add support for saving compressed Z80 snapshots (at this moment, are stored
|
||||||
|
always uncompressed).
|
||||||
|
-Add +3 disk drive emulation
|
||||||
|
-Add Disciple/PlusD emulation
|
||||||
|
-Add emulation for Russian spectrums (scorpion & pentagon).
|
||||||
|
-Add a TAP manager, to allow to go to a specific block into the TAP file.
|
||||||
|
-Add support for mouse, emulating the AMX Mouse.
|
||||||
|
|
141
VERSIONS
Normal file
141
VERSIONS
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
2.7.0
|
||||||
|
|
||||||
|
*Fixed a bug that prevented FBZX to store the current mode
|
||||||
|
*Now supports 320x240 mode
|
||||||
|
|
||||||
|
2.6.0
|
||||||
|
|
||||||
|
*ULAPlus support
|
||||||
|
*Fixed a little bug in the ROM loading
|
||||||
|
*Allows to go to TAP/Snapshots/etc menus from HELP menu
|
||||||
|
|
||||||
|
2.5.0
|
||||||
|
|
||||||
|
*Allows to set POKEs
|
||||||
|
*Emulates B&W sets
|
||||||
|
*Allows to load and save SCR snapshots
|
||||||
|
|
||||||
|
2.4.3
|
||||||
|
|
||||||
|
*Fixed a bug with the double-scan flag
|
||||||
|
|
||||||
|
2.4.2
|
||||||
|
|
||||||
|
*Fixed a bug with alsa sound
|
||||||
|
|
||||||
|
2.4.1
|
||||||
|
|
||||||
|
*Now will work fine under all 64bit systems
|
||||||
|
|
||||||
|
2.4.0
|
||||||
|
|
||||||
|
*Fixed a bug in SNA loader (thanks to Jose Luis)
|
||||||
|
*Added a DC filter in PulseAudio sound, to avoid losing the sound when
|
||||||
|
mixing with other audio sources (thanks to Paul N)
|
||||||
|
*Added a help message at startup
|
||||||
|
|
||||||
|
2.3.0
|
||||||
|
|
||||||
|
*Added support for PulseAudio
|
||||||
|
*Allows to selectively compile the audio backend (useful for Gentoo users)
|
||||||
|
|
||||||
|
2.2.0
|
||||||
|
|
||||||
|
*Several bugfixes in the Z80 emulator, giving a much more accurate
|
||||||
|
emulation of the Z80 instruction set (thanks to the Z80 tests from
|
||||||
|
FUSE). Anyway, still not perfect.
|
||||||
|
|
||||||
|
2.1b
|
||||||
|
|
||||||
|
*Directory ROMS in TAR.BZ2 package renamed to SPECTRUM-ROMS to allow FBZX
|
||||||
|
to run without global installation.
|
||||||
|
|
||||||
|
2.1
|
||||||
|
|
||||||
|
*Changed the ROM format for compatibility with files in
|
||||||
|
Debian package SPECTRUM-ROMS
|
||||||
|
*Added new icon (thanks to Paulo Silva)
|
||||||
|
|
||||||
|
2.0
|
||||||
|
|
||||||
|
*100% Free code (under GPL3) due to a rewriten Z80 emulator
|
||||||
|
*Emulates the Spanish 128K (thanks to J. Baltasar)
|
||||||
|
*Can use ALSA or OSS to sound output
|
||||||
|
*Stores the volume settings
|
||||||
|
*Fixed a bug in the sound with some soundcards
|
||||||
|
*Can be run from the local directory, without installing in /usr
|
||||||
|
|
||||||
|
1.10
|
||||||
|
|
||||||
|
*Allows to switch between full screen and window mode
|
||||||
|
*Added Turbo mode, to load TZX files faster (both thanks to a patch
|
||||||
|
from Marcin Bukat)
|
||||||
|
*Shows FBZX as window name
|
||||||
|
|
||||||
|
1.9
|
||||||
|
|
||||||
|
*Stores the current mode before exiting, so if you was playing in 128K
|
||||||
|
mode, it will return in 128K mode.
|
||||||
|
*Allows to show the screen with or without scanline emulation
|
||||||
|
*Shows the OSD in the bottom of the screen
|
||||||
|
*Clicking on the X button in the window bar closes the emulator
|
||||||
|
|
||||||
|
1.8
|
||||||
|
|
||||||
|
*Fixed a bug when loading .Z80 snapshots
|
||||||
|
*Added support for .SNA snapshots
|
||||||
|
*Added support for Joysticks
|
||||||
|
*Now creates an entry in the GNOME/KDE menus
|
||||||
|
*Can load snapshots or tapes from the command line
|
||||||
|
*Allows to asociate to it the file extensions .SNA, .Z80, .TAP and TZX so
|
||||||
|
you can load games just clicking over the file.
|
||||||
|
|
||||||
|
1.7
|
||||||
|
|
||||||
|
*Fixed a bug in the creation of 128K snapshots
|
||||||
|
*Fixed the memory access ports in 128K mode
|
||||||
|
|
||||||
|
1.6
|
||||||
|
*Fixed an stupid bug that can crash FBZX
|
||||||
|
*Added support for rotated, 480x640 screens (like PDAs)
|
||||||
|
*Direct support for 8, 16, 24 and 32 bpp (more performance)
|
||||||
|
*Added contended memory emulation
|
||||||
|
*Added support for ',' and '.' keys
|
||||||
|
*Added FullScreen mode in XWindows
|
||||||
|
*Added a picture with the keyboard layout
|
||||||
|
*Added support for computers without function keys
|
||||||
|
*Asks for confirmation before exiting
|
||||||
|
*Fixed the version number
|
||||||
|
|
||||||
|
1.5
|
||||||
|
*Direct compilation under BIG ENDIAN arquitectures (eg. PowerPC).
|
||||||
|
|
||||||
|
1.4
|
||||||
|
*Added the ability to create .TAP files and save to them.
|
||||||
|
*Added Interface I and Microdrive emulation (read and write).
|
||||||
|
*Added emulation of DELETE key.
|
||||||
|
*Added emulation of SNOW effect.
|
||||||
|
*Fixed a little bug in the fast-TAP loader.
|
||||||
|
*Fixed a speed problem when used without sound.
|
||||||
|
|
||||||
|
|
||||||
|
1.3
|
||||||
|
*Added support for more TZX tape files (thanks to Daley Thompson :)
|
||||||
|
|
||||||
|
1.2
|
||||||
|
*Added support for TZX tape files.
|
||||||
|
*Fixed a bug in the file selector.
|
||||||
|
*Added right emulation of register R.
|
||||||
|
*Added a digital low-pass filter to enhace the 48K sound.
|
||||||
|
|
||||||
|
1.1
|
||||||
|
*Changed the sound system. Now it uses OSS instead the SDL API. This fixes a
|
||||||
|
problem with the temporization and some glitches in the sound.
|
||||||
|
*Now can be used without sound card (run it with '-nosound' parameter).
|
||||||
|
|
||||||
|
1.0.1
|
||||||
|
*Very little fixes to remove some innocent warnings during compilation. Thanks
|
||||||
|
to Philip Kendall.
|
||||||
|
|
||||||
|
1.0
|
||||||
|
*First public release.
|
12
fbzx.desktop
Normal file
12
fbzx.desktop
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
X-MultipleArgs=false
|
||||||
|
Type=Application
|
||||||
|
Version=2.4.3
|
||||||
|
Encoding=UTF-8
|
||||||
|
Name=FBZX
|
||||||
|
GenericName=A Sinclair ZX Spectrum emulator
|
||||||
|
Comment=Play with the old, great games of the venerable ZX Spectrum
|
||||||
|
TryExec=fbzx
|
||||||
|
Exec=fbzx
|
||||||
|
Categories=Game;
|
||||||
|
Icon=fbzx
|
1
fbzx.pnproj
Normal file
1
fbzx.pnproj
Normal file
@ -0,0 +1 @@
|
|||||||
|
<Project name="fbzx"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="src" path="src\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="z80free" path="z80free\"><File path="COPYING"></File><File path="Makefile"></File><File path="Makefile.ori"></File><File path="README.txt"></File><File path="tests.expected"></File><File path="tests.in"></File><File path="tests.z80free"></File><File path="Z80free.c"></File><File path="Z80free.h"></File><File path="Z80free_codes.c"></File><File path="Z80free_codes.txt"></File><File path="Z80free_codesCB.c"></File><File path="Z80free_codesCB.txt"></File><File path="Z80free_codesDD.c"></File><File path="Z80free_codesDD.txt"></File><File path="Z80free_codesDDCB.c"></File><File path="Z80free_codesDDCB.txt"></File><File path="Z80free_codesED.c"></File><File path="Z80free_codesED.txt"></File><File path="Z80free_codesFD.c"></File><File path="Z80free_codesFD.txt"></File><File path="Z80free_codesFDCB.c"></File><File path="Z80free_codesFDCB.txt"></File><File path="z80free_gencode.py"></File><File path="z80free_tester.c"></File><File path="z80free_testgen.py"></File><File path="z80txt_converter.py"></File><File path="z80_test.pnproj"></File><File path="z80_test.pnps"></File></MagicFolder><File path="cargador.c"></File><File path="cargador.h"></File><File path="characters.c"></File><File path="characters.h"></File><File path="computer.c"></File><File path="computer.h"></File><File path="emulator.c"></File><File path="emulator.h"></File><File path="menus.c"></File><File path="menus.h"></File><File path="microdrive.c"></File><File path="microdrive.h"></File><File path="sound.c"></File><File path="sound.h"></File><File path="spk_ay.c"></File><File path="spk_ay.h"></File><File path="tape.c"></File><File path="tape.h"></File></MagicFolder><File path="Makefile"></File></Project>
|
1
fbzx.pnps
Normal file
1
fbzx.pnps
Normal file
@ -0,0 +1 @@
|
|||||||
|
<pd><ViewState><e p="fbzx" x="true"></e><e p="fbzx\src" x="true"></e><e p="fbzx\src\z80free" x="false"></e></ViewState></pd>
|
12
fbzx.svg
Normal file
12
fbzx.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg id="svg2" width="144" height="144" version="1.0">
|
||||||
|
<rect id="a" style="opacity:1;fill:#31372a;stroke:none" width="144" height="143.84433" x="0" y="0" />
|
||||||
|
<path id="b" style="fill:#dd5555;fill-opacity:1;stroke:none" d="M 144,24 L 84,144 L 96,144 L 144,48 L 144,24 z" />
|
||||||
|
<path id="c" style="fill:#77aa44;fill-opacity:1;stroke:none" d="M 144,72 L 108,144 L 120,144 L 144,96 L 144,72 z" />
|
||||||
|
<path id="d" style="fill:#bbbbaa;fill-opacity:1;stroke:none" d="M 58,70 L 17,70 L 17,68 L 58,68 L 58,48 L 8,48 L 8,57 L 49,57 L 49,59 L 8,59 L 8,79 L 58,79 L 58,70 z" />
|
||||||
|
<path id="e" style="fill:#bbbbaa;fill-opacity:1;stroke:none" d="M 71,68 L 103,68 L 103,79 L 112,79 L 112,59 L 103,59 L 103,48 L 94,48 L 94,59 L 80,59 L 80,48 L 71,48 L 71,59 L 62,59 L 62,79 L 71,79 L 71,68 z" />
|
||||||
|
<path id="f" style="fill:#bbbbaa;fill-opacity:1;stroke:none" d="M 28,24 L 58,24 L 58,15 L 28,15 L 28,13 L 58,13 L 58,4 L 38.5,4 L 19,4 L 19,15 L 10,15 L 10,24 L 19,24 L 19,46 L 28,46 L 28,24 z" />
|
||||||
|
<path id="g" style="fill:#bbbbaa;fill-opacity:1;stroke:none" d="M 110,15 L 71,15 L 71,4 L 62,4 L 62,46 L 110,46 L 110,15 zM 71,24 L 101,24 L 101,37 L 71,37 L 71,24 z" />
|
||||||
|
<path id="h" style="fill:#4477aa;fill-opacity:1;stroke:none" d="M 144,96 L 120,144 L 132,144 L 144,120 L 144,96 z" />
|
||||||
|
<path id="i" style="fill:#ee9944;fill-opacity:1;stroke:none" d="M 144,72 L 108,144 L 96,144 L 144,48 L 144,72 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
BIN
keymap.bmp
Normal file
BIN
keymap.bmp
Normal file
Binary file not shown.
BIN
spectrum-roms/128-0.rom
Normal file
BIN
spectrum-roms/128-0.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/128-1.rom
Normal file
BIN
spectrum-roms/128-1.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/128-spanish-0.rom
Normal file
BIN
spectrum-roms/128-spanish-0.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/128-spanish-1.rom
Normal file
BIN
spectrum-roms/128-spanish-1.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/48.rom
Normal file
BIN
spectrum-roms/48.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/if1-2.rom
Normal file
BIN
spectrum-roms/if1-2.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/plus2-0.rom
Normal file
BIN
spectrum-roms/plus2-0.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/plus2-1.rom
Normal file
BIN
spectrum-roms/plus2-1.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/plus3-0.rom
Normal file
BIN
spectrum-roms/plus3-0.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/plus3-1.rom
Normal file
BIN
spectrum-roms/plus3-1.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/plus3-2.rom
Normal file
BIN
spectrum-roms/plus3-2.rom
Normal file
Binary file not shown.
BIN
spectrum-roms/plus3-3.rom
Normal file
BIN
spectrum-roms/plus3-3.rom
Normal file
Binary file not shown.
625
src/cargador.c
Normal file
625
src/cargador.c
Normal file
@ -0,0 +1,625 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "z80free/Z80free.h"
|
||||||
|
#include "computer.h"
|
||||||
|
#include "emulator.h"
|
||||||
|
#include "cargador.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void uncompress_z80(FILE *fichero,int length,unsigned char *memo) {
|
||||||
|
|
||||||
|
unsigned char byte_loaded,EDfound,counter;
|
||||||
|
int position,retval;
|
||||||
|
|
||||||
|
counter=0;
|
||||||
|
byte_loaded=0;
|
||||||
|
EDfound=0;
|
||||||
|
position=0;
|
||||||
|
|
||||||
|
printf("Descomprimo de longitud %d\n",length);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(counter) {
|
||||||
|
memo[position++]=byte_loaded;
|
||||||
|
counter--;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
retval=fread(&byte_loaded,1,1,fichero);
|
||||||
|
|
||||||
|
if(EDfound==2) { // we have two EDs
|
||||||
|
counter=byte_loaded;
|
||||||
|
retval=fread(&byte_loaded,1,1,fichero);
|
||||||
|
EDfound=0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(byte_loaded==0xED) {
|
||||||
|
EDfound++;
|
||||||
|
} else {
|
||||||
|
if(EDfound==1) { // we found ED xx. We write ED and xx
|
||||||
|
memo[position++]=0xED;
|
||||||
|
EDfound=0;
|
||||||
|
}
|
||||||
|
if (position>=length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memo[position++]=byte_loaded;
|
||||||
|
}
|
||||||
|
} while(position<length);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int save_z80(char *filename) {
|
||||||
|
|
||||||
|
FILE *fichero;
|
||||||
|
unsigned char value,bucle;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
fichero=fopen(filename,"r");
|
||||||
|
if(fichero!=NULL) {
|
||||||
|
fclose(fichero);
|
||||||
|
return -1; // file already exists
|
||||||
|
}
|
||||||
|
|
||||||
|
fichero=fopen(filename,"w");
|
||||||
|
|
||||||
|
if(fichero==NULL)
|
||||||
|
return -2; // can't create file
|
||||||
|
|
||||||
|
fprintf(fichero,"%c%c%c%c%c%c",procesador.Rm.br.A,procesador.Rm.br.F,procesador.Rm.br.C,procesador.Rm.br.B,procesador.Rm.br.L,procesador.Rm.br.H); // AF, BC and HL
|
||||||
|
|
||||||
|
if(ordenador.mode128k==0) // 48K
|
||||||
|
fprintf(fichero,"%c%c",(byte)(procesador.PC&0x0FF),(byte)((procesador.PC>>8)&0xFF)); // PC
|
||||||
|
else
|
||||||
|
fprintf(fichero,"%c%c",0,0); // 128K
|
||||||
|
|
||||||
|
fprintf(fichero,"%c%c",procesador.Rm.br.P,procesador.Rm.br.S); // SP
|
||||||
|
fprintf(fichero,"%c%c%c",procesador.I,procesador.R,(((procesador.R2>>7)&0x01)|((ordenador.border<<1)&0x0E))); // I, R and border color
|
||||||
|
|
||||||
|
fprintf(fichero,"%c%c%c%c%c%c%c%c%c%c%c%c%c%c",procesador.Rm.br.E,procesador.Rm.br.D,procesador.Ra.br.C,procesador.Ra.br.B,procesador.Ra.br.E,procesador.Ra.br.D,procesador.Ra.br.L,procesador.Ra.br.H,procesador.Ra.br.A,procesador.Ra.br.F,procesador.Rm.br.IYl,procesador.Rm.br.IYh,procesador.Rm.br.IXl,procesador.Rm.br.IXh);
|
||||||
|
|
||||||
|
if (procesador.IFF1)
|
||||||
|
value=1;
|
||||||
|
else
|
||||||
|
value=0;
|
||||||
|
fprintf(fichero,"%c",value);
|
||||||
|
if (procesador.IFF2)
|
||||||
|
value=1;
|
||||||
|
else
|
||||||
|
value=0;
|
||||||
|
fprintf(fichero,"%c",value);
|
||||||
|
value=procesador.IM;
|
||||||
|
if(ordenador.issue==2)
|
||||||
|
value|=4;
|
||||||
|
switch (ordenador.joystick) {
|
||||||
|
case 1:
|
||||||
|
value|=64;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
value|=128;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
value|=192;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(fichero,"%c",value);
|
||||||
|
|
||||||
|
if(ordenador.mode128k==0) { // 48K
|
||||||
|
retval=fwrite((ordenador.memoria+147456),16384,1,fichero); // video memory
|
||||||
|
retval=fwrite((ordenador.memoria+98304),32768,1,fichero); // memory pages 2 & 3
|
||||||
|
fclose(fichero);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 128K
|
||||||
|
|
||||||
|
fprintf(fichero,"%c%c",23,0); // Z80 file v2.01
|
||||||
|
fprintf(fichero,"%c%c",(byte)(procesador.PC&0x0FF),(byte)((procesador.PC>>8)&0x0FF)); // PC
|
||||||
|
fprintf(fichero,"%c",3); // hardware mode=3
|
||||||
|
fprintf(fichero,"%c",ordenador.mport1); // content of 0x7FFD latch
|
||||||
|
fprintf(fichero,"%c%c",0,0); // no If1, no emulation of any kind
|
||||||
|
fprintf(fichero,"%c",ordenador.ay_latch); // last selected AY register
|
||||||
|
for(bucle=0;bucle<16;bucle++)
|
||||||
|
fprintf(fichero,"%c",ordenador.ay_registers[bucle]); // AY registers
|
||||||
|
for(bucle=0;bucle<8;bucle++) {
|
||||||
|
fprintf(fichero,"%c%c",0xFF,0xFF); // length=0xFFFF (uncompressed)
|
||||||
|
fprintf(fichero,"%c",bucle+3); // page number
|
||||||
|
retval=fwrite(ordenador.memoria+(16384*bucle)+65536,16384,1,fichero); // store page
|
||||||
|
}
|
||||||
|
fclose(fichero);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_z80(char *filename) {
|
||||||
|
|
||||||
|
struct z80snapshot snap;
|
||||||
|
unsigned char tempo[30],tempo2[56],memo[49152],type,compressed,page,byte_read[3];
|
||||||
|
FILE *fichero;
|
||||||
|
int longitud=0,longitud2,bucle,retval;
|
||||||
|
|
||||||
|
longitud=strlen(filename);
|
||||||
|
if ((longitud>4)&&(0==strcasecmp(".sna",filename+(longitud-4)))) {
|
||||||
|
printf("Read SNA file\n");
|
||||||
|
return load_sna(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Read Z80 file\n");
|
||||||
|
|
||||||
|
for(bucle=0;bucle<16;bucle++)
|
||||||
|
snap.ay_regs[bucle]=0;
|
||||||
|
|
||||||
|
fichero=fopen(filename,"r");
|
||||||
|
if(fichero==NULL)
|
||||||
|
return -1; // error
|
||||||
|
|
||||||
|
printf("Read header (first 30 bytes)\n");
|
||||||
|
retval=fread(tempo,1,30,fichero);
|
||||||
|
|
||||||
|
if((tempo[6]==0)&&(tempo[7]==0)) { // extended Z80
|
||||||
|
printf("It's an extended Z80 file\n");
|
||||||
|
type=1; // new type
|
||||||
|
|
||||||
|
retval=fread(tempo2,1,2,fichero); // read the length of the extension
|
||||||
|
|
||||||
|
longitud=((int)tempo2[0])+256*((int)tempo2[1]);
|
||||||
|
if(longitud>54) {
|
||||||
|
fclose(fichero);
|
||||||
|
printf("Not suported Z80 file\n");
|
||||||
|
return -3; // not a supported Z80 file
|
||||||
|
}
|
||||||
|
printf("Length: %d\n",longitud);
|
||||||
|
retval=fread(tempo2+2,1,longitud,fichero);
|
||||||
|
|
||||||
|
if(longitud==23) // z80 ver 2.01
|
||||||
|
switch(tempo2[4]) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
snap.type=0; // 48K
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
snap.type=1; // 128K
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fclose(fichero);
|
||||||
|
printf("Again not suported Z80 file\n");
|
||||||
|
return -3; // not a supported Z80 file
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else // z80 ver 3.0x
|
||||||
|
switch(tempo2[4]) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
snap.type=0; // 48K
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
snap.type=1; // 128K
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fclose(fichero);
|
||||||
|
return -3; // not a supported Z80 file
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Old type z80\n");
|
||||||
|
type=0; // old type
|
||||||
|
snap.type=0; // 48k
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tempo[29]&0x04) {
|
||||||
|
printf("Issue 2\n");
|
||||||
|
snap.issue=2; // issue2
|
||||||
|
} else {
|
||||||
|
printf("Issue 3\n");
|
||||||
|
snap.issue=3; // issue3
|
||||||
|
}
|
||||||
|
|
||||||
|
snap.A=tempo[0];
|
||||||
|
snap.F=tempo[1];
|
||||||
|
snap.C=tempo[2];
|
||||||
|
snap.B=tempo[3];
|
||||||
|
snap.L=tempo[4];
|
||||||
|
snap.H=tempo[5];
|
||||||
|
if(type) {
|
||||||
|
snap.PC=((word)tempo2[2])+256*((word)tempo2[3]);
|
||||||
|
for(bucle=0;bucle<16;bucle++)
|
||||||
|
snap.ay_regs[bucle]=tempo2[9+bucle];
|
||||||
|
snap.ay_latch=tempo2[8];
|
||||||
|
} else {
|
||||||
|
snap.PC=((word)tempo[6])+256*((word)tempo[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
snap.SP=((word)tempo[8])+256*((word)tempo[9]);
|
||||||
|
snap.I=tempo[10];
|
||||||
|
snap.R=(tempo[11]&0x7F);
|
||||||
|
|
||||||
|
if(tempo[12]==255) {
|
||||||
|
printf("Byte 12 is 255! doing 1\n");
|
||||||
|
tempo[12]=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tempo[12]&0x01)
|
||||||
|
snap.R|=0x80;
|
||||||
|
|
||||||
|
snap.border=(tempo[12]>>1)&0x07;
|
||||||
|
|
||||||
|
if(tempo[12]&32)
|
||||||
|
compressed=1;
|
||||||
|
else
|
||||||
|
compressed=0;
|
||||||
|
|
||||||
|
snap.E=tempo[13];
|
||||||
|
snap.D=tempo[14];
|
||||||
|
snap.CC=tempo[15];
|
||||||
|
snap.BB=tempo[16];
|
||||||
|
snap.EE=tempo[17];
|
||||||
|
snap.DD=tempo[18];
|
||||||
|
snap.LL=tempo[19];
|
||||||
|
snap.HH=tempo[20];
|
||||||
|
snap.AA=tempo[21];
|
||||||
|
snap.FF=tempo[22];
|
||||||
|
snap.IY=((word)tempo[23])+256*((word)tempo[24]);
|
||||||
|
snap.IX=((word)tempo[25])+256*((word)tempo[26]);
|
||||||
|
|
||||||
|
if(tempo[27]!=0)
|
||||||
|
snap.IFF1=1;
|
||||||
|
else
|
||||||
|
snap.IFF1=0;
|
||||||
|
|
||||||
|
if(tempo[28]!=0)
|
||||||
|
snap.IFF2=1;
|
||||||
|
else
|
||||||
|
snap.IFF2=0;
|
||||||
|
|
||||||
|
switch(tempo[29]&0x03) {
|
||||||
|
case 0:
|
||||||
|
snap.Imode=0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
snap.Imode=1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
snap.Imode=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
snap.joystick=((tempo[29]>>6)&0x03);
|
||||||
|
|
||||||
|
if(type)
|
||||||
|
snap.pager=tempo2[5];
|
||||||
|
|
||||||
|
if(type) { // extended z80
|
||||||
|
if(snap.type==1) { // 128K snapshot
|
||||||
|
|
||||||
|
/* fclose(fichero);
|
||||||
|
return -3;*/ // z80 file not yet supported
|
||||||
|
|
||||||
|
while(!feof(fichero)) {
|
||||||
|
retval=fread(byte_read,3,1,fichero);
|
||||||
|
if(feof(fichero))
|
||||||
|
break;
|
||||||
|
longitud2=((int)byte_read[0])+256*((int)byte_read[1]);
|
||||||
|
switch(byte_read[2]) {
|
||||||
|
case 3:
|
||||||
|
page=0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
page=1;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
page=2;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
page=3;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
page=4;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
page=5;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
page=6;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
page=7;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
page=11;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("Loading page %d of length %d\n",page,longitud);
|
||||||
|
if(longitud2==0xFFFF) // uncompressed raw data
|
||||||
|
retval=fread(snap.page[page],16384,1,fichero);
|
||||||
|
else
|
||||||
|
uncompress_z80(fichero,16384,snap.page[page]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
while(!feof(fichero)) {
|
||||||
|
retval=fread(byte_read,3,1,fichero);
|
||||||
|
if(feof(fichero))
|
||||||
|
break;
|
||||||
|
longitud2=((int)byte_read[0])+256*((int)byte_read[1]);
|
||||||
|
switch(byte_read[2]) {
|
||||||
|
case 8:
|
||||||
|
page=0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
page=1;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
page=2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
page=11;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(longitud2==0xFFFF) // uncompressed raw data
|
||||||
|
retval=fread(snap.page[page],16384,1,fichero);
|
||||||
|
else
|
||||||
|
uncompress_z80(fichero,16384,snap.page[page]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(compressed) {
|
||||||
|
// 48k compressed z80 loader
|
||||||
|
|
||||||
|
// we uncompress first the data
|
||||||
|
|
||||||
|
uncompress_z80(fichero,49152,memo);
|
||||||
|
|
||||||
|
memcpy(snap.page[0],memo,16384);
|
||||||
|
memcpy(snap.page[1],memo+16384,16384);
|
||||||
|
memcpy(snap.page[2],memo+32768,16384);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 48k uncompressed z80 loader
|
||||||
|
|
||||||
|
retval=fread(snap.page[0],16384,1,fichero);
|
||||||
|
retval=fread(snap.page[1],16384,1,fichero);
|
||||||
|
retval=fread(snap.page[2],16384,1,fichero);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
load_snap(&snap);
|
||||||
|
fclose(fichero);
|
||||||
|
return 0; // all right
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_sna(char *filename) {
|
||||||
|
|
||||||
|
unsigned char tempo[49179];
|
||||||
|
unsigned char tempo2[98308];
|
||||||
|
unsigned char type=0;
|
||||||
|
FILE *fichero;
|
||||||
|
struct z80snapshot snap;
|
||||||
|
unsigned char v1,v2;
|
||||||
|
int addr,loop;
|
||||||
|
|
||||||
|
|
||||||
|
printf("Loading SNA file\n");
|
||||||
|
|
||||||
|
fichero=fopen(filename,"r");
|
||||||
|
if(fichero==NULL)
|
||||||
|
return -1; // error
|
||||||
|
|
||||||
|
if (1!=fread(tempo,49179,1,fichero)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0==fread(tempo2,1,98308,fichero)) {
|
||||||
|
printf("48K SNA\n");
|
||||||
|
type=0;
|
||||||
|
} else {
|
||||||
|
printf("128K SNA\n");
|
||||||
|
type=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snap.type=type;
|
||||||
|
|
||||||
|
snap.I=tempo[0];
|
||||||
|
snap.LL=tempo[1];
|
||||||
|
snap.HH=tempo[2];
|
||||||
|
snap.EE=tempo[3];
|
||||||
|
snap.DD=tempo[4];
|
||||||
|
snap.CC=tempo[5];
|
||||||
|
snap.BB=tempo[6];
|
||||||
|
snap.FF=tempo[7];
|
||||||
|
snap.AA=tempo[8];
|
||||||
|
|
||||||
|
snap.L=tempo[9];
|
||||||
|
snap.H=tempo[10];
|
||||||
|
snap.E=tempo[11];
|
||||||
|
snap.D=tempo[12];
|
||||||
|
snap.C=tempo[13];
|
||||||
|
snap.B=tempo[14];
|
||||||
|
|
||||||
|
snap.IY=((word)tempo[15])+256*((word)tempo[16]);
|
||||||
|
snap.IX=((word)tempo[17])+256*((word)tempo[18]);
|
||||||
|
|
||||||
|
if (tempo[19]&0x01) {
|
||||||
|
snap.IFF1=1;
|
||||||
|
} else {
|
||||||
|
snap.IFF1=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempo[19]&0x02) {
|
||||||
|
snap.IFF2=1;
|
||||||
|
} else {
|
||||||
|
snap.IFF2=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
snap.R=tempo[20];
|
||||||
|
snap.F=tempo[21];
|
||||||
|
snap.A=tempo[22];
|
||||||
|
snap.SP=((word)tempo[23])+256*((word)tempo[24]);
|
||||||
|
snap.Imode=tempo[25];
|
||||||
|
snap.border=tempo[26];
|
||||||
|
|
||||||
|
if (type==0) {
|
||||||
|
|
||||||
|
v1=tempo[23];
|
||||||
|
v2=tempo[24];
|
||||||
|
addr=((int)v1)+256*((int)v2);
|
||||||
|
if ((addr<16384)||(addr>=65534)) {
|
||||||
|
printf("Error loading SNA file. Return address in ROM.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
addr-=16384;
|
||||||
|
addr+=27;
|
||||||
|
snap.PC=((word)tempo[addr])+256*((word)tempo[addr+1]);
|
||||||
|
tempo[addr]=0;
|
||||||
|
tempo[addr+1]=0;
|
||||||
|
snap.SP+=2;
|
||||||
|
snap.IFF1=snap.IFF2;
|
||||||
|
memcpy(snap.page[0],tempo+27,16384);
|
||||||
|
memcpy(snap.page[1],tempo+16411,16384);
|
||||||
|
memcpy(snap.page[2],tempo+32795,16384);
|
||||||
|
} else {
|
||||||
|
snap.PC=((word)tempo2[0])+256*((word)tempo2[1]);
|
||||||
|
memcpy(snap.page[5],tempo+27,16384);
|
||||||
|
memcpy(snap.page[2],tempo+16411,16384);
|
||||||
|
v1=tempo[2];
|
||||||
|
snap.pager=v1;
|
||||||
|
v1&=0x07;
|
||||||
|
memcpy(snap.page[v1],tempo+32795,16384);
|
||||||
|
addr=4;
|
||||||
|
for (loop=0;loop<7;loop++) {
|
||||||
|
if ((loop==2)||(loop==5)||(loop==((int)v1))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memcpy(snap.page[loop],tempo2+addr,16384);
|
||||||
|
addr+=16384;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
load_snap(&snap);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_snap(struct z80snapshot *snap) {
|
||||||
|
|
||||||
|
int bucle;
|
||||||
|
|
||||||
|
printf("Loading SnapShot\n");
|
||||||
|
|
||||||
|
switch(snap->type) {
|
||||||
|
case 0: // 48k
|
||||||
|
printf("Mode 48K\n");
|
||||||
|
ordenador.mode128k=0; // 48K mode
|
||||||
|
ordenador.issue=snap->issue;
|
||||||
|
ResetComputer();
|
||||||
|
break;
|
||||||
|
case 1: // 128k
|
||||||
|
printf("Mode 128K\n");
|
||||||
|
ordenador.mode128k=2; // +2 mode
|
||||||
|
ordenador.issue=3;
|
||||||
|
ResetComputer();
|
||||||
|
printf("Pager: %X\n",snap->pager);
|
||||||
|
Z80free_Out(0x7FFD,snap->pager);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ordenador.joystick=snap->joystick;
|
||||||
|
|
||||||
|
procesador.Rm.br.A=snap->A;
|
||||||
|
procesador.Rm.br.F=snap->F;
|
||||||
|
procesador.Rm.br.B=snap->B;
|
||||||
|
procesador.Rm.br.C=snap->C;
|
||||||
|
procesador.Rm.br.D=snap->D;
|
||||||
|
procesador.Rm.br.E=snap->E;
|
||||||
|
procesador.Rm.br.H=snap->H;
|
||||||
|
procesador.Rm.br.L=snap->L;
|
||||||
|
printf("A:%d F:%d B:%d C:%d D:%d E:%d H:%d L:%d\n",snap->A,snap->F,snap->B,snap->C,snap->D,snap->E,snap->H,snap->L);
|
||||||
|
procesador.Ra.br.A=snap->AA;
|
||||||
|
procesador.Ra.br.F=snap->FF;
|
||||||
|
procesador.Ra.br.B=snap->BB;
|
||||||
|
procesador.Ra.br.C=snap->CC;
|
||||||
|
procesador.Ra.br.D=snap->DD;
|
||||||
|
procesador.Ra.br.E=snap->EE;
|
||||||
|
procesador.Ra.br.H=snap->HH;
|
||||||
|
procesador.Ra.br.L=snap->LL;
|
||||||
|
printf("A:%d F:%d B:%d C:%d D:%d E:%d H:%d L:%d\n",snap->AA,snap->FF,snap->BB,snap->CC,snap->DD,snap->EE,snap->HH,snap->LL);
|
||||||
|
procesador.Rm.wr.IX=snap->IX;
|
||||||
|
procesador.Rm.wr.IY=snap->IY;
|
||||||
|
procesador.Rm.wr.SP=snap->SP;
|
||||||
|
procesador.PC=snap->PC;
|
||||||
|
printf("IX:%d IY:%d SP:%d PC:%d\n",snap->IX,snap->IY,snap->SP,snap->PC);
|
||||||
|
procesador.I=snap->I;
|
||||||
|
procesador.R=snap->R;
|
||||||
|
procesador.R2=snap->R;
|
||||||
|
printf("I:%d R:%d\n",snap->I,snap->R);
|
||||||
|
|
||||||
|
if(snap->IFF1) {
|
||||||
|
procesador.IFF1=1;
|
||||||
|
} else {
|
||||||
|
procesador.IFF1=0;
|
||||||
|
}
|
||||||
|
if(snap->IFF2) {
|
||||||
|
procesador.IFF2=1;
|
||||||
|
} else {
|
||||||
|
procesador.IFF2=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
procesador.IM=snap->Imode;
|
||||||
|
Z80free_Out(0xFFFE,((snap->border&0x07)|0x10));
|
||||||
|
|
||||||
|
switch(snap->type) {
|
||||||
|
case 0: // 48K
|
||||||
|
|
||||||
|
for(bucle=0;bucle<16384;bucle++) {
|
||||||
|
ordenador.memoria[bucle+147456]=snap->page[0][bucle];
|
||||||
|
ordenador.memoria[bucle+98304]=snap->page[1][bucle];
|
||||||
|
ordenador.memoria[bucle+114688]=snap->page[2][bucle];
|
||||||
|
}
|
||||||
|
|
||||||
|
ordenador.ay_emul=0;
|
||||||
|
break;
|
||||||
|
case 1: // 128K
|
||||||
|
|
||||||
|
for(bucle=0;bucle<16384;bucle++) {
|
||||||
|
ordenador.memoria[bucle+65536]=snap->page[0][bucle];
|
||||||
|
ordenador.memoria[bucle+81920]=snap->page[1][bucle];
|
||||||
|
ordenador.memoria[bucle+98304]=snap->page[2][bucle];
|
||||||
|
ordenador.memoria[bucle+114688]=snap->page[3][bucle];
|
||||||
|
ordenador.memoria[bucle+131072]=snap->page[4][bucle];
|
||||||
|
ordenador.memoria[bucle+147456]=snap->page[5][bucle];
|
||||||
|
ordenador.memoria[bucle+163840]=snap->page[6][bucle];
|
||||||
|
ordenador.memoria[bucle+180224]=snap->page[7][bucle];
|
||||||
|
}
|
||||||
|
ordenador.ay_emul=1;
|
||||||
|
for(bucle=0;bucle<16;bucle++)
|
||||||
|
ordenador.ay_registers[bucle]=snap->ay_regs[bucle];
|
||||||
|
ordenador.ay_latch=snap->ay_latch;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
43
src/cargador.h
Normal file
43
src/cargador.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "z80free/Z80free.h"
|
||||||
|
#include "computer.h"
|
||||||
|
#include "emulator.h"
|
||||||
|
|
||||||
|
struct z80snapshot {
|
||||||
|
|
||||||
|
byte A,F,B,C,D,E,H,L,AA,FF,BB,CC,DD,EE,HH,LL,R,I,IFF1,IFF2,Imode,issue;
|
||||||
|
word PC,IX,IY,SP;
|
||||||
|
byte type; // bit 0/1: 48K/128K/+3
|
||||||
|
byte border; // border color
|
||||||
|
byte pager; // content of pagination register in 128K mode
|
||||||
|
unsigned char page[12][16384];
|
||||||
|
unsigned int found_pages; // bit=1: page exists. bit=0: page don't exists.
|
||||||
|
unsigned char ay_regs[16];
|
||||||
|
unsigned char ay_latch;
|
||||||
|
unsigned char joystick;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int save_z80(char *);
|
||||||
|
int load_z80(char *);
|
||||||
|
int load_sna(char *);
|
||||||
|
void load_snap(struct z80snapshot *);
|
||||||
|
void uncompress_z80(FILE *,int,unsigned char *);
|
224
src/characters.c
Normal file
224
src/characters.c
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "characters.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include "emulator.h"
|
||||||
|
|
||||||
|
// prints the ASCII character CHARAC in the framebuffer MEMO, at X,Y with ink color COLOR and paper color BACK, asuming that the screen width is WIDTH
|
||||||
|
|
||||||
|
void printchar(unsigned char *memo, unsigned char carac, int x, int y, unsigned char color, unsigned char back, int width) {
|
||||||
|
|
||||||
|
int bucle1, bucle2, pos;
|
||||||
|
unsigned char bit_rot;
|
||||||
|
unsigned char *lugar, *lugar2;
|
||||||
|
|
||||||
|
pos=0;
|
||||||
|
bit_rot=0x80;
|
||||||
|
|
||||||
|
lugar=memo + (y * width + x) * ordenador.bpp;
|
||||||
|
for (bucle1=0;bucle1<16;bucle1++) {
|
||||||
|
lugar2=lugar;
|
||||||
|
for (bucle2=0;bucle2 < 16;bucle2++) {
|
||||||
|
if ((characters[carac-32][pos]) & bit_rot)
|
||||||
|
paint_one_pixel (colors + (int) (color), lugar2);
|
||||||
|
//*((unsigned int *)lugar2)=*(colors+(int)(color-16));
|
||||||
|
else if ((ordenador.text_mini==0)||((bucle1%2==0)&&(bucle2%2==0)))
|
||||||
|
paint_one_pixel (colors + (int) (back), lugar2);
|
||||||
|
//*((unsigned int *)lugar2)=*(colors+(int)(back-16));
|
||||||
|
if ((ordenador.text_mini==0)||(bucle2%2==1)) {
|
||||||
|
lugar2+=ordenador.bpp;
|
||||||
|
}
|
||||||
|
bit_rot/=2;
|
||||||
|
if ((bucle2 == 7) || (bucle2 == 15)) {
|
||||||
|
pos++;
|
||||||
|
bit_rot=0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((ordenador.text_mini==0)||(bucle1%2==1)) {
|
||||||
|
lugar+=(width * ordenador.bpp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prints the string CADENA in X,Y (centered if X=-1), with colors COLOR and BACK
|
||||||
|
|
||||||
|
void print_string(unsigned char *memo, char *cadena, int x, int y, unsigned char color, unsigned char back, int width) {
|
||||||
|
|
||||||
|
int length, ncarac, bucle, xx;
|
||||||
|
int xxx, yyy;
|
||||||
|
int w,h;
|
||||||
|
unsigned char *str2;
|
||||||
|
|
||||||
|
if (ordenador.text_mini==1) {
|
||||||
|
if (x!=-1)
|
||||||
|
x/=2;
|
||||||
|
y/=2;
|
||||||
|
w=8;
|
||||||
|
h=10;
|
||||||
|
} else {
|
||||||
|
w=16;
|
||||||
|
h=20;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ncarac=0,str2=cadena;*str2;str2++) {
|
||||||
|
if ((*str2)>=' ') {
|
||||||
|
ncarac++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
length=w * ncarac;
|
||||||
|
|
||||||
|
if (length > width) {
|
||||||
|
if (x>=0)
|
||||||
|
xx=x;
|
||||||
|
else
|
||||||
|
xx=0;
|
||||||
|
} else {
|
||||||
|
if (x == -1) // we want it centered
|
||||||
|
xx=(width / 2) - (length / 2);
|
||||||
|
else
|
||||||
|
xx=x;
|
||||||
|
}
|
||||||
|
|
||||||
|
xxx=xx;
|
||||||
|
yyy=y;
|
||||||
|
str2=cadena;
|
||||||
|
for (bucle=0;bucle<ncarac;bucle++) {
|
||||||
|
while ((*str2)<' ') {
|
||||||
|
if ((*str2)==1) {
|
||||||
|
color=*(str2+1);
|
||||||
|
str2+=2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*str2==2) {
|
||||||
|
back=*(str2+1);
|
||||||
|
str2+=2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("Error de cadena %d %s\n",*str2,cadena);
|
||||||
|
str2++;
|
||||||
|
}
|
||||||
|
if ((*str2)<=127) {
|
||||||
|
printchar (memo,*str2, xxx, yyy, color, back, width);
|
||||||
|
xxx+=w;
|
||||||
|
if (xxx >= width - w) {
|
||||||
|
xxx=0;
|
||||||
|
yyy+=h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char characters[96][32]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,2,0,2,0,2,0,0,0,0,0,3,0,3,0,0,0}
|
||||||
|
,{0,0,28,224,28,224,28,224,28,224,8,64,8,64,8,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,2,64,2,64,2,64,2,64,2,64,31,240,4,128,4,128,4,128,63,224,4,128,4,128,4,128,4,128,0,0}
|
||||||
|
,{0,0,1,0,3,208,4,48,8,16,8,0,8,0,4,0,3,192,0,32,0,16,0,16,16,16,24,32,23,192,1,0}
|
||||||
|
,{14,0,17,0,32,128,32,128,32,128,17,0,14,56,1,192,14,0,112,224,1,16,2,8,2,8,2,8,1,16,0,224}
|
||||||
|
,{0,0,0,0,7,64,9,128,8,0,8,0,4,0,12,0,18,96,34,64,33,128,32,128,32,192,17,64,14,48,0,0}
|
||||||
|
,{0,0,3,128,3,128,3,128,3,128,3,128,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,0,64,0,128,0,128,0,128,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,128,0,128,0,128,0,64}
|
||||||
|
,{0,0,16,0,8,0,8,0,8,0,4,0,4,0,4,0,4,0,4,0,4,0,4,0,8,0,8,0,8,0,16,0}
|
||||||
|
,{0,0,1,0,1,0,1,0,25,48,15,224,3,128,6,192,12,96,24,48,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,0,63,248,1,0,1,0,1,0,1,0,1,0,0,0,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,128,3,128,7,0,6,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,128,3,128,3,128,0,0}
|
||||||
|
,{0,0,0,16,0,32,0,32,0,64,0,64,0,128,0,128,1,0,1,0,2,0,2,0,4,0,4,0,8,0,8,0}
|
||||||
|
,{0,0,3,128,12,96,8,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,8,32,12,96,3,128}
|
||||||
|
,{0,0,3,0,29,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,31,240}
|
||||||
|
,{0,0,7,128,24,64,32,32,32,32,0,32,0,32,0,64,0,128,1,0,2,0,4,0,8,0,16,0,32,16,63,240}
|
||||||
|
,{0,0,15,128,16,96,0,32,0,32,0,32,0,64,7,128,0,96,0,16,0,16,0,16,0,16,32,16,24,96,7,128}
|
||||||
|
,{0,0,0,192,1,64,2,64,2,64,4,64,8,64,8,64,16,64,16,64,32,64,63,240,0,64,0,64,0,64,3,240}
|
||||||
|
,{0,0,31,224,16,0,16,0,16,0,16,0,23,128,24,96,0,32,0,16,0,16,0,16,0,16,0,32,48,96,15,128}
|
||||||
|
,{0,0,1,224,6,0,12,0,8,0,16,0,19,192,20,32,24,16,16,16,16,16,16,16,16,16,8,16,12,32,3,192}
|
||||||
|
,{0,0,63,224,32,32,32,64,0,64,0,64,0,128,0,128,0,128,0,128,1,0,1,0,1,0,2,0,2,0,2,0}
|
||||||
|
,{0,0,7,128,8,64,16,32,16,32,16,32,16,32,8,64,15,192,16,32,32,16,32,16,32,16,16,32,24,96,7,128}
|
||||||
|
,{0,0,3,128,12,96,24,48,16,16,16,16,16,16,8,48,12,80,3,144,0,16,0,16,0,32,0,32,0,192,31,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,3,128,3,128,3,128,0,0,0,0,0,0,0,0,0,0,3,128,3,128,3,128,0,0}
|
||||||
|
,{0,0,0,0,0,0,7,0,7,0,7,0,0,0,0,0,0,0,0,0,0,0,7,0,7,0,14,0,12,0,24,0}
|
||||||
|
,{0,0,0,0,0,0,0,48,0,192,3,0,12,0,48,0,96,0,48,0,12,0,3,0,0,192,0,48,0,0,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,248,0,0,0,0,63,248,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,0,0,0,0,48,0,12,0,3,0,0,192,0,48,0,24,0,48,0,192,3,0,12,0,48,0,0,0,0,0}
|
||||||
|
,{0,0,31,0,32,128,32,64,0,64,0,64,0,64,0,128,3,0,4,0,4,0,0,0,0,0,6,0,6,0,0,0}
|
||||||
|
,{0,0,7,128,24,64,16,32,32,32,32,224,33,32,34,32,34,32,34,32,34,32,33,32,32,240,16,0,24,96,7,192}
|
||||||
|
,{0,0,31,128,2,128,4,64,4,64,4,64,8,32,8,32,8,32,31,240,16,16,16,16,32,8,32,8,120,60,0,0}
|
||||||
|
,{0,0,127,224,16,16,16,8,16,8,16,8,16,16,31,224,16,16,16,8,16,8,16,8,16,8,16,16,127,224,0,0}
|
||||||
|
,{0,0,3,200,12,40,24,24,16,8,32,0,32,0,32,0,32,0,32,0,32,0,16,8,24,24,12,48,3,192,0,0}
|
||||||
|
,{0,0,127,192,32,48,32,16,32,8,32,8,32,8,32,8,32,8,32,8,32,8,32,8,32,16,32,48,127,192,0,0}
|
||||||
|
,{0,0,127,240,16,16,16,16,16,16,17,0,17,0,31,0,17,0,17,0,16,8,16,8,16,8,16,8,127,248,0,0}
|
||||||
|
,{0,0,63,248,8,8,8,8,8,8,8,128,8,128,15,128,8,128,8,128,8,0,8,0,8,0,8,0,63,128,0,0}
|
||||||
|
,{0,0,7,144,24,80,48,48,32,16,64,0,64,0,64,0,64,0,65,248,64,16,32,16,48,16,24,32,7,192,0,0}
|
||||||
|
,{0,0,124,124,16,16,16,16,16,16,16,16,16,16,31,240,16,16,16,16,16,16,16,16,16,16,16,16,124,124,0,0}
|
||||||
|
,{0,0,31,240,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,31,240,0,0}
|
||||||
|
,{0,0,7,252,0,32,0,32,0,32,0,32,0,32,0,32,0,32,32,32,32,32,32,32,32,64,16,192,15,0,0,0}
|
||||||
|
,{0,0,124,120,16,32,16,64,16,128,17,0,18,0,22,0,25,0,16,128,16,64,16,32,16,32,16,16,124,60,0,0}
|
||||||
|
,{0,0,127,0,8,0,8,0,8,0,8,0,8,0,8,0,8,0,8,0,8,8,8,8,8,8,8,8,127,248,0,0}
|
||||||
|
,{0,0,112,28,48,24,48,24,40,40,40,40,36,72,36,72,34,136,35,136,32,8,32,8,32,8,32,8,120,60,0,0}
|
||||||
|
,{0,0,240,252,48,16,40,16,36,16,36,16,34,16,34,16,33,16,33,16,32,144,32,144,32,80,32,48,252,48,0,0}
|
||||||
|
,{0,0,7,192,24,48,48,24,32,8,64,4,64,4,64,4,64,4,64,4,64,4,32,8,48,24,24,48,7,192,0,0}
|
||||||
|
,{0,0,63,224,8,16,8,8,8,8,8,8,8,8,8,16,15,224,8,0,8,0,8,0,8,0,8,0,63,128,0,0}
|
||||||
|
,{0,0,7,192,24,48,48,24,32,8,64,4,64,4,64,4,64,4,64,4,64,4,32,8,48,24,24,48,7,192,3,24}
|
||||||
|
,{0,0,127,192,16,32,16,16,16,16,16,16,16,16,16,32,31,192,16,128,16,64,16,32,16,32,16,16,124,28,0,0}
|
||||||
|
,{0,0,7,144,24,80,32,48,32,16,32,0,24,0,7,128,0,96,0,16,0,16,32,16,48,16,40,32,39,192,0,0}
|
||||||
|
,{0,0,63,248,33,8,33,8,33,8,33,8,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,15,224,0,0}
|
||||||
|
,{0,0,124,248,32,16,32,16,32,16,32,16,32,16,32,16,32,16,32,16,32,16,32,16,32,16,16,32,15,192,0,0}
|
||||||
|
,{0,0,124,124,32,8,32,8,16,16,16,16,8,32,8,32,8,32,4,64,4,64,4,64,2,128,3,128,1,0,0,0}
|
||||||
|
,{0,0,124,124,32,8,32,8,33,8,33,8,34,136,34,136,18,144,20,80,20,80,20,80,24,48,24,48,24,48,0,0}
|
||||||
|
,{0,0,124,124,16,16,8,32,8,32,4,64,2,128,1,0,2,128,4,64,4,64,8,32,16,16,16,16,124,124,0,0}
|
||||||
|
,{0,0,120,60,16,16,8,32,8,32,4,64,4,64,2,128,1,0,1,0,1,0,1,0,1,0,1,0,15,224,0,0}
|
||||||
|
,{0,0,63,240,32,16,32,32,32,64,32,128,0,128,1,0,2,0,4,0,4,16,8,16,16,16,32,16,63,240,0,0}
|
||||||
|
,{0,0,1,192,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,192}
|
||||||
|
,{16,0,16,0,8,0,8,0,4,0,4,0,2,0,2,0,1,0,1,0,0,128,0,128,0,64,0,64,0,32,0,32}
|
||||||
|
,{0,0,7,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,7,0}
|
||||||
|
,{0,0,2,0,7,0,8,128,16,64,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,254,0,0}
|
||||||
|
,{0,0,12,0,6,0,3,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,15,128,16,64,0,32,0,32,15,160,16,96,32,32,32,32,32,32,16,96,15,184,0,0}
|
||||||
|
,{0,0,112,0,16,0,16,0,19,224,20,24,24,8,16,4,16,4,16,4,16,4,16,4,24,8,20,24,115,224,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,7,208,24,48,16,16,32,16,32,0,32,0,32,0,32,0,16,24,24,48,7,192,0,0}
|
||||||
|
,{0,0,0,112,0,16,0,16,15,144,48,80,32,48,64,16,64,16,64,16,64,16,64,16,32,48,48,80,15,156,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,7,192,24,48,16,16,32,8,32,8,63,248,32,0,32,0,16,0,24,24,7,224,0,0}
|
||||||
|
,{0,0,1,240,3,8,2,0,2,0,31,240,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,31,240,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,7,216,8,48,16,16,16,16,16,16,16,16,8,48,7,208,0,16,0,32,0,96,7,192}
|
||||||
|
,{0,0,112,0,16,0,16,0,16,0,19,192,20,32,24,16,16,16,16,16,16,16,16,16,16,16,16,16,124,124,0,0}
|
||||||
|
,{0,0,1,0,1,0,0,0,0,0,15,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,31,240,0,0}
|
||||||
|
,{0,0,0,64,0,64,0,0,0,0,31,224,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,64,0,192,31,0}
|
||||||
|
,{0,0,56,0,8,0,8,0,8,0,8,240,8,64,8,128,9,0,10,0,14,0,9,0,8,128,8,64,56,120,0,0}
|
||||||
|
,{0,0,31,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,63,248,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,238,112,49,136,33,8,33,8,33,8,33,8,33,8,33,8,33,8,33,8,249,140,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,115,192,20,32,24,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,124,124,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,7,192,24,48,16,16,32,8,32,8,32,8,32,8,32,8,16,16,24,48,7,192,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,55,192,24,32,16,16,16,16,16,16,16,16,24,32,23,192,16,0,16,0,16,0,126,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,7,216,8,48,16,16,16,16,16,16,16,16,8,48,7,208,0,16,0,16,0,16,0,252}
|
||||||
|
,{0,0,0,0,0,0,0,0,28,112,5,136,6,0,4,0,4,0,4,0,4,0,4,0,4,0,4,0,63,224,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,7,208,8,48,8,16,8,0,7,0,0,224,0,16,0,16,16,16,24,32,23,192,0,0}
|
||||||
|
,{0,0,8,0,8,0,8,0,63,224,8,0,8,0,8,0,8,0,8,0,8,0,8,0,8,0,4,48,3,192,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,112,112,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,8,80,7,152,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,124,124,16,16,16,16,8,32,8,32,8,32,4,64,4,64,2,128,3,128,1,0,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,120,60,32,8,32,8,33,8,17,16,18,144,18,144,18,144,10,160,12,96,12,96,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,60,120,16,16,8,32,4,64,2,128,1,0,2,128,4,64,8,32,16,16,60,120,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,30,120,4,32,4,32,4,64,2,64,2,128,1,128,1,0,3,0,2,0,63,128,0,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,31,240,16,16,16,32,0,64,0,128,1,0,2,0,4,0,8,16,16,16,31,240,0,0}
|
||||||
|
,{0,0,0,192,1,0,1,0,1,0,1,0,1,0,1,0,6,0,1,0,1,0,1,0,1,0,1,0,1,0,0,192}
|
||||||
|
,{0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0}
|
||||||
|
,{0,0,6,0,1,0,1,0,1,0,1,0,1,0,1,0,0,192,1,0,1,0,1,0,1,0,1,0,1,0,6,0}
|
||||||
|
,{0,0,0,0,0,0,0,0,0,0,15,12,25,152,48,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
,{0,0,85,84,0,0,64,4,0,0,64,4,0,0,64,4,0,0,64,4,0,0,64,4,0,0,85,84,0,0,0,0}};
|
23
src/characters.h
Normal file
23
src/characters.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern unsigned char characters[96][32];
|
||||||
|
|
||||||
|
void printchar(unsigned char *,unsigned char,int,int,unsigned char,unsigned char,int);
|
||||||
|
void print_string(unsigned char *,char*,int,int,unsigned char,unsigned char,int);
|
1599
src/computer.c
Normal file
1599
src/computer.c
Normal file
File diff suppressed because it is too large
Load Diff
215
src/computer.h
Normal file
215
src/computer.h
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef computer_h
|
||||||
|
#define computer_h
|
||||||
|
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
#include <SDL/SDL_thread.h>
|
||||||
|
|
||||||
|
// #define MUT
|
||||||
|
|
||||||
|
extern char salir;
|
||||||
|
|
||||||
|
enum tapmodes {TAP_GUIDE, TAP_DATA, TAP_PAUSE, TAP_TRASH, TAP_STOP, TAP_PAUSE2, TZX_PURE_TONE,
|
||||||
|
TZX_SEQ_PULSES, TAP_FINAL_BIT, TAP_PAUSE3};
|
||||||
|
enum taptypes {TAP_TAP, TAP_TZX};
|
||||||
|
|
||||||
|
struct computer {
|
||||||
|
|
||||||
|
unsigned int temporal_io;
|
||||||
|
|
||||||
|
// screen private global variables
|
||||||
|
SDL_Surface *screen;
|
||||||
|
unsigned char *screenbuffer;
|
||||||
|
unsigned int screen_width;
|
||||||
|
unsigned int translate[6144],translate2[6144];
|
||||||
|
unsigned char zaurus_mini;
|
||||||
|
unsigned char text_mini;
|
||||||
|
unsigned char dblscan;
|
||||||
|
unsigned char bw;
|
||||||
|
|
||||||
|
int contador_flash;
|
||||||
|
|
||||||
|
unsigned int *p_translt,*p_translt2;
|
||||||
|
unsigned char *pixel; // current address
|
||||||
|
char border,flash;
|
||||||
|
int currline,currpix;
|
||||||
|
|
||||||
|
int tstados_counter; // counts tstates leaved to the next call
|
||||||
|
int resx,resy,bpp; // screen resolutions
|
||||||
|
int init_line; // cuantity to add to the base address to start to paint
|
||||||
|
int next_line; // cuantity to add when we reach the end of line to go to next line
|
||||||
|
int next_scanline; // cuantity to add to pass to the next scanline
|
||||||
|
int first_line; // first line to start to paint
|
||||||
|
int last_line; // last line to paint
|
||||||
|
int first_pixel; // first pixel of a line to paint
|
||||||
|
int last_pixel; // last pixel of a line to paint
|
||||||
|
int next_pixel; // next pixel
|
||||||
|
int pixancho,pixalto; // maximum pixel value for width and height
|
||||||
|
int jump_pixel;
|
||||||
|
unsigned char screen_snow; // 0-> no emulate snow; 1-> emulate snow
|
||||||
|
unsigned char contended_zone; // 0-> no contention; 1-> contention possible
|
||||||
|
int cicles_counter; // counts how many pixel clock cicles passed since las interrupt
|
||||||
|
|
||||||
|
char ulaplus; // 0 = inactive; 1 = active
|
||||||
|
unsigned char ulaplus_reg; // contains the last selected register in the ULAPlus
|
||||||
|
unsigned char ulaplus_palete[64]; // contains the current palete
|
||||||
|
|
||||||
|
// keyboard private global variables
|
||||||
|
|
||||||
|
unsigned char s8,s9,s10,s11,s12,s13,s14,s15;
|
||||||
|
unsigned char k8,k9,k10,k11,k12,k13,k14,k15;
|
||||||
|
unsigned char readed;
|
||||||
|
unsigned char tab_extended;
|
||||||
|
unsigned char esc_again;
|
||||||
|
|
||||||
|
// kempston joystick private global variables
|
||||||
|
|
||||||
|
unsigned char js,jk;
|
||||||
|
|
||||||
|
// Linux joystick private global variables
|
||||||
|
|
||||||
|
unsigned char use_js;
|
||||||
|
unsigned char updown,leftright;
|
||||||
|
|
||||||
|
// sound global variables
|
||||||
|
|
||||||
|
int tst_sample; // number of tstates per sample
|
||||||
|
int freq; // frequency for reproduction
|
||||||
|
int format; // 0: 8 bits, 1: 16 bits LSB, 2: 16 bits MSB
|
||||||
|
signed char sign; // 0: unsigned; 1: signed
|
||||||
|
int channels; // number of channels
|
||||||
|
int buffer_len; // sound buffer length (in samples)
|
||||||
|
int increment; // cuantity to add to jump to the next sample
|
||||||
|
unsigned char volume; // volume
|
||||||
|
unsigned char sample1[4]; // buffer with precalculated sample 1 (for buzzer)
|
||||||
|
unsigned char sample1b[4]; // buffer with prec. sample 1 (for AY-3-8912)
|
||||||
|
unsigned char sample0[4]; // buffer with precalculated sample 0
|
||||||
|
unsigned char sound_bit;
|
||||||
|
unsigned int tstados_counter_sound;
|
||||||
|
unsigned char *current_buffer;
|
||||||
|
unsigned char num_buff;
|
||||||
|
unsigned int sound_cuantity; // counter for the buffer
|
||||||
|
unsigned char ay_registers[16]; // registers for the AY emulation
|
||||||
|
unsigned int aych_a,aych_b,aych_c,aych_n,aych_envel; // counters for AY emulation
|
||||||
|
unsigned char ayval_a,ayval_b,ayval_c,ayval_n;
|
||||||
|
unsigned char ay_emul; // 0: no AY emulation; 1: AY emulation
|
||||||
|
unsigned char vol_a,vol_b,vol_c;
|
||||||
|
unsigned int tst_ay;
|
||||||
|
unsigned int tst_ay2;
|
||||||
|
unsigned int ay_latch;
|
||||||
|
signed char ay_envel_value;
|
||||||
|
unsigned char ay_envel_way;
|
||||||
|
unsigned char sound_current_value;
|
||||||
|
|
||||||
|
// bus global variables
|
||||||
|
|
||||||
|
unsigned char bus_counter;
|
||||||
|
unsigned char bus_value;
|
||||||
|
unsigned char issue; // 2= 48K issue 2, 3= 48K issue 3
|
||||||
|
unsigned char mode128k; // 0=48K, 1=128K, 2=+2, 3=+3
|
||||||
|
unsigned char joystick; // 0=cursor, 1=kempston, 2=sinclair1, 3=sinclair2
|
||||||
|
unsigned char port254;
|
||||||
|
|
||||||
|
|
||||||
|
// tape global variables
|
||||||
|
|
||||||
|
enum tapmodes tape_current_mode;
|
||||||
|
unsigned char pause; // 1=tape stop
|
||||||
|
enum taptypes tape_file_type;
|
||||||
|
unsigned int tape_counter0;
|
||||||
|
unsigned int tape_counter1;
|
||||||
|
unsigned int tape_counter_rep;
|
||||||
|
unsigned char tape_byte;
|
||||||
|
unsigned char tape_bit;
|
||||||
|
unsigned char tape_readed;
|
||||||
|
unsigned int tape_byte_counter;
|
||||||
|
unsigned int tape_pause_at_end;
|
||||||
|
FILE *tap_file;
|
||||||
|
unsigned char tape_fast_load; // 0 normal load; 1 fast load
|
||||||
|
unsigned char current_tap[2049];
|
||||||
|
|
||||||
|
unsigned char tape_current_bit;
|
||||||
|
unsigned int tape_block_level;
|
||||||
|
unsigned int tape_sync_level0;
|
||||||
|
unsigned int tape_sync_level1;
|
||||||
|
unsigned int tape_bit0_level;
|
||||||
|
unsigned int tape_bit1_level;
|
||||||
|
unsigned char tape_bits_at_end;
|
||||||
|
unsigned int tape_loop_counter;
|
||||||
|
long tape_loop_pos;
|
||||||
|
|
||||||
|
unsigned char tape_write; // 0 can't write; 1 can write
|
||||||
|
|
||||||
|
// Microdrive global variables
|
||||||
|
FILE *mdr_file; // Current microdrive file
|
||||||
|
unsigned char mdr_current_mdr[2049]; // current path and name for microdrive file
|
||||||
|
unsigned char mdr_active; // 0: not installed; 1: installed
|
||||||
|
unsigned char mdr_paged; // 0: not pagined; 1: pagined
|
||||||
|
unsigned int mdr_tapehead; // current position in the tape
|
||||||
|
unsigned int mdr_bytes; // number of bytes read or written in this transfer
|
||||||
|
unsigned int mdr_maxbytes; // maximum number of bytes to read or write in this transfer
|
||||||
|
unsigned int mdr_gap; // TSTATEs remaining for GAP end
|
||||||
|
unsigned int mdr_nogap; // TSTATEs remaining for next GAP
|
||||||
|
unsigned char mdr_cartridge[137923]; // current cartridge
|
||||||
|
unsigned char mdr_drive; // current drive
|
||||||
|
byte mdr_old_STATUS; // to detect an edge in COM CLK
|
||||||
|
unsigned char mdr_modified; // if a sector is stored, this change to know that it must be stored in the file
|
||||||
|
|
||||||
|
// OSD global variables
|
||||||
|
|
||||||
|
unsigned char osd_text[200];
|
||||||
|
unsigned int osd_time;
|
||||||
|
|
||||||
|
// pagination global variables
|
||||||
|
|
||||||
|
unsigned char mport1,mport2; // ports for memory management (128K and +3)
|
||||||
|
unsigned int video_offset; // 0 for page 5, and 32768 for page 7
|
||||||
|
unsigned char *block0,*block1,*block2,*block3; // pointers for memory access (one for each 16K block).
|
||||||
|
|
||||||
|
// public
|
||||||
|
|
||||||
|
unsigned char memoria[196608]; // memory (12 pages of 16K each one). 4 for ROM, and 8 for RAM
|
||||||
|
unsigned char shadowrom[8192]; // space for Interface I's ROMs
|
||||||
|
unsigned char interr;
|
||||||
|
unsigned char mustlock;
|
||||||
|
unsigned char other_ret; // 0=no change; 1=memory returns RET (201)
|
||||||
|
|
||||||
|
unsigned char turbo;
|
||||||
|
};
|
||||||
|
|
||||||
|
void computer_init();
|
||||||
|
void register_screen(SDL_Surface *);
|
||||||
|
inline void show_screen(int);
|
||||||
|
inline void paint_pixels(unsigned char, unsigned char, unsigned char);
|
||||||
|
inline void read_keyboard();
|
||||||
|
void fill_audio(void *udata,Uint8 *,int);
|
||||||
|
void set_volume(unsigned char);
|
||||||
|
inline void play_sound(unsigned int);
|
||||||
|
inline void emulate(int);
|
||||||
|
void ResetComputer();
|
||||||
|
inline byte bus_empty();
|
||||||
|
void set_memory_pointers();
|
||||||
|
inline void play_ay();
|
||||||
|
inline void paint_one_pixel(unsigned char *colour,unsigned char *address);
|
||||||
|
void computer_set_palete();
|
||||||
|
void set_palete_entry(unsigned char entry, byte Value);
|
||||||
|
|
||||||
|
#endif
|
802
src/emulator.c
Normal file
802
src/emulator.c
Normal file
@ -0,0 +1,802 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "z80free/Z80free.h"
|
||||||
|
#include "computer.h"
|
||||||
|
#include "emulator.h"
|
||||||
|
#include "cargador.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "characters.h"
|
||||||
|
#include "menus.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
#include <SDL/SDL_thread.h>
|
||||||
|
#include "sound.h"
|
||||||
|
#include "tape.h"
|
||||||
|
#include "microdrive.h"
|
||||||
|
|
||||||
|
#ifdef GEKKO
|
||||||
|
#include <gccore.h>
|
||||||
|
#include <fat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
FILE *fdebug;
|
||||||
|
#define printf(...) fprintf(fdebug,__VA_ARGS__); fflush (fdebug)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char debug_var=1;
|
||||||
|
|
||||||
|
Z80FREE procesador;
|
||||||
|
struct computer ordenador;
|
||||||
|
SDL_Surface *screen;
|
||||||
|
char salir,sound_aborted;
|
||||||
|
unsigned char *sound[NUM_SNDBUF];
|
||||||
|
char path_snaps[2049];
|
||||||
|
char path_taps[2049];
|
||||||
|
char path_mdrs[2049];
|
||||||
|
unsigned int colors[80];
|
||||||
|
unsigned int jump_frames,curr_frames;
|
||||||
|
char *filenames[5];
|
||||||
|
|
||||||
|
void SDL_Fullscreen_Switch()
|
||||||
|
{
|
||||||
|
Uint32 flags = screen->flags;
|
||||||
|
if ( flags & SDL_FULLSCREEN )
|
||||||
|
flags &= ~SDL_FULLSCREEN;
|
||||||
|
else
|
||||||
|
flags |= SDL_FULLSCREEN;
|
||||||
|
|
||||||
|
screen = SDL_SetVideoMode(screen->w, screen->h, screen->format->BitsPerPixel,flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *myfopen(char *filename,char *mode) {
|
||||||
|
|
||||||
|
char tmp[4096];
|
||||||
|
FILE *fichero;
|
||||||
|
|
||||||
|
fichero=fopen(filename,mode);
|
||||||
|
if (fichero!=NULL) {
|
||||||
|
return (fichero);
|
||||||
|
}
|
||||||
|
sprintf(tmp,"/usr/share/%s",filename);
|
||||||
|
fichero=fopen(tmp,mode);
|
||||||
|
if (fichero!=NULL) {
|
||||||
|
return (fichero);
|
||||||
|
}
|
||||||
|
sprintf(tmp,"/usr/local/share/%s",filename);
|
||||||
|
fichero=fopen(tmp,mode);
|
||||||
|
if (fichero!=NULL) {
|
||||||
|
return (fichero);
|
||||||
|
}
|
||||||
|
#ifdef GEKKO
|
||||||
|
sprintf(tmp,"/fbzx-wii/%s",filename);
|
||||||
|
fichero=fopen(tmp,mode);
|
||||||
|
if (fichero!=NULL) {
|
||||||
|
return (fichero);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *load_a_rom(char **filenames) {
|
||||||
|
|
||||||
|
char **pointer;
|
||||||
|
int offset=0;
|
||||||
|
FILE *fichero;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
for(pointer=filenames;*pointer!=NULL;pointer++) {
|
||||||
|
fichero=myfopen(*pointer,"r");
|
||||||
|
if(fichero==NULL) {
|
||||||
|
return (*pointer);
|
||||||
|
}
|
||||||
|
size=fread(ordenador.memoria+offset,16384,1,fichero);
|
||||||
|
offset+=16384;
|
||||||
|
fclose(fichero);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_rom(char type) {
|
||||||
|
|
||||||
|
char *retval;
|
||||||
|
FILE *fichero;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case 0:
|
||||||
|
filenames[0]="spectrum-roms/48.rom";
|
||||||
|
filenames[1]=NULL;
|
||||||
|
retval=load_a_rom(filenames);
|
||||||
|
if (retval) {
|
||||||
|
printf("Can't load file %s\n",retval);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
filenames[0]="spectrum-roms/128-0.rom";
|
||||||
|
filenames[1]="spectrum-roms/128-1.rom";
|
||||||
|
filenames[2]=NULL;
|
||||||
|
retval=load_a_rom(filenames);
|
||||||
|
if (retval) {
|
||||||
|
printf("Can't load file %s\n",retval);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
filenames[0]="spectrum-roms/plus2-0.rom";
|
||||||
|
filenames[1]="spectrum-roms/plus2-1.rom";
|
||||||
|
filenames[2]=NULL;
|
||||||
|
retval=load_a_rom(filenames);
|
||||||
|
if (retval) {
|
||||||
|
printf("Can't load file %s\n",retval);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// first, try last version of PLUS3 roms
|
||||||
|
|
||||||
|
filenames[0]="spectrum-roms/plus3-41-0.rom";
|
||||||
|
filenames[1]="spectrum-roms/plus3-41-1.rom";
|
||||||
|
filenames[2]="spectrum-roms/plus3-41-2.rom";
|
||||||
|
filenames[3]="spectrum-roms/plus3-41-3.rom";
|
||||||
|
filenames[4]=NULL;
|
||||||
|
retval=load_a_rom(filenames);
|
||||||
|
if (retval) {
|
||||||
|
printf("Can't load the Spectrum +3 ROM version 4.1. Trying with version 4.0\n");
|
||||||
|
filenames[0]="spectrum-roms/plus3-40-0.rom";
|
||||||
|
filenames[1]="spectrum-roms/plus3-40-1.rom";
|
||||||
|
filenames[2]="spectrum-roms/plus3-40-2.rom";
|
||||||
|
filenames[3]="spectrum-roms/plus3-40-3.rom";
|
||||||
|
filenames[4]=NULL;
|
||||||
|
retval=load_a_rom(filenames);
|
||||||
|
if (retval) {
|
||||||
|
printf("Can't load the Spectrum +3 ROM version 4.0. Trying with legacy filenames\n");
|
||||||
|
filenames[0]="spectrum-roms/plus3-0.rom";
|
||||||
|
filenames[1]="spectrum-roms/plus3-1.rom";
|
||||||
|
filenames[2]="spectrum-roms/plus3-2.rom";
|
||||||
|
filenames[3]="spectrum-roms/plus3-3.rom";
|
||||||
|
filenames[4]=NULL;
|
||||||
|
retval=load_a_rom(filenames);
|
||||||
|
if (retval) {
|
||||||
|
printf("Can't load file %s\n",retval);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
filenames[0]="spectrum-roms/128-spanish-0.rom";
|
||||||
|
filenames[1]="spectrum-roms/128-spanish-1.rom";
|
||||||
|
filenames[2]=NULL;
|
||||||
|
retval=load_a_rom(filenames);
|
||||||
|
if (retval) {
|
||||||
|
printf("Can't load file %s\n",retval);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fichero=myfopen("spectrum-roms/if1-2.rom","r"); // load Interface1 ROM
|
||||||
|
if(fichero==NULL) {
|
||||||
|
// try legacy name
|
||||||
|
fichero=myfopen("spectrum-roms/if1-v2.rom","r");
|
||||||
|
if(fichero==NULL) {
|
||||||
|
printf("Can't open Interface1 ROM file\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size=fread(ordenador.shadowrom,8192,1,fichero);
|
||||||
|
fclose(fichero);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_screen(int resx,int resy,int depth,int fullscreen,int dblbuffer,int hwsurface) {
|
||||||
|
|
||||||
|
int retorno,bucle,bucle2,valores,ret2;
|
||||||
|
unsigned char value;
|
||||||
|
|
||||||
|
//if (sound_type!=3)
|
||||||
|
retorno=SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
/*else
|
||||||
|
retorno=SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);*/
|
||||||
|
if(retorno!=0) {
|
||||||
|
printf("Can't initialize SDL library. Exiting\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK)) {
|
||||||
|
ordenador.use_js=0;
|
||||||
|
printf("Can't initialize JoyStick subsystem\n");
|
||||||
|
} else {
|
||||||
|
printf("JoyStick subsystem initialized\n");
|
||||||
|
ordenador.use_js=1;
|
||||||
|
if(SDL_NumJoysticks()>0){
|
||||||
|
// Open joystick
|
||||||
|
for (bucle=0;bucle<SDL_NumJoysticks();bucle++) {
|
||||||
|
if (NULL==SDL_JoystickOpen(bucle)) {
|
||||||
|
printf("Can't open joystick %d\n",bucle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// screen initialization
|
||||||
|
valores=SDL_HWPALETTE|SDL_ANYFORMAT;
|
||||||
|
if (fullscreen==1)
|
||||||
|
valores|=SDL_FULLSCREEN;
|
||||||
|
|
||||||
|
if (dblbuffer==1)
|
||||||
|
valores|=SDL_DOUBLEBUF;
|
||||||
|
if (hwsurface==1)
|
||||||
|
valores|=SDL_HWSURFACE;
|
||||||
|
else
|
||||||
|
valores|=SDL_SWSURFACE;
|
||||||
|
|
||||||
|
screen=SDL_SetVideoMode(resx,resy,depth,valores);
|
||||||
|
if(screen==NULL) {
|
||||||
|
printf("Can't assign SDL Surface. Exiting\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ordenador.bpp=screen->format->BytesPerPixel;
|
||||||
|
printf("Bytes per pixel: %d\n",ordenador.bpp);
|
||||||
|
|
||||||
|
if(SDL_MUSTLOCK(screen)) {
|
||||||
|
ordenador.mustlock=1;
|
||||||
|
SDL_LockSurface(screen);
|
||||||
|
} else
|
||||||
|
ordenador.mustlock=0;
|
||||||
|
|
||||||
|
printf("Locking screen: %d\n", ordenador.mustlock);
|
||||||
|
|
||||||
|
// sound initialization
|
||||||
|
|
||||||
|
if (sound_type==SOUND_AUTOMATIC) {
|
||||||
|
ret2=sound_init(1); // check all sound systems
|
||||||
|
} else {
|
||||||
|
ret2=sound_init(0); // try with the one specified in command line
|
||||||
|
}
|
||||||
|
if(ret2==0) {
|
||||||
|
sound_aborted=0;
|
||||||
|
} else { // if fails, run without sound
|
||||||
|
sound_type=SOUND_NO;
|
||||||
|
sound_init(0);
|
||||||
|
sound_aborted=1;
|
||||||
|
}
|
||||||
|
printf("Init sound\n");
|
||||||
|
if(ordenador.format)
|
||||||
|
ordenador.increment=2*ordenador.channels;
|
||||||
|
else
|
||||||
|
ordenador.increment=ordenador.channels;
|
||||||
|
|
||||||
|
value=0;
|
||||||
|
for(bucle2=0;bucle2<NUM_SNDBUF;bucle2++) {
|
||||||
|
sound[bucle2]=(unsigned char *)malloc(ordenador.buffer_len*ordenador.increment+8);
|
||||||
|
for(bucle=0;bucle<ordenador.buffer_len*ordenador.increment+4;bucle++)
|
||||||
|
sound[bucle2][bucle]=value;
|
||||||
|
value+=4;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Init sound 2\n");
|
||||||
|
ordenador.tst_sample=3500000/ordenador.freq;
|
||||||
|
printf("Set volume\n");
|
||||||
|
set_volume(70);
|
||||||
|
printf("Return init\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void end_system() {
|
||||||
|
|
||||||
|
sound_close();
|
||||||
|
|
||||||
|
if(ordenador.mustlock)
|
||||||
|
SDL_UnlockSurface(screen);
|
||||||
|
|
||||||
|
if(ordenador.tap_file!=NULL)
|
||||||
|
fclose(ordenador.tap_file);
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_main_game(char *nombre) {
|
||||||
|
|
||||||
|
int longitud,retval;
|
||||||
|
char *puntero;
|
||||||
|
|
||||||
|
longitud=strlen(nombre);
|
||||||
|
if (longitud<5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
puntero=nombre+(longitud-4);
|
||||||
|
if ((0==strcasecmp(".z80",puntero))||(0==strcasecmp(".sna",puntero))) {
|
||||||
|
load_z80(nombre);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((0==strcasecmp(".tap",puntero))||(0==strcasecmp(".tzx",puntero))) {
|
||||||
|
char char_id[10];
|
||||||
|
ordenador.tape_write = 0; // by default, can't record
|
||||||
|
ordenador.tap_file=fopen(nombre,"r+"); // read and write
|
||||||
|
if(ordenador.tap_file==NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
strcpy(ordenador.current_tap,nombre);
|
||||||
|
|
||||||
|
retval=fread(char_id,10,1,ordenador.tap_file); // read the (maybe) TZX header
|
||||||
|
if((!strncmp(char_id,"ZXTape!",7)) && (char_id[7]==0x1A)&&(char_id[8]==1)) {
|
||||||
|
ordenador.tape_file_type = TAP_TZX;
|
||||||
|
rewind_tape(ordenador.tap_file,1);
|
||||||
|
} else {
|
||||||
|
ordenador.tape_file_type = TAP_TAP;
|
||||||
|
rewind_tape(ordenador.tap_file,1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_config(struct computer *object) {
|
||||||
|
|
||||||
|
char config_path[1024];
|
||||||
|
int length;
|
||||||
|
FILE *fconfig;
|
||||||
|
|
||||||
|
strcpy(config_path,getenv("HOME"));
|
||||||
|
length=strlen(config_path);
|
||||||
|
if ((length>0)&&(config_path[length-1]!='/'))
|
||||||
|
strcat(config_path,"/");
|
||||||
|
strcat(config_path,"fbzx_conf");
|
||||||
|
fconfig = fopen(config_path,"wb");
|
||||||
|
if (fconfig==NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(fconfig,"mode=%c%c",48+object->mode128k,10);
|
||||||
|
fprintf(fconfig,"issue=%c%c",48+object->issue,10);
|
||||||
|
fprintf(fconfig,"joystick=%c%c",48+object->joystick,10);
|
||||||
|
fprintf(fconfig,"ay_sound=%c%c",48+object->ay_emul,10);
|
||||||
|
fprintf(fconfig,"interface1=%c%c",48+object->mdr_active,10);
|
||||||
|
fprintf(fconfig,"doublescan=%c%c",48+object->dblscan,10);
|
||||||
|
fprintf(fconfig,"volume=%c%c",65+(object->volume/4),10);
|
||||||
|
fprintf(fconfig,"bw=%c%c",48+object->bw,10);
|
||||||
|
fclose(fconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_config(struct computer *object) {
|
||||||
|
|
||||||
|
char config_path[1024];
|
||||||
|
char line[1024],carac,done;
|
||||||
|
int length,pos;
|
||||||
|
FILE *fconfig;
|
||||||
|
unsigned char volume=255,mode128k=255,issue=255,joystick=255,ay_emul=255,mdr_active=255,dblscan=255,bw=255;
|
||||||
|
|
||||||
|
strcpy(config_path,getenv("HOME"));
|
||||||
|
length=strlen(config_path);
|
||||||
|
if ((length>0)&&(config_path[length-1]!='/'))
|
||||||
|
strcat(config_path,"/");
|
||||||
|
strcat(config_path,"fbzx_conf");
|
||||||
|
fconfig = fopen(config_path,"rb");
|
||||||
|
if (fconfig==NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
done=1;
|
||||||
|
pos=0;
|
||||||
|
line[0]=0;
|
||||||
|
while(!feof(fconfig)) {
|
||||||
|
if (done) {
|
||||||
|
line[0]=0;
|
||||||
|
pos=0;
|
||||||
|
done=0;
|
||||||
|
}
|
||||||
|
if (0!=fread(&carac,1,1,fconfig)) {
|
||||||
|
if ((carac!=13)&&(carac!=10)) {
|
||||||
|
line[pos]=carac;
|
||||||
|
if (pos<1023) {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done=1;
|
||||||
|
line[pos]=0;
|
||||||
|
if (line[0]=='#') { // coment
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line,"mode=",5)) {
|
||||||
|
printf("Cambio a modo %c\n",line[5]-'0');
|
||||||
|
mode128k=line[5]-'0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line,"issue=",6)) {
|
||||||
|
issue=line[6]-'0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line,"joystick=",9)) {
|
||||||
|
joystick=line[9]-'0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line,"ay_sound=",9)) {
|
||||||
|
ay_emul=line[9]-'0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line,"interface1=",11)) {
|
||||||
|
mdr_active=line[11]-'0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line,"doublescan=",11)) {
|
||||||
|
dblscan=line[11]-'0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line,"volume=",7)) {
|
||||||
|
volume=4*(line[7]-'A');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(line,"bw=",3)) {
|
||||||
|
bw=(line[3]-'0');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode128k<5) {
|
||||||
|
object->mode128k=mode128k;
|
||||||
|
}
|
||||||
|
if (issue<4) {
|
||||||
|
object->issue=issue;
|
||||||
|
}
|
||||||
|
if (joystick<4) {
|
||||||
|
object->joystick=joystick;
|
||||||
|
}
|
||||||
|
if (ay_emul<2) {
|
||||||
|
object->ay_emul=ay_emul;
|
||||||
|
}
|
||||||
|
if (mdr_active<2) {
|
||||||
|
object->mdr_active=mdr_active;
|
||||||
|
}
|
||||||
|
if (dblscan<2) {
|
||||||
|
object->dblscan=dblscan;
|
||||||
|
}
|
||||||
|
if (bw<2) {
|
||||||
|
object->bw=bw;
|
||||||
|
}
|
||||||
|
if (volume<255) {
|
||||||
|
object->volume=volume;
|
||||||
|
set_volume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc,char *argv[]) {
|
||||||
|
|
||||||
|
int bucle,tstados,argumento,fullscreen,dblbuffer,hwsurface,length;
|
||||||
|
char gamefile[4096];
|
||||||
|
word PC=0;
|
||||||
|
|
||||||
|
// by default, try all sound modes
|
||||||
|
sound_type=SOUND_AUTOMATIC;
|
||||||
|
gamefile[0]=0;
|
||||||
|
ordenador.zaurus_mini=0;
|
||||||
|
ordenador.text_mini=0;
|
||||||
|
ordenador.ulaplus=0;
|
||||||
|
ordenador.ulaplus_reg=0;
|
||||||
|
fullscreen=0;
|
||||||
|
dblbuffer=0;
|
||||||
|
hwsurface=0;
|
||||||
|
|
||||||
|
argumento=0;
|
||||||
|
jump_frames=0;
|
||||||
|
curr_frames=0;
|
||||||
|
ordenador.dblscan=0;
|
||||||
|
ordenador.bw=0;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fatInitDefault();
|
||||||
|
fdebug = fopen("/fbzx-wii/logfile.txt","w");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GEKKO
|
||||||
|
fullscreen=1;
|
||||||
|
dblbuffer=1;
|
||||||
|
hwsurface=1;
|
||||||
|
setenv("HOME", "/fbzx-wii", 1);
|
||||||
|
|
||||||
|
printf("\x1b[2;0H");
|
||||||
|
|
||||||
|
//initialize libfat library
|
||||||
|
if (!fatInitDefault())
|
||||||
|
{
|
||||||
|
printf("Couldn't initialize SD fat subsytem\n\n");
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("SD FAT subsytem initialized\n\n");
|
||||||
|
|
||||||
|
//SDL_Delay(3000);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
computer_init();
|
||||||
|
printf("Computer init\n");
|
||||||
|
|
||||||
|
printf("Modo: %d\n",ordenador.mode128k);
|
||||||
|
// load current config
|
||||||
|
load_config(&ordenador);
|
||||||
|
printf("Modo: %d\n",ordenador.mode128k);
|
||||||
|
while(argumento<argc) {
|
||||||
|
if ((0==strcmp(argv[argumento],"-h"))||(0==strcmp(argv[argumento],"--help"))) {
|
||||||
|
printf("\nUsage: fbzx [-nosound] ");
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
printf("[-alsa] ");
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
printf("[-oss] ");
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
printf("[-pulse] ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("[-mini] [-rotate] [-fs] [-hw] [-db] [-ds] [-ss] [-jump N] [gamefile]\n");
|
||||||
|
printf("\n -nosound: don't emulate sound\n");
|
||||||
|
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
printf(" -alsa: use ALSA for sound output\n");
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
printf(" -oss: use OSS for sound output\n");
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
printf(" -pulse: use PulseAudio for sound output (default)\n");
|
||||||
|
#endif
|
||||||
|
printf(" -mini: show screen at 320x240 in a rotated 640x480 screen\n");
|
||||||
|
printf(" -rotate: rotate screen clockwise\n");
|
||||||
|
printf(" -micro: show screen at 320x240\n");
|
||||||
|
printf(" -fs: start FBZX at fullscreen\n");
|
||||||
|
printf(" -hw: use hardware buffer (best for console framebuffer)\n");
|
||||||
|
printf(" -db: use double buffer\n");
|
||||||
|
printf(" -ds: use doublescan (don't emulate TV black stripes)\n");
|
||||||
|
printf(" -ss: force singlescan (emulate TV black stripes)\n");
|
||||||
|
printf(" -bw: emulate black&white TV set\n");
|
||||||
|
printf(" -color: emulate a color TV set\n");
|
||||||
|
printf(" -jump N: show one TV refresh and jump over N refreshes (for slow systems)\n");
|
||||||
|
printf(" gamefile: an optional .Z80 snapshot or .TAP/.TZX tape file\n\n");
|
||||||
|
exit(0);
|
||||||
|
} else if(0==strcmp(argv[argumento],"-nosound")) {
|
||||||
|
sound_type=SOUND_NO;
|
||||||
|
argumento++;
|
||||||
|
} else if(0==strcmp(argv[argumento],"-mini")) {
|
||||||
|
ordenador.zaurus_mini=1;
|
||||||
|
argumento++;
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
} else if(0==strcmp(argv[argumento],"-pulse")) {
|
||||||
|
sound_type=SOUND_PULSEAUDIO;
|
||||||
|
argumento++;
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
} else if(0==strcmp(argv[argumento],"-alsa")) {
|
||||||
|
sound_type=SOUND_ALSA;
|
||||||
|
argumento++;
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
} else if(0==strcmp(argv[argumento],"-oss")) {
|
||||||
|
sound_type=SOUND_OSS;
|
||||||
|
argumento++;
|
||||||
|
#endif
|
||||||
|
} else if(0==strcmp(argv[argumento],"-rotate")) {
|
||||||
|
ordenador.zaurus_mini=2;
|
||||||
|
argumento++;
|
||||||
|
} else if (0==strcmp(argv[argumento],"-micro")) {
|
||||||
|
ordenador.zaurus_mini=3;
|
||||||
|
ordenador.text_mini=1;
|
||||||
|
argumento++;
|
||||||
|
}else if(0==strcmp(argv[argumento],"-fs")) {
|
||||||
|
fullscreen=1;
|
||||||
|
argumento++;
|
||||||
|
} else if(0==strcmp(argv[argumento],"-hw")) {
|
||||||
|
hwsurface=1;
|
||||||
|
argumento++;
|
||||||
|
} else if(0==strcmp(argv[argumento],"-db")) {
|
||||||
|
dblbuffer=1;
|
||||||
|
argumento++;
|
||||||
|
} else if(0==strcmp(argv[argumento],"-ds")) {
|
||||||
|
ordenador.dblscan=1;
|
||||||
|
argumento++;
|
||||||
|
} else if(0==strcmp(argv[argumento],"-bw")) {
|
||||||
|
ordenador.bw=1;
|
||||||
|
argumento++;
|
||||||
|
} else if(0==strcmp(argv[argumento],"-color")) {
|
||||||
|
ordenador.bw=0;
|
||||||
|
argumento++;
|
||||||
|
} else if(0==strcmp(argv[argumento],"-ss")) {
|
||||||
|
ordenador.dblscan=0;
|
||||||
|
argumento++;
|
||||||
|
} else if(0==strncmp(argv[argumento],"-jump",5)) {
|
||||||
|
jump_frames=(int)(argv[argumento][5]);
|
||||||
|
jump_frames-=48;
|
||||||
|
argumento++;
|
||||||
|
printf ("Jump %d\n",jump_frames);
|
||||||
|
} else {
|
||||||
|
strcpy(gamefile,argv[argumento]);
|
||||||
|
argumento++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
atexit(end_system);
|
||||||
|
switch(ordenador.zaurus_mini) {
|
||||||
|
case 0:
|
||||||
|
init_screen(640,480,0,0,dblbuffer,hwsurface);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
init_screen(480,640,0,0,dblbuffer,hwsurface);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
init_screen(320,240,0,0,dblbuffer,hwsurface);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("Modo: %d\n",ordenador.mode128k);
|
||||||
|
register_screen(screen);
|
||||||
|
printf("Screen registered\n");
|
||||||
|
printf("Modo: %d\n",ordenador.mode128k);
|
||||||
|
#ifndef GEKKO
|
||||||
|
if(fullscreen) {
|
||||||
|
SDL_Fullscreen_Switch();
|
||||||
|
}
|
||||||
|
SDL_WM_SetCaption("FBZX","");
|
||||||
|
#endif
|
||||||
|
ordenador.interr=0;
|
||||||
|
|
||||||
|
ordenador.screenbuffer=ordenador.screen->pixels;
|
||||||
|
ordenador.screen_width=ordenador.screen->w;
|
||||||
|
|
||||||
|
// assign initial values for PATH variables
|
||||||
|
|
||||||
|
strcpy(path_snaps,getenv("HOME"));
|
||||||
|
length=strlen(path_snaps);
|
||||||
|
if ((length>0)&&(path_snaps[length-1]!='/'))
|
||||||
|
strcat(path_snaps,"/");
|
||||||
|
strcpy(path_taps,path_snaps);
|
||||||
|
strcpy(path_mdrs,path_snaps);
|
||||||
|
ordenador.current_tap[0]=0;
|
||||||
|
|
||||||
|
// assign random values to the memory before start execution
|
||||||
|
|
||||||
|
printf("Reset memory\n");
|
||||||
|
printf("Modo: %d\n",ordenador.mode128k);
|
||||||
|
for(bucle=0;bucle<196608;bucle++)
|
||||||
|
ordenador.memoria[bucle]=(unsigned char) rand();
|
||||||
|
|
||||||
|
printf("Memory resetted\n");
|
||||||
|
ordenador.tap_file=NULL;
|
||||||
|
printf("Modo: %d\n",ordenador.mode128k);
|
||||||
|
|
||||||
|
// we filter all the events, except keyboard events
|
||||||
|
|
||||||
|
SDL_EventState(SDL_ACTIVEEVENT,SDL_IGNORE);
|
||||||
|
SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE);
|
||||||
|
SDL_EventState(SDL_MOUSEBUTTONDOWN,SDL_IGNORE);
|
||||||
|
SDL_EventState(SDL_MOUSEBUTTONUP,SDL_IGNORE);
|
||||||
|
SDL_EventState(SDL_JOYAXISMOTION,SDL_ENABLE);
|
||||||
|
SDL_EventState(SDL_JOYBALLMOTION,SDL_ENABLE);
|
||||||
|
SDL_EventState(SDL_JOYHATMOTION,SDL_ENABLE);
|
||||||
|
SDL_EventState(SDL_JOYBUTTONDOWN,SDL_ENABLE);
|
||||||
|
SDL_EventState(SDL_JOYBUTTONUP,SDL_ENABLE);
|
||||||
|
SDL_EventState(SDL_QUIT,SDL_ENABLE);
|
||||||
|
SDL_EventState(SDL_SYSWMEVENT,SDL_IGNORE);
|
||||||
|
SDL_EventState(SDL_VIDEORESIZE,SDL_IGNORE);
|
||||||
|
SDL_EventState(SDL_USEREVENT,SDL_IGNORE);
|
||||||
|
|
||||||
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
salir=1;
|
||||||
|
|
||||||
|
printf("Init microdrive\n");
|
||||||
|
microdrive_init();
|
||||||
|
|
||||||
|
printf("Reset computer\n");
|
||||||
|
ResetComputer();
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
printf("Reset screen\n");
|
||||||
|
clean_screen();
|
||||||
|
|
||||||
|
if (sound_aborted==1) {
|
||||||
|
strcpy(ordenador.osd_text,"Running without sound (read the FAQ)");
|
||||||
|
ordenador.osd_time=100;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Modo: %d\n",ordenador.mode128k);
|
||||||
|
printf("load main game\n");
|
||||||
|
load_main_game(gamefile);
|
||||||
|
printf("Modo: %d\n",ordenador.mode128k);
|
||||||
|
|
||||||
|
sprintf(ordenador.osd_text,"Press F1 for help");
|
||||||
|
ordenador.osd_time=200;
|
||||||
|
|
||||||
|
printf("BPP: %d\n",ordenador.bpp);
|
||||||
|
while(salir) {
|
||||||
|
|
||||||
|
do {
|
||||||
|
tstados=Z80free_ustep(&procesador);
|
||||||
|
if(tstados<0) {
|
||||||
|
printf("Error %X\n",procesador.PC);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
emulate(tstados); // execute the whole hardware emulation for that number of TSTATES
|
||||||
|
} while(procesador.Status!=Z80XX);
|
||||||
|
|
||||||
|
PC=procesador.PC;
|
||||||
|
|
||||||
|
/* if PC is 0x0556, a call to LD_BYTES has been made, so if
|
||||||
|
FAST_LOAD is 1, we must load the block in memory and return */
|
||||||
|
|
||||||
|
if((!ordenador.mdr_paged)&&(PC==0x0556) && (ordenador.tape_fast_load==1)&&(ordenador.tape_file_type==TAP_TAP)) {
|
||||||
|
if(ordenador.tap_file!=NULL)
|
||||||
|
fastload_block(ordenador.tap_file);
|
||||||
|
else {
|
||||||
|
sprintf(ordenador.osd_text,"No TAP file selected");
|
||||||
|
ordenador.osd_time=50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if PC is 0x04C2, a call to SA_BYTES has been made, so if
|
||||||
|
we want to save to the TAP file, we do it */
|
||||||
|
|
||||||
|
if((!ordenador.mdr_paged)&&(PC==0x04C2)&&(ordenador.tape_write==1)&&(ordenador.tape_file_type==TAP_TAP)) {
|
||||||
|
if(ordenador.tap_file!=NULL)
|
||||||
|
save_file(ordenador.tap_file);
|
||||||
|
else {
|
||||||
|
sprintf(ordenador.osd_text,"No TAP file selected");
|
||||||
|
ordenador.osd_time=50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if ordenador.mdr_paged is 2, we have executed the RET at 0x0700, so
|
||||||
|
we have to return to the classic ROM */
|
||||||
|
|
||||||
|
if(ordenador.mdr_paged==2)
|
||||||
|
ordenador.mdr_paged=0;
|
||||||
|
|
||||||
|
/* if PC is 0x0008 or 0x1708, and we have a microdrive, we have to page
|
||||||
|
the Interface 1 ROM */
|
||||||
|
|
||||||
|
if(((PC==0x0008)||(PC==0x1708))&&(ordenador.mdr_active))
|
||||||
|
ordenador.mdr_paged = 1;
|
||||||
|
|
||||||
|
/* if PC is 0x0700 and we have a microdrive, we have to unpage
|
||||||
|
the Interface 1 ROM after the last instruction */
|
||||||
|
|
||||||
|
if((PC==0x0700)&&(ordenador.mdr_active))
|
||||||
|
ordenador.mdr_paged = 2;
|
||||||
|
|
||||||
|
if(ordenador.interr==1) {
|
||||||
|
read_keyboard (NULL); // read the physical keyboard
|
||||||
|
Z80free_INT(&procesador,bus_empty());
|
||||||
|
ordenador.interr=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_config(&ordenador);
|
||||||
|
return 0;
|
||||||
|
}
|
45
src/emulator.h
Normal file
45
src/emulator.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "z80free/Z80free.h"
|
||||||
|
#include "computer.h"
|
||||||
|
|
||||||
|
#ifndef emulator_h
|
||||||
|
#define emulator_h
|
||||||
|
|
||||||
|
#define NUM_SNDBUF 2
|
||||||
|
|
||||||
|
extern char debug_var;
|
||||||
|
|
||||||
|
extern SDL_Surface *screen;
|
||||||
|
extern Z80FREE procesador;
|
||||||
|
extern struct computer ordenador;
|
||||||
|
extern unsigned char *sound[NUM_SNDBUF];
|
||||||
|
extern char path_snaps[2049];
|
||||||
|
extern char path_taps[2049];
|
||||||
|
extern char path_mdrs[2049];
|
||||||
|
extern unsigned int colors[80];
|
||||||
|
extern unsigned int jump_frames,curr_frames;
|
||||||
|
|
||||||
|
void SDL_Fullscreen_Switch(void);
|
||||||
|
void load_rom(char);
|
||||||
|
void load_main_game(char *nombre);
|
||||||
|
FILE *myfopen(char *filename,char *mode);
|
||||||
|
|
||||||
|
#endif
|
1949
src/menus.c
Normal file
1949
src/menus.c
Normal file
File diff suppressed because it is too large
Load Diff
53
src/menus.h
Normal file
53
src/menus.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2011 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct fichero {
|
||||||
|
char nombre[256]; // filename (for files and directories)
|
||||||
|
char nombrepath[2049]; // filename with path
|
||||||
|
int tipo; // file type (0=file, 1=directory, 2=parent directory)
|
||||||
|
struct fichero *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LOAD_FILE_TYPES {FILETYPE_Z80, FILETYPE_TAP_TZX, FILETYPE_MDR, FILETYPE_SCR};
|
||||||
|
|
||||||
|
void clean_screen();
|
||||||
|
void help_menu();
|
||||||
|
void load_z80file();
|
||||||
|
char *select_file(char *,enum LOAD_FILE_TYPES);
|
||||||
|
struct fichero *read_directory(char *,enum LOAD_FILE_TYPES);
|
||||||
|
unsigned int wait_key();
|
||||||
|
void print_files(struct fichero *,int,int);
|
||||||
|
void delete_filelist(struct fichero *);
|
||||||
|
void select_tapfile();
|
||||||
|
void save_z80file();
|
||||||
|
void settings_menu();
|
||||||
|
void snapshots_menu();
|
||||||
|
void taps_menu();
|
||||||
|
void create_tapfile();
|
||||||
|
void select_mdrfile();
|
||||||
|
void create_mdrfile();
|
||||||
|
void microdrive_menu();
|
||||||
|
void keyboard_menu();
|
||||||
|
void load_scrfile();
|
||||||
|
int ask_filename(char *nombre,int y_coord,char *extension);
|
||||||
|
void create_scrfile();
|
||||||
|
void do_poke();
|
||||||
|
int ask_value(int *final_value,int y_coord,int max_value);
|
||||||
|
void tools_menu();
|
||||||
|
int launch_menu(unsigned int key_pressed);
|
176
src/microdrive.c
Normal file
176
src/microdrive.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "microdrive.h"
|
||||||
|
#include "computer.h"
|
||||||
|
#include "emulator.h"
|
||||||
|
|
||||||
|
byte basura;
|
||||||
|
|
||||||
|
void microdrive_init() {
|
||||||
|
|
||||||
|
int bucle;
|
||||||
|
|
||||||
|
basura = 0;
|
||||||
|
|
||||||
|
ordenador.mdr_active = 0;
|
||||||
|
ordenador.mdr_paged = 0;
|
||||||
|
|
||||||
|
for(bucle=0;bucle<137922;bucle++)
|
||||||
|
ordenador.mdr_cartridge[bucle]=0xFF; // cartridge erased
|
||||||
|
ordenador.mdr_cartridge[137922]=0; // but not write-protected
|
||||||
|
|
||||||
|
ordenador.mdr_tapehead=0;
|
||||||
|
ordenador.mdr_drive=0; // no motor on
|
||||||
|
ordenador.mdr_old_STATUS=0x00; // default -> no down edge
|
||||||
|
ordenador.mdr_modified=0; // not modified
|
||||||
|
ordenador.mdr_current_mdr[0]=0; // no cartridge
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void microdrive_reset() {
|
||||||
|
|
||||||
|
ordenador.mdr_gap = 15;
|
||||||
|
ordenador.mdr_nogap = 15;
|
||||||
|
ordenador.mdr_tapehead = 0; // head is at start position
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void microdrive_emulate(int tstados) {
|
||||||
|
// still nothing to do here
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
byte microdrive_in(word Port) {
|
||||||
|
|
||||||
|
byte retorno;
|
||||||
|
|
||||||
|
/* allow access to the port only if motor 1 is ON and there's a file open */
|
||||||
|
|
||||||
|
if(((Port|0xFFE7)==0xFFE7)&&(ordenador.mdr_drive==0x01)&&(ordenador.mdr_current_mdr[0])) {
|
||||||
|
if(ordenador.mdr_bytes<ordenador.mdr_maxbytes) {
|
||||||
|
retorno=ordenador.mdr_cartridge[ordenador.mdr_tapehead];
|
||||||
|
basura=retorno;
|
||||||
|
increment_head();
|
||||||
|
} else {
|
||||||
|
retorno = basura;
|
||||||
|
}
|
||||||
|
ordenador.mdr_bytes++;
|
||||||
|
return (retorno);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((Port|0xFFE7)==0xFFEF) {
|
||||||
|
if((ordenador.mdr_drive==0x01)&&(ordenador.mdr_current_mdr[0])) { // motor 1 ON and file selected
|
||||||
|
if(ordenador.mdr_gap) {
|
||||||
|
retorno=0xFE; // GAP and SYNC high
|
||||||
|
ordenador.mdr_gap--;
|
||||||
|
} else {
|
||||||
|
retorno=0xF8; // GAP and SYNC low
|
||||||
|
if(ordenador.mdr_nogap)
|
||||||
|
ordenador.mdr_nogap--;
|
||||||
|
else {
|
||||||
|
ordenador.mdr_gap=15;
|
||||||
|
ordenador.mdr_nogap=15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!ordenador.mdr_cartridge[137922]) // if write protected
|
||||||
|
retorno|=0x01; // active bit
|
||||||
|
} else // motor 1 OFF
|
||||||
|
retorno=0xFF;
|
||||||
|
|
||||||
|
microdrive_restart();
|
||||||
|
return (retorno);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Port|0xFFE7)==0xFFF7) {
|
||||||
|
microdrive_restart();
|
||||||
|
return (0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0xFF);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void microdrive_out(word Port,byte Value) {
|
||||||
|
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
/* allow access to the port only if motor 1 is ON and there's a file open */
|
||||||
|
|
||||||
|
if(((Port|0xFFE7)==0xFFE7)&&(ordenador.mdr_drive==0x01)&&(ordenador.mdr_current_mdr[0])) {
|
||||||
|
if((ordenador.mdr_bytes>11)&&(ordenador.mdr_bytes<(ordenador.mdr_maxbytes+12))) {
|
||||||
|
ordenador.mdr_cartridge[ordenador.mdr_tapehead]=(unsigned int) Value;
|
||||||
|
increment_head();
|
||||||
|
ordenador.mdr_modified=1;
|
||||||
|
}
|
||||||
|
ordenador.mdr_bytes++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((Port|0xFFE7)==0xFFEF) {
|
||||||
|
if(((Value&0x02)==0)&&((ordenador.mdr_old_STATUS&0x02)==2)) { // edge down-> new bit for motor ON
|
||||||
|
ordenador.mdr_drive=((ordenador.mdr_drive<<1)&0xFE); // rotate one drive
|
||||||
|
if(!(Value&0x01)) // if COM DATA is 0, we add a 1 bit to mdr_drive
|
||||||
|
ordenador.mdr_drive|=0x01;
|
||||||
|
|
||||||
|
if(ordenador.mdr_modified) { // if the cartridge has been modified, we store it in hard disk
|
||||||
|
ordenador.mdr_file=fopen(ordenador.mdr_current_mdr,"wb"); // create for write
|
||||||
|
if(ordenador.mdr_file==NULL) {
|
||||||
|
sprintf(ordenador.osd_text,"Can't store the cartridge");
|
||||||
|
ordenador.osd_time=150;
|
||||||
|
} else {
|
||||||
|
retval=fwrite(ordenador.mdr_cartridge,137923,1,ordenador.mdr_file); // save cartridge
|
||||||
|
fclose(ordenador.mdr_file);
|
||||||
|
ordenador.mdr_file=NULL;
|
||||||
|
ordenador.mdr_modified=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ordenador.mdr_old_STATUS=Value;
|
||||||
|
microdrive_restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Port|0xFFE7)==0xFFF7) {
|
||||||
|
microdrive_restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment_head() { // gets the tape head to the next byte
|
||||||
|
|
||||||
|
ordenador.mdr_tapehead++;
|
||||||
|
if(ordenador.mdr_tapehead>137921)
|
||||||
|
ordenador.mdr_tapehead=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void microdrive_restart() { // there's an access to a port. Reset counters and relocate the head
|
||||||
|
|
||||||
|
//printf("Inicializado\n");
|
||||||
|
|
||||||
|
while(((ordenador.mdr_tapehead%543)!=0)&&((ordenador.mdr_tapehead%543)!=15))
|
||||||
|
increment_head(); // put head in the start of a block
|
||||||
|
|
||||||
|
ordenador.mdr_bytes = 0; // reset current number of bytes written
|
||||||
|
if((ordenador.mdr_tapehead%543)==0)
|
||||||
|
ordenador.mdr_maxbytes = 15; // up to 15 bytes for header blocks
|
||||||
|
else
|
||||||
|
ordenador.mdr_maxbytes = 528; // up to 528 bytes for data blocks
|
||||||
|
|
||||||
|
}
|
33
src/microdrive.h
Normal file
33
src/microdrive.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef H_MICRODRIVE
|
||||||
|
#define H_MICRODRIVE
|
||||||
|
|
||||||
|
#include "z80free/Z80free.h"
|
||||||
|
|
||||||
|
void microdrive_init();
|
||||||
|
void microdrive_reset();
|
||||||
|
byte microdrive_in(word);
|
||||||
|
void microdrive_out(word,byte);
|
||||||
|
void microdrive_emulate(int);
|
||||||
|
void increment_head();
|
||||||
|
void microdrive_restart();
|
||||||
|
|
||||||
|
#endif
|
476
src/sound.c
Normal file
476
src/sound.c
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "z80free/Z80free.h"
|
||||||
|
#include "computer.h"
|
||||||
|
#include "emulator.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
char tabla[1024];
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#ifndef GEKKO
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
extern FILE *fdebug;
|
||||||
|
#define printf(...) fprintf(fdebug,__VA_ARGS__); fflush (fdebug)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*#include <SDL/SDL.h>
|
||||||
|
#include "SDL/SDL_audio.h"
|
||||||
|
#include "SDL_thread.h"*/
|
||||||
|
|
||||||
|
#include "sound.h"
|
||||||
|
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
#include <sys/soundcard.h>
|
||||||
|
int audio_fd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||||
|
#define ALSA_PCM_NEW_SW_PARAMS_API
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
int started_sound;
|
||||||
|
snd_pcm_t * _soundDevice;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
#include <pulse/simple.h>
|
||||||
|
pa_simple *pulse_s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum e_soundtype sound_type;
|
||||||
|
|
||||||
|
int sound_init() {
|
||||||
|
|
||||||
|
if (sound_type!=SOUND_AUTOMATIC) {
|
||||||
|
switch(sound_type) {
|
||||||
|
case SOUND_NO: // No sound; simulate 8bits mono
|
||||||
|
printf("No Sound\n");
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=0;
|
||||||
|
ordenador.channels=1;
|
||||||
|
ordenador.channels = 1;
|
||||||
|
ordenador.freq=48000;
|
||||||
|
ordenador.buffer_len=4800; // will wait 1/10 second
|
||||||
|
return (0);
|
||||||
|
break;
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
case SOUND_PULSEAUDIO:
|
||||||
|
printf("Trying PulseAudio\n");
|
||||||
|
if(0==sound_init_pulse()) {
|
||||||
|
sound_type=SOUND_PULSEAUDIO;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("Failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
case SOUND_ALSA:
|
||||||
|
printf("Trying ALSA sound\n");
|
||||||
|
if(0==sound_init_alsa()) {
|
||||||
|
sound_type=SOUND_ALSA;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("Failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
case SOUND_OSS:
|
||||||
|
printf("Trying OSS sound\n");
|
||||||
|
if(0==sound_init_oss()) {
|
||||||
|
sound_type=SOUND_OSS;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("Failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
printf("Trying PulseAudio\n");
|
||||||
|
if(0==sound_init_pulse()) {
|
||||||
|
sound_type=SOUND_PULSEAUDIO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
printf("Trying ALSA sound\n");
|
||||||
|
if(0==sound_init_alsa()) {
|
||||||
|
sound_type=SOUND_ALSA;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
printf("Trying OSS sound\n");
|
||||||
|
if(0==sound_init_oss()) {
|
||||||
|
sound_type=SOUND_OSS;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
int sound_init_pulse() {
|
||||||
|
|
||||||
|
pa_sample_spec ss;
|
||||||
|
pa_buffer_attr buf;
|
||||||
|
|
||||||
|
ss.format = PA_SAMPLE_U8;
|
||||||
|
ss.channels = 1;
|
||||||
|
ss.rate = 48000;
|
||||||
|
|
||||||
|
buf.maxlength=8192;
|
||||||
|
buf.tlength=4096;
|
||||||
|
buf.prebuf=4096;
|
||||||
|
buf.minreq=4096;
|
||||||
|
buf.fragsize=4096;
|
||||||
|
|
||||||
|
pulse_s = pa_simple_new(NULL,"fbzx",PA_STREAM_PLAYBACK,NULL,"Spectrum",&ss,NULL,&buf,NULL);
|
||||||
|
if (pulse_s==NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=0;
|
||||||
|
ordenador.channels=1;
|
||||||
|
ordenador.freq=48000;
|
||||||
|
ordenador.buffer_len=4096;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
int sound_init_alsa() {
|
||||||
|
|
||||||
|
int err;
|
||||||
|
snd_pcm_hw_params_t *hw_params;
|
||||||
|
|
||||||
|
unsigned int resample,samplerate;
|
||||||
|
snd_pcm_uframes_t bufferSize;
|
||||||
|
|
||||||
|
err = snd_pcm_open( &_soundDevice, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0 );
|
||||||
|
if (err<0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
|
||||||
|
snd_pcm_close (_soundDevice);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = snd_pcm_hw_params_any (_soundDevice, hw_params)) < 0) {
|
||||||
|
snd_pcm_close (_soundDevice);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((err = snd_pcm_hw_params_set_access (_soundDevice, hw_params,SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
|
||||||
|
snd_pcm_close (_soundDevice);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_U8) >= 0) {
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=0;
|
||||||
|
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_S8) >= 0) {
|
||||||
|
ordenador.sign=-128;
|
||||||
|
ordenador.format=0;
|
||||||
|
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_U16_LE) >= 0) {
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=1;
|
||||||
|
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_S16_LE) >= 0) {
|
||||||
|
ordenador.sign=-128;
|
||||||
|
ordenador.format=1;
|
||||||
|
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_U16_BE) >= 0) {
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=2;
|
||||||
|
} else if (snd_pcm_hw_params_set_format (_soundDevice, hw_params,SND_PCM_FORMAT_S16_BE) >= 0) {
|
||||||
|
ordenador.sign=-128;
|
||||||
|
ordenador.format=2;
|
||||||
|
} else {
|
||||||
|
snd_pcm_close (_soundDevice);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable resampling.
|
||||||
|
resample = 0;
|
||||||
|
err = snd_pcm_hw_params_set_rate_resample(_soundDevice, hw_params, resample);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_pcm_close (_soundDevice);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = snd_pcm_hw_params_set_channels (_soundDevice, hw_params, 1)) >= 0) {
|
||||||
|
ordenador.channels=1;
|
||||||
|
} else if ((err = snd_pcm_hw_params_set_channels (_soundDevice, hw_params, 2)) >= 0) {
|
||||||
|
ordenador.channels=2;
|
||||||
|
} else {
|
||||||
|
snd_pcm_close (_soundDevice);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
samplerate=48000;
|
||||||
|
if ((err = snd_pcm_hw_params_set_rate_near (_soundDevice, hw_params, &samplerate, 0)) < 0) {
|
||||||
|
snd_pcm_close (_soundDevice);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferSize=4096;
|
||||||
|
if (snd_pcm_hw_params_set_buffer_size_near(_soundDevice, hw_params, &bufferSize) < 0) {
|
||||||
|
fprintf(stderr, "Error setting buffersize.\n");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
ordenador.freq=samplerate;
|
||||||
|
|
||||||
|
err = snd_pcm_hw_params (_soundDevice, hw_params);
|
||||||
|
if (err<0) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
//snd_pcm_hw_params_get_buffer_size( hw_params, &bufferSize );
|
||||||
|
|
||||||
|
ordenador.buffer_len=bufferSize;
|
||||||
|
|
||||||
|
started_sound=0;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err = snd_pcm_prepare (_soundDevice);
|
||||||
|
if (err<0) {
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
int sound_init_oss() {
|
||||||
|
|
||||||
|
int parameter;
|
||||||
|
int parameter2;
|
||||||
|
int bytes,stereo;
|
||||||
|
int retval;
|
||||||
|
audio_buf_info bi;
|
||||||
|
|
||||||
|
audio_fd=open("/dev/dsp",O_WRONLY); // open DSP
|
||||||
|
if(audio_fd==-1) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=0;
|
||||||
|
bytes=1;
|
||||||
|
ordenador.channels=1;
|
||||||
|
ordenador.freq=22050;
|
||||||
|
ordenador.buffer_len=2048/(ordenador.channels*bytes);
|
||||||
|
|
||||||
|
parameter=0x0002000C ; // two buffers with 4096 bytes each one
|
||||||
|
|
||||||
|
if(ioctl(audio_fd,SNDCTL_DSP_SETFRAGMENT, ¶meter)==-1)
|
||||||
|
return (-6);
|
||||||
|
|
||||||
|
// set format
|
||||||
|
|
||||||
|
if(ioctl(audio_fd,SNDCTL_DSP_GETFMTS, ¶meter2)==-1)
|
||||||
|
return (-2);
|
||||||
|
parameter = 2; // we want mono audio
|
||||||
|
if(ioctl(audio_fd,SNDCTL_DSP_CHANNELS, ¶meter)==-1)
|
||||||
|
return (-4);
|
||||||
|
|
||||||
|
ordenador.channels = parameter;
|
||||||
|
|
||||||
|
// Priority: U8, S8, U16LE, S16LE, U16BE, U16LE
|
||||||
|
|
||||||
|
if(parameter2 & AFMT_S16_BE) {
|
||||||
|
parameter = AFMT_S16_BE;
|
||||||
|
}
|
||||||
|
if(parameter2 & AFMT_U16_BE){
|
||||||
|
parameter = AFMT_U16_BE;
|
||||||
|
}
|
||||||
|
if(parameter2 & AFMT_S16_LE) {
|
||||||
|
parameter = AFMT_S16_LE;
|
||||||
|
}
|
||||||
|
if(parameter2 & AFMT_U16_LE) {
|
||||||
|
parameter = AFMT_U16_LE;
|
||||||
|
}
|
||||||
|
if(parameter2 & AFMT_S8) {
|
||||||
|
parameter = AFMT_S8;
|
||||||
|
}
|
||||||
|
if(parameter2 & AFMT_U8) {
|
||||||
|
parameter = AFMT_U8;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes=0; //8 bits
|
||||||
|
stereo=0; // no stereo
|
||||||
|
|
||||||
|
retval=ioctl(audio_fd,SNDCTL_DSP_SETFMT,¶meter);
|
||||||
|
if(retval != 0) {
|
||||||
|
return (-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(parameter) {
|
||||||
|
case AFMT_U8:
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=0;
|
||||||
|
bytes=1;
|
||||||
|
break;
|
||||||
|
case AFMT_S8:
|
||||||
|
ordenador.sign=-128;
|
||||||
|
ordenador.format=0;
|
||||||
|
bytes=1;
|
||||||
|
break;
|
||||||
|
case AFMT_U16_LE:
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=1;
|
||||||
|
bytes=2;
|
||||||
|
break;
|
||||||
|
case AFMT_S16_LE:
|
||||||
|
ordenador.sign=-128;
|
||||||
|
ordenador.format=1;
|
||||||
|
bytes=2;
|
||||||
|
break;
|
||||||
|
case AFMT_U16_BE:
|
||||||
|
ordenador.sign=0;
|
||||||
|
ordenador.format=2;
|
||||||
|
bytes=2;
|
||||||
|
break;
|
||||||
|
case AFMT_S16_BE:
|
||||||
|
ordenador.sign=-128;
|
||||||
|
ordenador.format=2;
|
||||||
|
bytes=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter=48000; // we want, by default, 48000 samples per second
|
||||||
|
if(ioctl(audio_fd,SNDCTL_DSP_SPEED, ¶meter)==-1)
|
||||||
|
return (-5);
|
||||||
|
ordenador.freq=parameter;
|
||||||
|
|
||||||
|
if(ioctl(audio_fd,SNDCTL_DSP_GETOSPACE, &bi)==-1)
|
||||||
|
return (-6);
|
||||||
|
|
||||||
|
parameter=bi.bytes/4;
|
||||||
|
ordenador.buffer_len=parameter/(ordenador.channels*bytes);
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void sound_remove_dc(unsigned char *sound_buffer,int size){
|
||||||
|
static float oldsample=0.0;
|
||||||
|
static float origsample;
|
||||||
|
static int i;
|
||||||
|
|
||||||
|
for (i=0;i<size;i++) {
|
||||||
|
origsample=((float)(sound_buffer[i]))-128;
|
||||||
|
oldsample=(origsample+oldsample*999.0)*0.001+1e-6;
|
||||||
|
sound_buffer[i]=(int)(origsample-oldsample)*0.98+128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_play() {
|
||||||
|
|
||||||
|
|
||||||
|
static int retval,retval2;
|
||||||
|
|
||||||
|
ordenador.current_buffer=sound[0];
|
||||||
|
//remove_dc(ordenador.current_buffer,ordenador.buffer_len);
|
||||||
|
|
||||||
|
switch(sound_type) {
|
||||||
|
case SOUND_NO: // no sound
|
||||||
|
usleep(75000); // wait 1/20 second
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
case SOUND_OSS: // OSS
|
||||||
|
retval=write(audio_fd,ordenador.current_buffer,ordenador.buffer_len*ordenador.increment);
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
case SOUND_ALSA: // ALSA
|
||||||
|
if (started_sound==0) {
|
||||||
|
snd_pcm_prepare (_soundDevice);
|
||||||
|
started_sound=1;
|
||||||
|
}
|
||||||
|
retval=snd_pcm_writei(_soundDevice,sound[0],ordenador.buffer_len);
|
||||||
|
if (retval<0) {
|
||||||
|
retval=snd_pcm_prepare(_soundDevice);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
case SOUND_PULSEAUDIO: // PulseAudio
|
||||||
|
// Remove the DC component to avoid losing the sound when multiplexing with other sources
|
||||||
|
sound_remove_dc(ordenador.current_buffer,ordenador.buffer_len);
|
||||||
|
retval=pa_simple_write(pulse_s,sound[0],ordenador.buffer_len,&retval2);
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sound_close() {
|
||||||
|
|
||||||
|
switch(sound_type) {
|
||||||
|
case SOUND_NO:
|
||||||
|
break;
|
||||||
|
#ifdef D_SOUND_OSS
|
||||||
|
case SOUND_OSS:
|
||||||
|
close(audio_fd);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_ALSA
|
||||||
|
case SOUND_ALSA:
|
||||||
|
snd_pcm_drain (_soundDevice);
|
||||||
|
snd_pcm_close (_soundDevice);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef D_SOUND_PULSE
|
||||||
|
case SOUND_PULSEAUDIO:
|
||||||
|
pa_simple_free(pulse_s);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
39
src/sound.h
Normal file
39
src/sound.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SOUND_H
|
||||||
|
#define SOUND_H
|
||||||
|
|
||||||
|
enum e_soundtype {SOUND_NO, SOUND_OSS, SOUND_ALSA, SOUND_PULSEAUDIO, SOUND_AUTOMATIC};
|
||||||
|
|
||||||
|
extern enum e_soundtype sound_type;
|
||||||
|
|
||||||
|
int sound_init();
|
||||||
|
void sound_play();
|
||||||
|
void sound_close();
|
||||||
|
|
||||||
|
extern volatile unsigned char *sdl_sound_buffer;
|
||||||
|
|
||||||
|
int sound_init_oss();
|
||||||
|
int sound_init_alsa();
|
||||||
|
int sound_init_pulse();
|
||||||
|
|
||||||
|
void sdlcallback(void *userdata, Uint8 *stream, int len);
|
||||||
|
|
||||||
|
#endif
|
337
src/spk_ay.c
Normal file
337
src/spk_ay.c
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "emulator.h"
|
||||||
|
#include "sound.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* emulates the AY-3-8912 during TSTADOS tstates */
|
||||||
|
|
||||||
|
inline void play_ay (unsigned int tstados) {
|
||||||
|
|
||||||
|
if (!ordenador.ay_emul)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ordenador.tst_ay += tstados;
|
||||||
|
ordenador.tst_ay2 += tstados;
|
||||||
|
|
||||||
|
if (ordenador.tst_ay2 > 255) {
|
||||||
|
ordenador.tst_ay2 -= 256;
|
||||||
|
if ((ordenador.ay_registers[11])
|
||||||
|
|| (ordenador.ay_registers[12])) {
|
||||||
|
if (ordenador.aych_envel)
|
||||||
|
ordenador.aych_envel--;
|
||||||
|
else {
|
||||||
|
ordenador.aych_envel = (((unsigned int) ordenador.ay_registers[11]) + 256 * ((unsigned int) (ordenador.ay_registers[12])));
|
||||||
|
if (ordenador.ay_envel_way & 0x02) // start cycle?
|
||||||
|
switch ((ordenador.
|
||||||
|
ay_registers[13]) & 0x0F)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
ordenador.ay_envel_way = 4; // cycle started and decrementing
|
||||||
|
ordenador.ay_envel_value = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ordenador.ay_envel_way = 5; // cycle started and incrementing
|
||||||
|
ordenador.ay_envel_value = -1;
|
||||||
|
}
|
||||||
|
if (ordenador.ay_envel_way & 0x04)
|
||||||
|
{ // cycle started?
|
||||||
|
switch ((ordenador.
|
||||||
|
ay_registers[13]) & 0x0F)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 9:
|
||||||
|
ordenador.ay_envel_value--;
|
||||||
|
if (ordenador.
|
||||||
|
ay_envel_value == 0)
|
||||||
|
ordenador.ay_envel_way = 0; // end
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
case 15:
|
||||||
|
ordenador.ay_envel_value++;
|
||||||
|
if (ordenador.
|
||||||
|
ay_envel_value == 16)
|
||||||
|
{
|
||||||
|
ordenador.
|
||||||
|
ay_envel_value
|
||||||
|
= 0;
|
||||||
|
ordenador.ay_envel_way = 0; // end
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
ordenador.ay_envel_value--;
|
||||||
|
if (ordenador.ay_envel_value == -1)
|
||||||
|
ordenador.ay_envel_value = 15; // repeat
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
case 14:
|
||||||
|
if (ordenador.ay_envel_way & 0x01)
|
||||||
|
ordenador.ay_envel_value++;
|
||||||
|
else
|
||||||
|
ordenador.ay_envel_value--;
|
||||||
|
if (ordenador.ay_envel_value == 16) {
|
||||||
|
ordenador.ay_envel_value = 14;
|
||||||
|
ordenador.ay_envel_way =4;
|
||||||
|
}
|
||||||
|
if (ordenador.ay_envel_value == -1) {
|
||||||
|
ordenador.ay_envel_value = 1;
|
||||||
|
ordenador.ay_envel_way = 5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 11:
|
||||||
|
ordenador.ay_envel_value--;
|
||||||
|
if (ordenador.ay_envel_value == -1) {
|
||||||
|
ordenador.ay_envel_value = 15;
|
||||||
|
ordenador.ay_envel_way = 0; // end
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 12:
|
||||||
|
ordenador.ay_envel_value++;
|
||||||
|
if (ordenador.ay_envel_value == 16)
|
||||||
|
ordenador.ay_envel_value = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 13:
|
||||||
|
ordenador.ay_envel_value++;
|
||||||
|
if (ordenador.ay_envel_value == 15)
|
||||||
|
ordenador.ay_envel_way = 0; // end
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ordenador.ay_envel_value = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ordenador.tst_ay >= 16)
|
||||||
|
{
|
||||||
|
ordenador.tst_ay -= 16;
|
||||||
|
|
||||||
|
if ((ordenador.ay_registers[0])
|
||||||
|
|| (ordenador.ay_registers[1]))
|
||||||
|
{
|
||||||
|
if (ordenador.aych_a)
|
||||||
|
ordenador.aych_a--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ordenador.ayval_a = 1 - ordenador.ayval_a;
|
||||||
|
ordenador.aych_a =
|
||||||
|
(((unsigned int) ordenador.
|
||||||
|
ay_registers[0]) +
|
||||||
|
256 *
|
||||||
|
((unsigned
|
||||||
|
int) ((ordenador.
|
||||||
|
ay_registers[1]) & 0x0F))) /
|
||||||
|
2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ordenador.ayval_a = 0;
|
||||||
|
|
||||||
|
if ((ordenador.ay_registers[2])
|
||||||
|
|| (ordenador.ay_registers[3]))
|
||||||
|
{
|
||||||
|
if (ordenador.aych_b)
|
||||||
|
ordenador.aych_b--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ordenador.ayval_b = 1 - ordenador.ayval_b;
|
||||||
|
ordenador.aych_b =
|
||||||
|
(((unsigned int) ordenador.
|
||||||
|
ay_registers[2]) +
|
||||||
|
256 *
|
||||||
|
((unsigned
|
||||||
|
int) ((ordenador.
|
||||||
|
ay_registers[3]) & 0x0F))) /
|
||||||
|
2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ordenador.ayval_b = 0;
|
||||||
|
|
||||||
|
if ((ordenador.ay_registers[4])
|
||||||
|
|| (ordenador.ay_registers[5]))
|
||||||
|
{
|
||||||
|
if (ordenador.aych_c)
|
||||||
|
ordenador.aych_c--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ordenador.ayval_c = 1 - ordenador.ayval_c;
|
||||||
|
ordenador.aych_c =
|
||||||
|
(((unsigned int) ordenador.
|
||||||
|
ay_registers[4]) +
|
||||||
|
256 *
|
||||||
|
((unsigned
|
||||||
|
int) ((ordenador.
|
||||||
|
ay_registers[5]) & 0x0F))) /
|
||||||
|
2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ordenador.ayval_c = 0;
|
||||||
|
|
||||||
|
if (ordenador.ay_registers[6])
|
||||||
|
{
|
||||||
|
if (ordenador.aych_n)
|
||||||
|
ordenador.aych_n--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ordenador.ayval_n = 1 - ordenador.ayval_n;
|
||||||
|
ordenador.aych_n =
|
||||||
|
((((unsigned int) ordenador.
|
||||||
|
ay_registers[6]) & 0x1F) +
|
||||||
|
(rand () % 3)) / 2;
|
||||||
|
if (ordenador.aych_n > 16)
|
||||||
|
ordenador.aych_n = 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ordenador.ayval_n = 0;
|
||||||
|
|
||||||
|
if (ordenador.ay_registers[8] & 0x10)
|
||||||
|
ordenador.vol_a =
|
||||||
|
(unsigned
|
||||||
|
char) ((((unsigned int) ordenador.
|
||||||
|
ay_envel_value)) *
|
||||||
|
(unsigned int) ordenador.volume) / 15;
|
||||||
|
else
|
||||||
|
ordenador.vol_a =
|
||||||
|
(unsigned
|
||||||
|
char) ((((unsigned int) (ordenador.
|
||||||
|
ay_registers[8] &
|
||||||
|
0x0F)) *
|
||||||
|
(unsigned int) ordenador.volume) /
|
||||||
|
15);
|
||||||
|
|
||||||
|
if (ordenador.ay_registers[10] & 0x10)
|
||||||
|
ordenador.vol_c =
|
||||||
|
(unsigned
|
||||||
|
char) ((((unsigned int) ordenador.
|
||||||
|
ay_envel_value)) *
|
||||||
|
(unsigned int) ordenador.volume) / 15;
|
||||||
|
else
|
||||||
|
ordenador.vol_c =
|
||||||
|
(unsigned
|
||||||
|
char) ((((unsigned int) (ordenador.
|
||||||
|
ay_registers[10] &
|
||||||
|
0x0F)) *
|
||||||
|
(unsigned int) ordenador.volume) /
|
||||||
|
15);
|
||||||
|
|
||||||
|
if (ordenador.ay_registers[9] & 0x10)
|
||||||
|
ordenador.vol_b =
|
||||||
|
(unsigned
|
||||||
|
char) ((((unsigned int) ordenador.
|
||||||
|
ay_envel_value)) *
|
||||||
|
(unsigned int) ordenador.volume) / 15;
|
||||||
|
else
|
||||||
|
ordenador.vol_b =
|
||||||
|
(unsigned
|
||||||
|
char) ((((unsigned int) (ordenador.
|
||||||
|
ay_registers[9] &
|
||||||
|
0x0F)) *
|
||||||
|
(unsigned int) ordenador.volume) /
|
||||||
|
15);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Creates the sound buffer during the TSTADOS tstate that the Z80 used to
|
||||||
|
execute last instruction */
|
||||||
|
|
||||||
|
inline void play_sound (unsigned int tstados) {
|
||||||
|
|
||||||
|
int bucle;
|
||||||
|
int value;
|
||||||
|
unsigned char sample_v;
|
||||||
|
|
||||||
|
ordenador.tstados_counter_sound += tstados;
|
||||||
|
|
||||||
|
while (ordenador.tstados_counter_sound >= ordenador.tst_sample) {
|
||||||
|
|
||||||
|
ordenador.tstados_counter_sound -= ordenador.tst_sample;
|
||||||
|
if (sound_type!=1)
|
||||||
|
for (bucle = 0; bucle < ordenador.increment; bucle++) {
|
||||||
|
sample_v = ordenador.sample1b[bucle];
|
||||||
|
if ((ordenador.sound_bit) && (sample_v)) {
|
||||||
|
ordenador.sound_current_value+=(ordenador.tst_sample/8);
|
||||||
|
if(ordenador.sound_current_value>ordenador.volume)
|
||||||
|
ordenador.sound_current_value = ordenador.volume;
|
||||||
|
} else {
|
||||||
|
if(ordenador.sound_current_value>=(ordenador.tst_sample/8))
|
||||||
|
ordenador.sound_current_value-=((ordenador.tst_sample)/8);
|
||||||
|
else
|
||||||
|
ordenador.sound_current_value = 0;
|
||||||
|
}
|
||||||
|
value = ordenador.sound_current_value;
|
||||||
|
if (ordenador.ay_emul) { // if emulation is ON, emulate it
|
||||||
|
if ((ordenador.ayval_a) && (sample_v)
|
||||||
|
&& (!(ordenador.ay_registers[7] & 0x01)))
|
||||||
|
value += (int) ordenador.vol_a;
|
||||||
|
if ((ordenador.ayval_b) && (sample_v)
|
||||||
|
&& (!(ordenador.ay_registers[7] & 0x02)))
|
||||||
|
value += (int) ordenador.vol_b;
|
||||||
|
if ((ordenador.ayval_c) && (sample_v)
|
||||||
|
&& (!(ordenador.ay_registers[7] & 0x04)))
|
||||||
|
value += (int) ordenador.vol_c;
|
||||||
|
if ((ordenador.ayval_n) && (sample_v)
|
||||||
|
&& (!(ordenador.ay_registers[7] & 0x08)))
|
||||||
|
value += (int) ordenador.vol_a;
|
||||||
|
if ((ordenador.ayval_n) && (sample_v)
|
||||||
|
&& (!(ordenador.ay_registers[7] & 0x10)))
|
||||||
|
value += (int) ordenador.vol_b;
|
||||||
|
if ((ordenador.ayval_n) && (sample_v)
|
||||||
|
&& (!(ordenador.ay_registers[7] & 0x20)))
|
||||||
|
value += (int) ordenador.vol_c;
|
||||||
|
}
|
||||||
|
if (value > 255)
|
||||||
|
value = 255;
|
||||||
|
sample_v = (char)(value - (unsigned int)ordenador.sign);
|
||||||
|
*ordenador.current_buffer = 2*sample_v;
|
||||||
|
ordenador.current_buffer++;
|
||||||
|
}
|
||||||
|
ordenador.sound_cuantity++;
|
||||||
|
|
||||||
|
if (ordenador.sound_cuantity == ordenador.buffer_len) { // buffer filled
|
||||||
|
sound_play();
|
||||||
|
ordenador.sound_cuantity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
src/spk_ay.h
Normal file
26
src/spk_ay.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef H_SPK_AY
|
||||||
|
#define H_SPK_AY
|
||||||
|
|
||||||
|
inline void play_ay (unsigned int);
|
||||||
|
inline void play_sound (unsigned int);
|
||||||
|
|
||||||
|
#endif;
|
771
src/tape.c
Normal file
771
src/tape.c
Normal file
@ -0,0 +1,771 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "z80free/Z80free.h"
|
||||||
|
#include "computer.h"
|
||||||
|
#include "emulator.h"
|
||||||
|
#include "menus.h"
|
||||||
|
#include "tape.h"
|
||||||
|
|
||||||
|
int elcontador=0;
|
||||||
|
int eltstado=0;
|
||||||
|
char elbit=0;
|
||||||
|
|
||||||
|
/* reads a tape file and updates the readed bit */
|
||||||
|
|
||||||
|
inline void tape_read(FILE *fichero, int tstados) {
|
||||||
|
|
||||||
|
if(ordenador.pause)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(ordenador.tape_file_type == TAP_TAP)
|
||||||
|
tape_read_tap(fichero,tstados);
|
||||||
|
else
|
||||||
|
tape_read_tzx(fichero,tstados);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// manages TAP files in REAL_MODE
|
||||||
|
|
||||||
|
inline void tape_read_tap (FILE * fichero, int tstados) {
|
||||||
|
|
||||||
|
static unsigned char value, value2;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (fichero == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!ordenador.pause) {
|
||||||
|
if (ordenador.tape_current_mode == TAP_TRASH) { // initialize a new block
|
||||||
|
retval=fread (&value, 1, 1, fichero);
|
||||||
|
retval=fread (&value2, 1, 1, fichero); // read block longitude
|
||||||
|
if (feof (fichero)) {
|
||||||
|
rewind_tape(fichero,1);
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2);
|
||||||
|
retval=fread (&(ordenador.tape_byte), 1, 1, fichero);
|
||||||
|
ordenador.tape_bit = 0x80;
|
||||||
|
ordenador.tape_current_mode = TAP_GUIDE;
|
||||||
|
ordenador.tape_counter0 = 2168;
|
||||||
|
ordenador.tape_counter1 = 2168;
|
||||||
|
if (!(0x80 & ordenador.tape_byte))
|
||||||
|
ordenador.tape_counter_rep = 3228; // 4 seconds
|
||||||
|
else
|
||||||
|
ordenador.tape_counter_rep = 1614; // 2 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there's a pulse still being reproduce, just reproduce it
|
||||||
|
|
||||||
|
if (ordenador.tape_counter0) {
|
||||||
|
if (ordenador.tape_counter0 > tstados) {
|
||||||
|
ordenador.tape_readed = 0; // return 0
|
||||||
|
ordenador.tape_counter0 -= tstados; // decrement counter;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
tstados -= ordenador.tape_counter0;
|
||||||
|
ordenador.tape_counter0 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ordenador.tape_readed = 1; // return 1
|
||||||
|
if (ordenador.tape_counter1) {
|
||||||
|
if (ordenador.tape_counter1 > tstados) {
|
||||||
|
ordenador.tape_counter1 -= tstados; // decrement counter;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
tstados -= ordenador.tape_counter1;
|
||||||
|
ordenador.tape_counter1 = 0;
|
||||||
|
ordenador.tape_readed = 0; // return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pulse ended
|
||||||
|
|
||||||
|
switch (ordenador.tape_current_mode) {
|
||||||
|
case TAP_GUIDE: // guide tone
|
||||||
|
if (ordenador.tape_counter_rep) { // still into guide tone
|
||||||
|
ordenador.tape_counter_rep--;
|
||||||
|
ordenador.tape_counter0 = 2168 - tstados;
|
||||||
|
ordenador.tape_counter1 = 2168; // new pulse
|
||||||
|
return;
|
||||||
|
} else { // guide tone ended. send sync tone
|
||||||
|
ordenador.tape_counter0 = 667 - tstados;
|
||||||
|
ordenador.tape_counter1 = 735; // new pulse
|
||||||
|
ordenador.tape_current_mode = TAP_DATA; // data mode
|
||||||
|
ordenador.tape_bit = 0x80; // from bit0 to bit7
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TAP_DATA: // data
|
||||||
|
if (ordenador.tape_byte & ordenador.tape_bit) { // next bit is 1
|
||||||
|
ordenador.tape_counter0 = 1710 - tstados;
|
||||||
|
ordenador.tape_counter1 = 1710;
|
||||||
|
} else {
|
||||||
|
ordenador.tape_counter0 = 851 - tstados;
|
||||||
|
ordenador.tape_counter1 = 852;
|
||||||
|
}
|
||||||
|
ordenador.tape_bit = ((ordenador.tape_bit >> 1) & 0x7F); // from bit0 to bit7
|
||||||
|
if (!ordenador.tape_bit) {
|
||||||
|
ordenador.tape_byte_counter--;
|
||||||
|
if (!ordenador.tape_byte_counter) { // ended the block
|
||||||
|
ordenador.tape_current_mode = TAP_PAUSE; // pause
|
||||||
|
ordenador.tape_readed = 0;
|
||||||
|
ordenador.tape_counter_rep = 3500000; // 1 seconds
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ordenador.tape_bit = 0x80;
|
||||||
|
retval=fread (&(ordenador.tape_byte), 1, 1, fichero); // read next byte
|
||||||
|
if (feof (fichero)) {
|
||||||
|
rewind_tape(fichero,0);
|
||||||
|
ordenador.tape_current_mode = TAP_STOP; // stop tape
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TAP_PAUSE: // pause
|
||||||
|
ordenador.tape_readed = 0;
|
||||||
|
if (ordenador.tape_counter_rep > tstados) {
|
||||||
|
ordenador.tape_counter_rep -= tstados;
|
||||||
|
} else {
|
||||||
|
ordenador.tape_counter_rep = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH; // read new block
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case TAP_STOP:
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH; // initialize
|
||||||
|
ordenador.pause = 1; // pause it
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// manages TZX files
|
||||||
|
|
||||||
|
inline void tape_read_tzx (FILE * fichero, int tstados) {
|
||||||
|
|
||||||
|
static unsigned char value, value2,value3,value4,done;
|
||||||
|
static unsigned int bucle,bucle2;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if ((fichero == NULL)||(ordenador.pause))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ordenador.tape_current_mode == TAP_TRASH) { // initialize a new block
|
||||||
|
done = 0;
|
||||||
|
do {
|
||||||
|
retval=fread(&value,1,1,fichero); // read block ID
|
||||||
|
//printf("ID: %X en %d\n",value,ftell(fichero));
|
||||||
|
if(feof(fichero))
|
||||||
|
done = 1;
|
||||||
|
else
|
||||||
|
switch(value) {
|
||||||
|
case 0x10: // classic tape block
|
||||||
|
done = 1;
|
||||||
|
bucle = 0;
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
ordenador.tape_bit0_level = 852;
|
||||||
|
ordenador.tape_bit1_level = 1710;
|
||||||
|
ordenador.tape_bits_at_end = 8;
|
||||||
|
ordenador.tape_block_level = 2168;
|
||||||
|
ordenador.tape_sync_level0 = 667;
|
||||||
|
ordenador.tape_sync_level1 = 735;
|
||||||
|
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // pause length
|
||||||
|
ordenador.tape_pause_at_end = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
if(ordenador.tape_pause_at_end==0)
|
||||||
|
ordenador.tape_pause_at_end=10; // to avoid problems
|
||||||
|
ordenador.tape_pause_at_end *= 3500;
|
||||||
|
retval=fread (&value, 1, 1, fichero);
|
||||||
|
|
||||||
|
retval=fread (&value2, 1, 1, fichero); // read block longitude
|
||||||
|
if (feof (fichero)) {
|
||||||
|
rewind_tape(fichero,1);
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH;
|
||||||
|
for(bucle=0;bucle<10;bucle++)
|
||||||
|
retval=fread(&value3,1,1,fichero); // jump over the header
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2);
|
||||||
|
retval=fread (&(ordenador.tape_byte), 1, 1, fichero);
|
||||||
|
ordenador.tape_bit = 0x80;
|
||||||
|
ordenador.tape_current_mode = TAP_GUIDE;
|
||||||
|
ordenador.tape_counter0 = 2168;
|
||||||
|
ordenador.tape_counter1 = 2168;
|
||||||
|
if (!(0x80 & ordenador.tape_byte))
|
||||||
|
ordenador.tape_counter_rep = 3228; // 4 seconds
|
||||||
|
else
|
||||||
|
ordenador.tape_counter_rep = 1614; // 2 seconds
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x11: // turbo tape block
|
||||||
|
done = 1;
|
||||||
|
bucle = 0;
|
||||||
|
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_block_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_sync_level0 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_sync_level1 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_bit0_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_bit1_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_counter_rep = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
ordenador.tape_counter_rep /=2;
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
ordenador.tape_bits_at_end = value2;
|
||||||
|
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // pause length
|
||||||
|
ordenador.tape_pause_at_end = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
|
||||||
|
|
||||||
|
if(ordenador.tape_pause_at_end==0)
|
||||||
|
ordenador.tape_pause_at_end=10; // to avoid problems
|
||||||
|
ordenador.tape_pause_at_end *= 3500;
|
||||||
|
|
||||||
|
retval=fread (&value, 1, 1, fichero);
|
||||||
|
retval=fread (&value2, 1, 1, fichero);
|
||||||
|
retval=fread (&value3, 1, 1, fichero); // read block longitude
|
||||||
|
ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2) + 65536* ((unsigned int) value3);
|
||||||
|
|
||||||
|
if (feof (fichero)) {
|
||||||
|
rewind_tape(fichero,1);
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval=fread (&(ordenador.tape_byte), 1, 1, fichero);
|
||||||
|
ordenador.tape_bit = 0x80;
|
||||||
|
ordenador.tape_current_mode = TAP_GUIDE;
|
||||||
|
ordenador.tape_counter0 = ordenador.tape_block_level;
|
||||||
|
ordenador.tape_counter1 = ordenador.tape_block_level;
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x12: // pure tone
|
||||||
|
done = 1;
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // length of pulse in T-states
|
||||||
|
ordenador.tape_block_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
ordenador.tape_counter0 = ordenador.tape_block_level;
|
||||||
|
ordenador.tape_counter1 = 0;
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // number of pulses
|
||||||
|
ordenador.tape_counter_rep = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
if(ordenador.tape_counter_rep == 0)
|
||||||
|
done = 0;
|
||||||
|
ordenador.tape_current_mode = TZX_PURE_TONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x13: // multiple pulses
|
||||||
|
done=1;
|
||||||
|
retval=fread(&value2,1,1,fichero); // number of pulses
|
||||||
|
ordenador.tape_counter_rep = ((unsigned int) value2);
|
||||||
|
if(ordenador.tape_counter_rep == 0)
|
||||||
|
done = 0;
|
||||||
|
else {
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // length of pulse in T-states
|
||||||
|
ordenador.tape_counter0 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
ordenador.tape_counter1 = 0;
|
||||||
|
ordenador.tape_current_mode = TZX_SEQ_PULSES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x14: // turbo tape block
|
||||||
|
done = 1;
|
||||||
|
bucle = 0;
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_bit0_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_bit1_level = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
ordenador.tape_bits_at_end = value2;
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // pause length
|
||||||
|
ordenador.tape_pause_at_end = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
/*if(ordenador.tape_pause_at_end==0)
|
||||||
|
ordenador.tape_pause_at_end=10;*/ // to avoid problems
|
||||||
|
ordenador.tape_pause_at_end *= 3500;
|
||||||
|
retval=fread (&value, 1, 1, fichero);
|
||||||
|
retval=fread (&value2, 1, 1, fichero);
|
||||||
|
retval=fread (&value3,1,1,fichero); // read block longitude
|
||||||
|
if (feof (fichero)) {
|
||||||
|
rewind_tape(fichero,1);
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ordenador.tape_byte_counter = ((unsigned int) value) + 256 * ((unsigned int) value2) + 65536*((unsigned int)value3);
|
||||||
|
ordenador.tape_bit = 0x80;
|
||||||
|
retval=fread (&(ordenador.tape_byte), 1, 1, fichero); // read next byte
|
||||||
|
if((ordenador.tape_byte_counter==1)&&(ordenador.tape_bits_at_end!=8)) { // last byte
|
||||||
|
for(bucle=ordenador.tape_bits_at_end;bucle<8;bucle++) {
|
||||||
|
ordenador.tape_byte=((ordenador.tape_byte>>1)&0x7F);
|
||||||
|
ordenador.tape_bit = ((ordenador.tape_bit>>1)&0x7F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ordenador.tape_current_mode = TAP_DATA;
|
||||||
|
ordenador.tape_counter0 = 0;
|
||||||
|
ordenador.tape_counter1 = 0;
|
||||||
|
ordenador.tape_counter_rep = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x20: // pause
|
||||||
|
done = 1;
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // pause length
|
||||||
|
ordenador.tape_counter_rep = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
ordenador.tape_readed = 0;
|
||||||
|
ordenador.tape_counter0 = 0;
|
||||||
|
ordenador.tape_counter1 = 0; // 1ms of inversed pulse
|
||||||
|
if(ordenador.tape_counter_rep == 0) {
|
||||||
|
ordenador.tape_current_mode = TAP_PAUSE2; // initialize
|
||||||
|
ordenador.tape_byte_counter = 31500;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ordenador.tape_counter_rep *= 3500;
|
||||||
|
ordenador.tape_current_mode = TAP_PAUSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x21: // group start
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
bucle2=(unsigned int) value2;
|
||||||
|
for(bucle=0;bucle<bucle2;bucle++)
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x22: // group end
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x24: // loop start
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
ordenador.tape_loop_counter = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
ordenador.tape_loop_pos = ftell(fichero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x25: // loop end
|
||||||
|
if(ordenador.tape_loop_counter) {
|
||||||
|
ordenador.tape_loop_counter--;
|
||||||
|
fseek(fichero,ordenador.tape_loop_pos,SEEK_SET);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x2A: // pause if 48K
|
||||||
|
if(ordenador.mode128k==0) {
|
||||||
|
ordenador.pause = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x30: // text description
|
||||||
|
retval=fread(&value2,1,1,fichero); // length
|
||||||
|
for(bucle=0;bucle<((unsigned int)value2);bucle++)
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x31: // show text
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value2,1,1,fichero); // length
|
||||||
|
for(bucle=0;bucle<((unsigned int)value2);bucle++)
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x32: // archive info
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // pause length
|
||||||
|
bucle2 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
for(bucle=0;bucle<bucle2;bucle++)
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x33: // hardware info
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
bucle2 = ((unsigned int) value2) *3;
|
||||||
|
for(bucle=0;bucle<bucle2;bucle++)
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x34: // emulation info
|
||||||
|
for(bucle=0;bucle<8;bucle++)
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x35: // custon info
|
||||||
|
for(bucle=0;bucle<10;bucle++)
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
retval=fread(&value,1,1,fichero);
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
retval=fread(&value4,1,1,fichero);
|
||||||
|
bucle2 = ((unsigned int) value) + 256 * ((unsigned int) value2) + 65536*((unsigned int) value3) + 16777216*((unsigned int) value4);
|
||||||
|
for(bucle=0;bucle<bucle2;bucle++)
|
||||||
|
retval=fread(&value3,1,1,fichero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // not supported
|
||||||
|
sprintf(ordenador.osd_text,"Unsuported TZX. Contact FBZX autor. %X",value);
|
||||||
|
ordenador.osd_time=200;
|
||||||
|
rewind_tape(fichero,1); // rewind and stop
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH;
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (!done);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feof (fichero)) {
|
||||||
|
rewind_tape(fichero,1);
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there's a pulse still being reproduced, just play it
|
||||||
|
|
||||||
|
if (ordenador.tape_counter0) {
|
||||||
|
if (ordenador.tape_counter0 > tstados) {
|
||||||
|
ordenador.tape_readed = ordenador.tape_current_bit; // return current
|
||||||
|
ordenador.tape_counter0 -= tstados; // decrement counter;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
tstados -= ordenador.tape_counter0;
|
||||||
|
ordenador.tape_counter0 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ordenador.tape_readed = 1 - ordenador.tape_current_bit; // return oposite current
|
||||||
|
if (ordenador.tape_counter1) {
|
||||||
|
if (ordenador.tape_counter1 > tstados) {
|
||||||
|
ordenador.tape_counter1 -= tstados; // decrement counter;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
tstados -= ordenador.tape_counter1;
|
||||||
|
ordenador.tape_counter1 = 0;
|
||||||
|
ordenador.tape_readed = ordenador.tape_current_bit; // return current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pulse ended
|
||||||
|
|
||||||
|
switch (ordenador.tape_current_mode) {
|
||||||
|
case TAP_FINAL_BIT:
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH;
|
||||||
|
break;
|
||||||
|
case TAP_GUIDE: // guide tone
|
||||||
|
if (ordenador.tape_counter_rep) { // still into guide tone
|
||||||
|
ordenador.tape_counter_rep--;
|
||||||
|
ordenador.tape_counter0 = ordenador.tape_block_level - tstados;
|
||||||
|
ordenador.tape_counter1 = ordenador.tape_block_level; // new pulse
|
||||||
|
return;
|
||||||
|
} else { // guide tone ended. send sync tone
|
||||||
|
ordenador.tape_counter0 = ordenador.tape_sync_level0 - tstados;
|
||||||
|
ordenador.tape_counter1 = ordenador.tape_sync_level0; // new pulse
|
||||||
|
ordenador.tape_current_mode = TAP_DATA; // data mode
|
||||||
|
ordenador.tape_bit = 0x80; // from bit0 to bit7
|
||||||
|
if((ordenador.tape_byte_counter==1)&&(ordenador.tape_bits_at_end!=8)) { // last byte
|
||||||
|
for(bucle=ordenador.tape_bits_at_end;bucle<8;bucle++) {
|
||||||
|
ordenador.tape_byte=((ordenador.tape_byte>>1)&0x7F);
|
||||||
|
ordenador.tape_bit = ((ordenador.tape_bit>>1)&0x7F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TAP_DATA: // data
|
||||||
|
if (ordenador.tape_byte & ordenador.tape_bit) { // next bit is 1
|
||||||
|
ordenador.tape_counter0 = ordenador.tape_bit1_level - tstados;
|
||||||
|
ordenador.tape_counter1 = ordenador.tape_bit1_level;
|
||||||
|
} else {
|
||||||
|
ordenador.tape_counter0 = ordenador.tape_bit0_level - tstados;
|
||||||
|
ordenador.tape_counter1 = ordenador.tape_bit0_level;
|
||||||
|
}
|
||||||
|
ordenador.tape_bit = ((ordenador.tape_bit >> 1) & 0x7F); // from bit0 to bit7
|
||||||
|
if (!ordenador.tape_bit) {
|
||||||
|
ordenador.tape_byte_counter--;
|
||||||
|
if (!ordenador.tape_byte_counter) { // ended the block
|
||||||
|
if(ordenador.tape_pause_at_end) {
|
||||||
|
ordenador.tape_current_mode = TAP_PAUSE3; // pause
|
||||||
|
ordenador.tape_counter_rep = ordenador.tape_pause_at_end;
|
||||||
|
} else
|
||||||
|
ordenador.tape_current_mode = TAP_FINAL_BIT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ordenador.tape_bit = 0x80;
|
||||||
|
retval=fread (&(ordenador.tape_byte), 1, 1, fichero); // read next byte
|
||||||
|
if (feof (fichero)) {
|
||||||
|
rewind_tape (fichero,0);
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_STOP; // stop tape
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if((ordenador.tape_byte_counter==1)&&(ordenador.tape_bits_at_end!=8)) { // last byte
|
||||||
|
for(bucle=ordenador.tape_bits_at_end;bucle<8;bucle++) {
|
||||||
|
ordenador.tape_byte=((ordenador.tape_byte>>1)&0x7F);
|
||||||
|
ordenador.tape_bit = ((ordenador.tape_bit>>1)&0x7F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAP_PAUSE3: // one pulse of 1 ms for ending the bit
|
||||||
|
ordenador.tape_counter0 = 3500; // 1 ms
|
||||||
|
ordenador.tape_counter1 = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_PAUSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAP_PAUSE: // pause
|
||||||
|
ordenador.tape_readed = 0;
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
if (ordenador.tape_counter_rep > tstados) {
|
||||||
|
ordenador.tape_counter_rep -= tstados;
|
||||||
|
} else {
|
||||||
|
ordenador.tape_counter_rep = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH; // read new block
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TAP_PAUSE2: // pause and stop
|
||||||
|
ordenador.tape_readed = 0;
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
if (ordenador.tape_counter_rep > tstados) {
|
||||||
|
ordenador.tape_counter_rep -= tstados;
|
||||||
|
} else {
|
||||||
|
ordenador.tape_counter_rep = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH; // read new block
|
||||||
|
ordenador.pause = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TZX_PURE_TONE:
|
||||||
|
ordenador.tape_counter_rep--;
|
||||||
|
ordenador.tape_current_bit = 1 - ordenador.tape_current_bit; // invert current bit
|
||||||
|
if (ordenador.tape_counter_rep) { // still into guide tone
|
||||||
|
ordenador.tape_counter0 = ordenador.tape_block_level - tstados;
|
||||||
|
ordenador.tape_counter1 = 0; // new pulse
|
||||||
|
} else
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH; // next ID
|
||||||
|
break;
|
||||||
|
case TZX_SEQ_PULSES:
|
||||||
|
ordenador.tape_current_bit = 1 - ordenador.tape_current_bit; // invert current bit
|
||||||
|
ordenador.tape_counter_rep--;
|
||||||
|
if(ordenador.tape_counter_rep) {
|
||||||
|
retval=fread(&value2,1,1,fichero);
|
||||||
|
retval=fread(&value3,1,1,fichero); // length of pulse in T-states
|
||||||
|
ordenador.tape_counter0 = ((unsigned int) value2) + 256 * ((unsigned int) value3);
|
||||||
|
ordenador.tape_counter1 = 0;
|
||||||
|
} else
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH; // next ID
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAP_STOP:
|
||||||
|
ordenador.tape_current_bit = 0;
|
||||||
|
ordenador.tape_current_mode = TAP_TRASH; // initialize
|
||||||
|
ordenador.pause = 1; // pause it
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rewind_tape(FILE *fichero,unsigned char pause) {
|
||||||
|
|
||||||
|
int thebucle;
|
||||||
|
unsigned char value;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
rewind (ordenador.tap_file);
|
||||||
|
if(ordenador.tape_file_type==TAP_TZX)
|
||||||
|
for(thebucle=0;thebucle<10;thebucle++)
|
||||||
|
retval=fread(&value,1,1,ordenador.tap_file); // jump over the header
|
||||||
|
ordenador.pause=pause;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char file_empty(FILE *fichero) {
|
||||||
|
|
||||||
|
long position,position2;
|
||||||
|
|
||||||
|
position=ftell(fichero);
|
||||||
|
fseek(fichero,0,SEEK_END); // set the pointer at end
|
||||||
|
position2=ftell(fichero);
|
||||||
|
fseek(fichero,position,SEEK_SET); // return the pointer to the original place
|
||||||
|
if(position2==0)
|
||||||
|
return 1; // empty file
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_file(FILE *fichero) {
|
||||||
|
|
||||||
|
long position;
|
||||||
|
unsigned char xor,salir;
|
||||||
|
byte dato;
|
||||||
|
int longitud;
|
||||||
|
|
||||||
|
position=ftell(fichero); // store current position
|
||||||
|
fseek(fichero,0,SEEK_END); // put position at end
|
||||||
|
xor=0;
|
||||||
|
|
||||||
|
longitud=(int)(procesador.Rm.wr.DE);
|
||||||
|
longitud+=2;
|
||||||
|
|
||||||
|
dato=(byte)(longitud%256);
|
||||||
|
fprintf(fichero,"%c",dato);
|
||||||
|
dato=(byte)(longitud/256);
|
||||||
|
fprintf(fichero,"%c",dato); // file length
|
||||||
|
|
||||||
|
fprintf(fichero,"%c",procesador.Rm.br.A); // flag
|
||||||
|
|
||||||
|
xor^=procesador.Rm.br.A;
|
||||||
|
|
||||||
|
salir = 0;
|
||||||
|
do {
|
||||||
|
if (procesador.Rm.wr.DE == 0)
|
||||||
|
salir = 2;
|
||||||
|
if (!salir) {
|
||||||
|
dato=Z80free_Rd(procesador.Rm.wr.IX); // read data
|
||||||
|
fprintf(fichero,"%c",dato);
|
||||||
|
xor^=dato;
|
||||||
|
procesador.Rm.wr.IX++;
|
||||||
|
procesador.Rm.wr.DE--;
|
||||||
|
}
|
||||||
|
} while (!salir);
|
||||||
|
fprintf(fichero,"%c",xor);
|
||||||
|
procesador.Rm.wr.IX++;
|
||||||
|
procesador.Rm.wr.IX++;
|
||||||
|
fseek(fichero,position,SEEK_SET); // put position at end
|
||||||
|
|
||||||
|
if(ordenador.tape_fast_load==1) //if we want fast load, we assume we want fast save too
|
||||||
|
ordenador.other_ret = 1; // next instruction must be RET
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fastload_block (FILE * fichero) {
|
||||||
|
|
||||||
|
unsigned int longitud;
|
||||||
|
unsigned char value[65536], salir,empty,flag_found;
|
||||||
|
unsigned int veces;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
ordenador.other_ret = 1; // next instruction must be RET
|
||||||
|
|
||||||
|
if (!(procesador.Rm.br.F & F_C)) { // if Carry=0, is VERIFY, so return OK
|
||||||
|
procesador.Rm.br.F |= F_C; // verify OK
|
||||||
|
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||||
|
procesador.Rm.wr.DE = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
empty=file_empty(fichero);
|
||||||
|
|
||||||
|
|
||||||
|
if ((fichero == NULL)||(empty)) {
|
||||||
|
procesador.Rm.br.F &= (~F_C); // Load error
|
||||||
|
procesador.Rm.wr.IX += procesador.Rm.wr.DE;
|
||||||
|
procesador.Rm.wr.DE = 0;
|
||||||
|
if(empty)
|
||||||
|
sprintf (ordenador.osd_text, "Tape file empty");
|
||||||
|
else
|
||||||
|
sprintf (ordenador.osd_text, "No tape selected");
|
||||||
|
ordenador.osd_time = 100;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
veces=0;
|
||||||
|
|
||||||
|
flag_found=0;
|
||||||
|
do {
|
||||||
|
retval=fread (value, 2, 1, fichero); // read length of current block
|
||||||
|
if (feof (fichero)) { // end of file?
|
||||||
|
veces++; // one more time rewinded
|
||||||
|
sprintf (ordenador.osd_text, "Tape rewind");
|
||||||
|
ordenador.osd_time = 100;
|
||||||
|
rewind (fichero); // again
|
||||||
|
retval=fread (value, 2, 1, fichero); // read length of current block
|
||||||
|
}
|
||||||
|
longitud = ((unsigned int) value[0]) + 256 * ((unsigned int) value[1]);
|
||||||
|
retval=fread (value, 1, 1, fichero); // read flag byte
|
||||||
|
longitud--;
|
||||||
|
if (value[0] != procesador.Rm.br.A) { // different flag
|
||||||
|
retval=fread (value, longitud, 1, fichero); // jump to the next block
|
||||||
|
if (veces==3) { // tape rewinded three times? Block with that flag not found.
|
||||||
|
sprintf(ordenador.osd_text,"Block with right flag not found");
|
||||||
|
ordenador.osd_time = 100;
|
||||||
|
procesador.Rm.br.F &= (~F_C); // Load error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
flag_found = 1;
|
||||||
|
} while(flag_found == 0);
|
||||||
|
|
||||||
|
salir = 0;
|
||||||
|
do {
|
||||||
|
if (longitud == 0)
|
||||||
|
salir = 1;
|
||||||
|
if (procesador.Rm.wr.DE == 0)
|
||||||
|
salir = 2;
|
||||||
|
if (!salir) {
|
||||||
|
retval=fread (value, 1, 1, fichero); // read byte
|
||||||
|
Z80free_Wr (procesador.Rm.wr.IX, (byte) value[0]); // store the byte
|
||||||
|
procesador.Rm.wr.IX++;
|
||||||
|
procesador.Rm.wr.DE--;
|
||||||
|
longitud--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!salir);
|
||||||
|
|
||||||
|
clean_screen ();
|
||||||
|
|
||||||
|
if (salir == 1) { // system wants to load more bytes that the existent
|
||||||
|
procesador.Rm.br.F &= (~F_C); // Load error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((salir == 2) && (longitud != 1)) { // there are more bytes to load
|
||||||
|
procesador.Rm.br.F &= (~F_C); // Load error
|
||||||
|
if (longitud > 1)
|
||||||
|
retval=fread (value, longitud, 1, fichero); // jump to the next block
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval=fread (value, 1, 1, fichero); // jump over the checksum
|
||||||
|
procesador.Rm.br.F |= F_C; // Load OK
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
31
src/tape.h
Normal file
31
src/tape.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of FBZX
|
||||||
|
*
|
||||||
|
* FBZX 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FBZX 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef H_TAPE
|
||||||
|
#define H_TAPE
|
||||||
|
|
||||||
|
inline void tape_read(FILE *, int);
|
||||||
|
inline void tape_read_tap(FILE *, int);
|
||||||
|
inline void tape_read_tzx(FILE *, int);
|
||||||
|
void rewind_tape(FILE *,unsigned char);
|
||||||
|
unsigned char file_empty(FILE *);
|
||||||
|
void fastload_block (FILE *);
|
||||||
|
void save_file(FILE *);
|
||||||
|
|
||||||
|
#endif
|
674
src/z80free/COPYING
Normal file
674
src/z80free/COPYING
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. 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
|
||||||
|
them 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 prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. 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.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey 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;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If 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 convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU 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 that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
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.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program 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, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU 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 Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
141
src/z80free/Makefile
Normal file
141
src/z80free/Makefile
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Clear the implicit built in rules
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITPPC)),)
|
||||||
|
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(DEVKITPPC)/wii_rules
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# TARGET is the name of the output
|
||||||
|
# BUILD is the directory where object files & intermediate files will be placed
|
||||||
|
# SOURCES is a list of directories containing source code
|
||||||
|
# INCLUDES is a list of directories containing extra header files
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
TARGET := z80_test
|
||||||
|
BUILD := build
|
||||||
|
SOURCES := .
|
||||||
|
DATA :=
|
||||||
|
INCLUDES :=
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# options for code generation
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CFLAGS = -g -O1 -Wall $(MACHDEP) $(INCLUDE)
|
||||||
|
CXXFLAGS = $(CFLAGS)
|
||||||
|
|
||||||
|
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||||
|
#-fpack-struct
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# any extra libraries we wish to link with the project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBS := -lfat -lwiiuse -lbte -logc -lm -lwiikeyboard
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
# include and lib
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBDIRS := $(PORTLIBS)
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# no real need to edit anything past this point unless you need to add additional
|
||||||
|
# rules for different file extensions
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
|
|
||||||
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||||
|
|
||||||
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# automatically build a list of object files for our project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
|
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
|
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
||||||
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(CPPFILES)),)
|
||||||
|
export LD := $(CC)
|
||||||
|
else
|
||||||
|
export LD := $(CXX)
|
||||||
|
endif
|
||||||
|
|
||||||
|
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||||
|
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||||
|
$(sFILES:.s=.o) $(SFILES:.S=.o)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# build a list of include paths
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
|
-I$(CURDIR)/$(BUILD) \
|
||||||
|
-I$(LIBOGC_INC)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# build a list of library paths
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
||||||
|
-L$(LIBOGC_LIB)
|
||||||
|
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
|
.PHONY: $(BUILD) clean
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(BUILD):
|
||||||
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
clean:
|
||||||
|
@echo clean ...
|
||||||
|
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol dist
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
run:
|
||||||
|
wiiload $(TARGET).dol
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
|
||||||
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(OUTPUT).dol: $(OUTPUT).elf
|
||||||
|
$(OUTPUT).elf: $(OFILES)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# This rule links in binary data with the .jpg extension
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.jpg.o : %.jpg
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(bin2o)
|
||||||
|
|
||||||
|
-include $(DEPENDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------
|
32
src/z80free/Makefile.ori
Normal file
32
src/z80free/Makefile.ori
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
CC = gcc -c -O1 -Wall
|
||||||
|
CCo = gcc -O1 -Wall
|
||||||
|
|
||||||
|
z80free_tester: z80free_tester.o Z80free.o Z80free_codes.o Z80free_codesCB.o Z80free_codesED.o Z80free_codesDD.o Z80free_codesFD.o Z80free_codesDDCB.o Z80free_codesFDCB.o
|
||||||
|
$(CCo) -o z80free_tester z80free_tester.o Z80free.o Z80free_codes.o Z80free_codesCB.o Z80free_codesED.o Z80free_codesDD.o Z80free_codesFD.o Z80free_codesDDCB.o Z80free_codesFDCB.o
|
||||||
|
|
||||||
|
z80free_tester.o: z80free_tester.c Z80free.h
|
||||||
|
$(CC) -o z80free_tester.o z80free_tester.c
|
||||||
|
|
||||||
|
Z80free.o: Z80free.c Z80free.h
|
||||||
|
$(CC) -o Z80free.o Z80free.c
|
||||||
|
|
||||||
|
Z80free_codes.o: Z80free_codes.c Z80free.h
|
||||||
|
$(CC) -o Z80free_codes.o Z80free_codes.c
|
||||||
|
|
||||||
|
Z80free_codesCB.o: Z80free_codesCB.c Z80free.h
|
||||||
|
$(CC) -o Z80free_codesCB.o Z80free_codesCB.c
|
||||||
|
|
||||||
|
Z80free_codesED.o: Z80free_codesED.c Z80free.h
|
||||||
|
$(CC) -o Z80free_codesED.o Z80free_codesED.c
|
||||||
|
|
||||||
|
Z80free_codesDD.o: Z80free_codesDD.c Z80free.h
|
||||||
|
$(CC) -o Z80free_codesDD.o Z80free_codesDD.c
|
||||||
|
|
||||||
|
Z80free_codesFD.o: Z80free_codesFD.c Z80free.h
|
||||||
|
$(CC) -o Z80free_codesFD.o Z80free_codesFD.c
|
||||||
|
|
||||||
|
Z80free_codesDDCB.o: Z80free_codesDDCB.c Z80free.h
|
||||||
|
$(CC) -o Z80free_codesDDCB.o Z80free_codesDDCB.c
|
||||||
|
|
||||||
|
Z80free_codesFDCB.o: Z80free_codesFDCB.c Z80free.h
|
||||||
|
$(CC) -o Z80free_codesFDCB.o Z80free_codesFDCB.c
|
247
src/z80free/README.txt
Normal file
247
src/z80free/README.txt
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
Z80Free
|
||||||
|
A free Z80 emulator
|
||||||
|
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
Z80free is distributed under the GPL license, version three or later, which
|
||||||
|
means that is distributed "as is", without warraty of any kind. To know more
|
||||||
|
details, read the file COPYING.
|
||||||
|
|
||||||
|
|
||||||
|
WHAT IS Z80free?
|
||||||
|
|
||||||
|
Z80free is a Z80 emulator written in C. It's designed to be as accurate as
|
||||||
|
possible, mainly in the flags from the F register, the instruction set
|
||||||
|
(emulating all the oficial and unoficial instructions like SET n,(IX+10h),r
|
||||||
|
the phantom IN, incorrect FD and DD sequences...) and the R register. It also
|
||||||
|
aims to allow a very accurate emulation of the computer hardware by dividing
|
||||||
|
the instructions as finely as possible; that way the prefixes, when
|
||||||
|
available, are executed in a first round, and only then the instruction
|
||||||
|
itself is executed. This allows a much more precise emulation of incorrect
|
||||||
|
sequences of prefixes like FDFDFDFDxx... and others.
|
||||||
|
|
||||||
|
|
||||||
|
WORKING WITH Z80FREE
|
||||||
|
|
||||||
|
The heart is the typedef struct Z80FREE, which contains all the registers and
|
||||||
|
some variables needed to maintain the current state.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Z80FRegs Rm; /** Main register set (R) */
|
||||||
|
Z80FRegs Ra; /** Alternate register set (R') */
|
||||||
|
word PC; /** Program counter */
|
||||||
|
byte R; /** Refresh */
|
||||||
|
byte R2; /** Upper bit for Refresh */
|
||||||
|
byte I;
|
||||||
|
byte IFF1; /** Interrupt Flipflop 1. If it's 2
|
||||||
|
decrement it and don't allow INT */
|
||||||
|
byte IFF2; /** Interrupt Flipflop 2 */
|
||||||
|
byte IM; /** Interrupt mode */
|
||||||
|
byte HALT; /** HALT status */
|
||||||
|
byte INT_P; /** INT pending */
|
||||||
|
byte NMI_P; /** NMI pending */
|
||||||
|
byte empty_bus; /** value for empty bus when procesing
|
||||||
|
a maskable int */
|
||||||
|
word IAddr; /** address with offset for IX+d and IY+d */
|
||||||
|
byte IAddr_done; /** if 1, IAddr contains a valid data */
|
||||||
|
enum {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD, Z80INT} Status;
|
||||||
|
} Z80FREE;
|
||||||
|
|
||||||
|
The first two elements, Rm and Ra, contains the main and alternate register
|
||||||
|
sets. The typedef is the following:
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
/** Word registers. */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
word AF, BC, DE, HL, IX, IY, SP;
|
||||||
|
} wr;
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
byte F,A, C,B, E,D, L,H, IXl,IXh, IYl,IYh, P,S;
|
||||||
|
} br;
|
||||||
|
#else
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
byte A,F, B,C, D,E, H,L, IXh,IXl, IYh,IYl, S,P;
|
||||||
|
} br;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} Z80FRegs;
|
||||||
|
|
||||||
|
This means that accessing a register (like HL) is done with
|
||||||
|
|
||||||
|
processor.Rm.wr.HL
|
||||||
|
|
||||||
|
while accessing a register like H in 8bit mode is done with
|
||||||
|
|
||||||
|
processor.Rm.br.H
|
||||||
|
|
||||||
|
Since Z80FRegs is an union, both structs are solaped. The conditional
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN allows to set the right register
|
||||||
|
order depending on the endiannes of the machine.
|
||||||
|
|
||||||
|
The register R is stored twice: as R and R2, but only R is incremented after
|
||||||
|
each instruction or prefix. When reading it (with LD A,R), the value is
|
||||||
|
composed with (R&0x7F)|(R2&0x80). That way the true value is returned,
|
||||||
|
since the real Z80 only increment the lower 7 bits of R, but stores all the
|
||||||
|
8 bits.
|
||||||
|
|
||||||
|
IFF1 and IFF2 are modified by DI and EI. But IFF1 can be 0, 1 or 2. When its
|
||||||
|
2, it means that the interrups have to be allowed after the next instruction.
|
||||||
|
This is because, when doing
|
||||||
|
|
||||||
|
...
|
||||||
|
EI
|
||||||
|
XXX
|
||||||
|
YYY
|
||||||
|
...
|
||||||
|
|
||||||
|
if an interrupt arrives during EI, it won't be accepted between EI and XXX,
|
||||||
|
but between XXX and YYY. When IFF1 is 2, Z80FREE won't still accept
|
||||||
|
interrupts, but will decrement it, so at the next instruction it will be 1,
|
||||||
|
accepting the pending interrupt.
|
||||||
|
|
||||||
|
IM can be 0, 1 or 2, but currently modes 0 and 1 are the same (they both jump
|
||||||
|
to 38h).
|
||||||
|
|
||||||
|
When HALT is 1, the processor is running a HALT instruction, returning 4
|
||||||
|
tstates consumed and maintaining the PC counter until an interrupt is
|
||||||
|
accepted (or a reset is done).
|
||||||
|
|
||||||
|
All the other info is internal and should not be needed when creating an
|
||||||
|
emulator.
|
||||||
|
|
||||||
|
There are four functions offered by Z80FREE to interact with it:
|
||||||
|
|
||||||
|
void Z80free_reset(Z80FREE *);
|
||||||
|
|
||||||
|
RESET function resets the processor.
|
||||||
|
|
||||||
|
void Z80free_INT(Z80FREE *,byte);
|
||||||
|
|
||||||
|
INT triggers a maskable interrupt. The BYTE value contains the value
|
||||||
|
currently present in the bus (useful when, in a future, the true IM0
|
||||||
|
mode will be implemented).
|
||||||
|
|
||||||
|
int Z80free_step(Z80FREE *);
|
||||||
|
|
||||||
|
Runs the processor for one complete instruction. It returns the number of
|
||||||
|
TSTates used by that instruction. After it, the PC points to the next
|
||||||
|
instruction, and is safe to do operations like creating snapshots or
|
||||||
|
similar.
|
||||||
|
|
||||||
|
int Z80free_ustep(Z80FREE *);
|
||||||
|
|
||||||
|
Runs the processor for a microstep. That means that, if the current
|
||||||
|
instruction has a prefix, only the prefix will be recognized, and the
|
||||||
|
PC will point to the middle of the instruction; but if the instruction
|
||||||
|
doesn't have a prefix, it will run it complete. It returns the TSTates
|
||||||
|
used to run that piece of the current instruction. It's unsafe to create
|
||||||
|
an snapshot after running this function because the processor can be
|
||||||
|
in an intermediate state, but is safe to update the hardware (like the
|
||||||
|
screen or the sound).
|
||||||
|
|
||||||
|
To know when is safe to do things, a piece of code like this one can
|
||||||
|
be used:
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
do {
|
||||||
|
// Insecure zone. Only update the hardware
|
||||||
|
tstados=Z80free_ustep(&procesador);
|
||||||
|
EMULATE(tstados);
|
||||||
|
} while(procesador.Status!=Z80XX);
|
||||||
|
|
||||||
|
// Secure zone. Do snapshots and other things that
|
||||||
|
// require the Z80 to be in a defined state.
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
Here is assumed that EMULATE(int) emulates the screen, sound,... for
|
||||||
|
that number of TSTates. When STATUS is Z80XX, the processor is going
|
||||||
|
to read the first byte of an instruction, and is safe to do other things
|
||||||
|
like creating snapshots.
|
||||||
|
|
||||||
|
Of course, if you don't want to complicate things, just use Z80FREE_STEP.
|
||||||
|
|
||||||
|
Finally, you must implement the following functions in order to emulate the
|
||||||
|
hardware itself:
|
||||||
|
|
||||||
|
byte Z80free_Rd (register word Addr);
|
||||||
|
|
||||||
|
When Z80Free needs to read a byte from memory, it will call this function.
|
||||||
|
It must return the value contained in the possition ADDR.
|
||||||
|
|
||||||
|
void Z80free_Wr (register word Addr, register byte Value);
|
||||||
|
|
||||||
|
When Z80Free needs to write a byte to memory, it will call this funcion.
|
||||||
|
It must store the data VALUE at the position ADDR.
|
||||||
|
|
||||||
|
byte Z80free_In (register word Port);
|
||||||
|
|
||||||
|
When Z80Free needs to access to an input port, it will call this function.
|
||||||
|
PORT contains the 16bit port being accessed.
|
||||||
|
|
||||||
|
void Z80free_Out (register word Port, register byte Value);
|
||||||
|
|
||||||
|
When Z80Free needs to access to an output port, it will call this function.
|
||||||
|
PORT contains the 16bit port being accessed, and VALUE the data to be
|
||||||
|
written to the port.
|
||||||
|
|
||||||
|
|
||||||
|
HOW Z80FREE IS IMPLEMENTED
|
||||||
|
|
||||||
|
There are two main files: Z80FREE.C and Z80FREE.H. Z80FREE.C contains the main
|
||||||
|
loop and some help functions. Some of them were extracted from LibZ80 (from
|
||||||
|
Gabriel Gambetta), adapted to the new processor structure and, where needed,
|
||||||
|
fixed some little bugs.
|
||||||
|
|
||||||
|
But the true magic is in the files z80FREE_CODESXXXX.C. These files contains
|
||||||
|
big switch/case functions which plays each Z80 instruction and returns the
|
||||||
|
number of TSTATES used by them. But these files weren't created "by hand",
|
||||||
|
but parsing the files Z80FREE_CODESXXXX.TXT. These files contains a list of
|
||||||
|
all the Z80 instructions, with its opcode numbers and the number of TSTATES
|
||||||
|
used (when it's a conditional instruction, which can use more TSTATES when
|
||||||
|
true than when false, it contain both values), and are parsed by the program
|
||||||
|
Z80FREE_GENCODE.PY.
|
||||||
|
|
||||||
|
This program gets the opcode, the number of TSTATES and the instruction.
|
||||||
|
Then it splits the instruction in the instruction itself (like LD, or EX) and
|
||||||
|
parameters (like A or 5). With all that data it generates the code for that
|
||||||
|
instruction in the right CASE statement.
|
||||||
|
|
||||||
|
The code in Z80FREE_GENCODE.PY is divided in several classes, so is extremely
|
||||||
|
easy to adapt it to other processors. Just read the comments (you should use
|
||||||
|
the GENERIC_PARSER class "as is", and create a new class which inherits from
|
||||||
|
it and implements the methods GET_CODE_FROM_ONE_PARAM, CREATE_CODE,
|
||||||
|
WRITE_START_CODE and WRITE_END_CODE.
|
||||||
|
|
||||||
|
In order to simplify the parser, the syntax of some instructions have been
|
||||||
|
modified, like the I/O ones: instead of (C) we use [BC].
|
||||||
|
|
||||||
|
If an instruction is incorrectly implemented, you must fix it in
|
||||||
|
Z80FREE_GENCODE.PY, run it again to regenerate the .C files, and only then
|
||||||
|
recompile your emulator.
|
||||||
|
|
||||||
|
The big advantage of this method is that, if the implementation of one
|
||||||
|
instruction type is incorrect, fixing it once will fix it in all the
|
||||||
|
instructions with all the access modes used. An example: if the LD
|
||||||
|
instruction type has a bug, fixing it will fix all the LD instructions, like
|
||||||
|
LD A,n, LD (HL),A, LD B,C... The same when the bug is in the parameter code:
|
||||||
|
if there's an error in the code that implements (HL) as writing, fixing it
|
||||||
|
will fix all the instructions that uses it, like LD (HL),A, or CP (HL).
|
||||||
|
|
||||||
|
|
||||||
|
CONTACTING THE AUTHOR
|
||||||
|
|
||||||
|
This program is
|
||||||
|
(C) 2008 Sergio Costas Rodriguez
|
||||||
|
(Raster Software Vigo)
|
||||||
|
|
||||||
|
raster@rastersoft.com
|
||||||
|
http://www.rastersoft.com
|
||||||
|
|
783
src/z80free/Z80free.c
Normal file
783
src/z80free/Z80free.c
Normal file
@ -0,0 +1,783 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of Z80Free, with some bits extracted
|
||||||
|
* and fixed from libZ80 (from Gabriel Gambetta)
|
||||||
|
*
|
||||||
|
* Z80Free 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Z80Free 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Z80free.h"
|
||||||
|
|
||||||
|
void Z80free_reset(Z80FREE *processor) {
|
||||||
|
|
||||||
|
processor->PC=0;
|
||||||
|
processor->IFF1=0;
|
||||||
|
processor->IFF2=0;
|
||||||
|
processor->Rm.wr.AF=0xFFFF;
|
||||||
|
processor->Rm.wr.BC=0xFFFF;
|
||||||
|
processor->Rm.wr.DE=0xFFFF;
|
||||||
|
processor->Rm.wr.HL=0xFFFF;
|
||||||
|
processor->Rm.wr.IX=0xFFFF;
|
||||||
|
processor->Rm.wr.IY=0xFFFF;
|
||||||
|
processor->Ra.wr.AF=0xFFFF;
|
||||||
|
processor->Ra.wr.BC=0xFFFF;
|
||||||
|
processor->Ra.wr.DE=0xFFFF;
|
||||||
|
processor->Ra.wr.HL=0xFFFF;
|
||||||
|
processor->HALT=0;
|
||||||
|
processor->IM=0;
|
||||||
|
processor->I=0;
|
||||||
|
processor->Status=0;
|
||||||
|
processor->IAddr_done=0;
|
||||||
|
processor->INT_P=0;
|
||||||
|
processor->NMI_P=0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80free_INT(Z80FREE *processor,byte value) {
|
||||||
|
|
||||||
|
processor->INT_P=1;
|
||||||
|
processor->empty_bus=value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int Z80free_step(Z80FREE *processor) {
|
||||||
|
|
||||||
|
int retval=0;
|
||||||
|
do {
|
||||||
|
retval+=Z80free_ustep(processor);
|
||||||
|
} while(processor->Status!=Z80XX);
|
||||||
|
return (retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Z80free_ustep(Z80FREE *processor) {
|
||||||
|
|
||||||
|
static byte opcode,d1;
|
||||||
|
int retval=0;
|
||||||
|
|
||||||
|
processor->R++;
|
||||||
|
if (processor->Status==Z80XX) {
|
||||||
|
if (processor->NMI_P) { // NMI triggered
|
||||||
|
if (processor->HALT) {
|
||||||
|
processor->HALT=0;
|
||||||
|
processor->PC++;
|
||||||
|
}
|
||||||
|
processor->NMI_P=0;
|
||||||
|
Z80free_doPush(processor,processor->PC);
|
||||||
|
processor->PC=0x0066;
|
||||||
|
processor->IFF1=0; // disable INTs
|
||||||
|
processor->Status=Z80INT;
|
||||||
|
return(11); // we use 11 tstates for attending a NMI
|
||||||
|
}
|
||||||
|
if (processor->INT_P) {
|
||||||
|
processor->INT_P=0;
|
||||||
|
if (processor->IFF1==1) { // allow INTs only in this case
|
||||||
|
if (processor->HALT) {
|
||||||
|
processor->HALT=0;
|
||||||
|
processor->PC++;
|
||||||
|
}
|
||||||
|
processor->Status=Z80INT;
|
||||||
|
processor->IFF1=0;
|
||||||
|
processor->IFF2=0;
|
||||||
|
Z80free_doPush(processor,processor->PC);
|
||||||
|
if (processor->IM!=2) { // we will forget IM0 mode for now; maybe in the future...
|
||||||
|
processor->PC=0x0038;
|
||||||
|
return (13);
|
||||||
|
} else {
|
||||||
|
processor->PC=Z80free_read16(((((word)processor->I)<<8)&0xFF00) | ((word)processor->empty_bus));
|
||||||
|
return (19);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processor->IFF1>1) // set the right status for interrupts
|
||||||
|
processor->IFF1--;
|
||||||
|
|
||||||
|
opcode=Z80free_Rd(processor->PC);
|
||||||
|
processor->PC++;
|
||||||
|
switch(processor->Status) {
|
||||||
|
case Z80INT:
|
||||||
|
processor->Status=Z80XX;
|
||||||
|
case Z80XX:
|
||||||
|
if (opcode==0xCB) {
|
||||||
|
processor->Status=Z80CB;
|
||||||
|
return 4;
|
||||||
|
} else if (opcode==0xED) {
|
||||||
|
processor->Status=Z80ED;
|
||||||
|
return 4;
|
||||||
|
} else if (opcode==0xDD) {
|
||||||
|
processor->Status=Z80DD;
|
||||||
|
return 4;
|
||||||
|
} else if (opcode==0xFD) {
|
||||||
|
processor->Status=Z80FD;
|
||||||
|
return 4;
|
||||||
|
} else {
|
||||||
|
return(Z80free_codes(processor,opcode));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Z80CB:
|
||||||
|
processor->Status=Z80XX;
|
||||||
|
return(Z80free_codesCB(processor,opcode));
|
||||||
|
break;
|
||||||
|
case Z80ED:
|
||||||
|
processor->Status=Z80XX;
|
||||||
|
return(Z80free_codesED(processor,opcode));
|
||||||
|
break;
|
||||||
|
case Z80DD:
|
||||||
|
if (opcode==0xDD) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
if (opcode==0xFD) {
|
||||||
|
processor->Status=Z80FD;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
processor->Status=Z80XX;
|
||||||
|
if (opcode==0xCB) {
|
||||||
|
d1=Z80free_Rd(processor->PC++);
|
||||||
|
retval+=Z80free_codesDDCB(processor,d1);
|
||||||
|
} else {
|
||||||
|
retval+=Z80free_codesDD(processor,opcode);
|
||||||
|
}
|
||||||
|
processor->IAddr_done=0;
|
||||||
|
return (retval);
|
||||||
|
break;
|
||||||
|
case Z80FD:
|
||||||
|
if (opcode==0xDD) {
|
||||||
|
processor->Status=Z80DD;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
if (opcode==0xFD) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
processor->Status=Z80XX;
|
||||||
|
if (opcode==0xCB) {
|
||||||
|
d1=Z80free_Rd(processor->PC++);
|
||||||
|
retval+=Z80free_codesFDCB(processor,d1);
|
||||||
|
} else {
|
||||||
|
retval+=Z80free_codesFD(processor,opcode);
|
||||||
|
}
|
||||||
|
processor->IAddr_done=0;
|
||||||
|
return (retval);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------
|
||||||
|
* Flag operations
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Sets a flag */
|
||||||
|
inline void Z80free_setFlag(Z80FREE *processor, byte flag) {
|
||||||
|
|
||||||
|
processor->Rm.br.F |= flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resets a flag */
|
||||||
|
inline void Z80free_resFlag(Z80FREE *processor, byte flag) {
|
||||||
|
|
||||||
|
processor->Rm.br.F &= ~flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Puts a value in a flag */
|
||||||
|
inline void Z80free_valFlag(Z80FREE *processor, byte flag, int val) {
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
processor->Rm.br.F |= flag;
|
||||||
|
else
|
||||||
|
processor->Rm.br.F &= ~flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a flag */
|
||||||
|
inline int Z80free_getFlag(Z80FREE *processor, byte flag) {
|
||||||
|
|
||||||
|
return (processor->Rm.br.F & flag) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------
|
||||||
|
* Flag adjustments
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int Z80free_parityBit[256] = {
|
||||||
|
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 };
|
||||||
|
|
||||||
|
|
||||||
|
inline void Z80free_adjustFlags (Z80FREE *processor, byte val) {
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_5, (val & F_5) != 0);
|
||||||
|
Z80free_valFlag(processor,F_3, (val & F_3) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Z80free_adjustFlagSZP (Z80FREE *processor, byte val) {
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_S, (val & 0x80) != 0);
|
||||||
|
Z80free_valFlag(processor,F_Z, (val == 0));
|
||||||
|
Z80free_valFlag(processor,F_PV, Z80free_parityBit[val]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Adjust flags after AND, OR, XOR
|
||||||
|
inline void Z80free_adjustLogicFlag (Z80FREE *processor, int flagH) {
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_S, (processor->Rm.br.A & 0x80) != 0);
|
||||||
|
Z80free_valFlag(processor,F_Z, (processor->Rm.br.A == 0));
|
||||||
|
Z80free_valFlag(processor,F_H, flagH);
|
||||||
|
Z80free_valFlag(processor,F_N, 0);
|
||||||
|
Z80free_valFlag(processor,F_C, 0);
|
||||||
|
Z80free_valFlag(processor,F_PV, Z80free_parityBit[processor->Rm.br.A]);
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, processor->Rm.br.A);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------
|
||||||
|
* Generic operations
|
||||||
|
* ---------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
byte Z80free_readR(Z80FREE *processor) {
|
||||||
|
Z80free_adjustFlagSZP(processor,(0x7F&processor->R)|(0x80&processor->R2));
|
||||||
|
Z80free_valFlag(processor,F_PV,processor->IFF2);
|
||||||
|
Z80free_valFlag(processor,F_N, 0);
|
||||||
|
Z80free_valFlag(processor,F_H, 0);
|
||||||
|
Z80free_adjustFlags(processor,(0x7F&processor->R)|(0x80&processor->R2));
|
||||||
|
return ((0x7F&processor->R)|(0x80&processor->R2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80free_setR(Z80FREE *processor,byte value) {
|
||||||
|
processor->R=value;
|
||||||
|
processor->R2=value;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte Z80free_readI(Z80FREE *processor) {
|
||||||
|
|
||||||
|
Z80free_adjustFlagSZP(processor,processor->I);
|
||||||
|
Z80free_valFlag(processor,F_PV,processor->IFF2);
|
||||||
|
Z80free_valFlag(processor,F_N, 0);
|
||||||
|
Z80free_valFlag(processor,F_H, 0);
|
||||||
|
Z80free_adjustFlags(processor,processor->I);
|
||||||
|
return (processor->I);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Do an arithmetic operation (ADD, SUB, ADC, SBC y CP) */
|
||||||
|
byte Z80free_doArithmetic (Z80FREE *processor, byte value1,byte value2, int withCarry, int isSub) {
|
||||||
|
|
||||||
|
static word res; /* To detect carry */
|
||||||
|
static byte carry;
|
||||||
|
|
||||||
|
if (withCarry && Z80free_getFlag(processor,F_C))
|
||||||
|
carry=1;
|
||||||
|
else
|
||||||
|
carry=0;
|
||||||
|
|
||||||
|
if (isSub) {
|
||||||
|
Z80free_setFlag(processor,F_N);
|
||||||
|
res = ((word)value1) - ((word)value2) - ((word)carry);
|
||||||
|
Z80free_valFlag(processor,F_H, ((value1 ^ value2 ^ res) & 0x10) != 0);
|
||||||
|
Z80free_valFlag(processor,F_PV, (((value1 ^ value2)&0x080) && (((res^value1)&0x080))));
|
||||||
|
} else {
|
||||||
|
Z80free_resFlag(processor,F_N);
|
||||||
|
res = ((word)value1) + ((word)value2) + ((word)carry);
|
||||||
|
Z80free_valFlag(processor,F_H, (((value1 & 0x0F) + (value2 & 0x0F)+carry) & 0x10) != 0);
|
||||||
|
Z80free_valFlag(processor,F_PV, ((((value1 ^ value2)&0x080)==0) && ((res^value1)&0x080)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_S, ((res & 0x080) != 0));
|
||||||
|
Z80free_valFlag(processor,F_C, ((res & 0x0100) != 0));
|
||||||
|
Z80free_valFlag(processor,F_Z, ((res&0xFF) == 0));
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, res&0xFF);
|
||||||
|
|
||||||
|
return (byte)(res & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
word Z80free_doArithmetic16 (Z80FREE *processor, word value1,word value2, int withCarry, int isSub) {
|
||||||
|
|
||||||
|
static word tmp;
|
||||||
|
static byte Ftmp;
|
||||||
|
|
||||||
|
Ftmp=processor->Rm.br.F; // store the F register to restore the unchanged bits when doing operations without carry
|
||||||
|
|
||||||
|
tmp=(word)Z80free_doArithmetic(processor,(byte)(value1&0x00FF),(byte)(value2&0x00FF),withCarry,isSub);
|
||||||
|
tmp|=((word)Z80free_doArithmetic(processor,(byte)((value1>>8)&0x00FF),(byte)((value2>>8)&0x00FF),1,isSub))<<8;
|
||||||
|
if (tmp) {
|
||||||
|
Z80free_resFlag(processor,F_Z);
|
||||||
|
} else {
|
||||||
|
Z80free_setFlag(processor,F_Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp&0x08000) {
|
||||||
|
Z80free_setFlag(processor,F_S);
|
||||||
|
} else {
|
||||||
|
Z80free_resFlag(processor,F_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(withCarry|isSub)) {
|
||||||
|
processor->Rm.br.F &= 0x3B; // preserve the new values of C, N, 3, H and 5
|
||||||
|
processor->Rm.br.F |= (Ftmp & 0xC4); // set the old values of P/V, Z and S
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80free_doAND (Z80FREE *processor, byte value) {
|
||||||
|
|
||||||
|
processor->Rm.br.A &= value;
|
||||||
|
Z80free_adjustLogicFlag(processor, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Z80free_doOR (Z80FREE *processor, byte value) {
|
||||||
|
|
||||||
|
processor->Rm.br.A |= value;
|
||||||
|
Z80free_adjustLogicFlag(processor, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Z80free_doXOR (Z80FREE *processor, byte value) {
|
||||||
|
|
||||||
|
processor->Rm.br.A ^= value;
|
||||||
|
Z80free_adjustLogicFlag(processor, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Z80free_doBIT (Z80FREE *processor, int b, byte val) {
|
||||||
|
|
||||||
|
if (val & (1 << b))
|
||||||
|
Z80free_resFlag(processor,F_Z | F_PV);
|
||||||
|
else
|
||||||
|
Z80free_setFlag(processor,F_Z | F_PV);
|
||||||
|
|
||||||
|
Z80free_setFlag(processor,F_H);
|
||||||
|
Z80free_resFlag(processor,F_N);
|
||||||
|
|
||||||
|
|
||||||
|
if ((b == 7) && !Z80free_getFlag(processor,F_Z))
|
||||||
|
Z80free_setFlag(processor,F_S);
|
||||||
|
else
|
||||||
|
Z80free_resFlag(processor,F_S);
|
||||||
|
|
||||||
|
/*Z80free_resFlag(processor,F_5);
|
||||||
|
if ((b == 5) && !Z80free_getFlag(processor,F_Z))
|
||||||
|
Z80free_setFlag(processor,F_5);
|
||||||
|
|
||||||
|
Z80free_resFlag(processor,F_3);
|
||||||
|
if ((b == 3) && !Z80free_getFlag(processor,F_Z))
|
||||||
|
Z80free_setFlag(processor,F_3);*/
|
||||||
|
Z80free_adjustFlags(processor,val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte Z80free_doSetRes (Z80FREE *processor, int bit, int pos, byte val) {
|
||||||
|
|
||||||
|
if (bit)
|
||||||
|
val |= (1 << pos);
|
||||||
|
else
|
||||||
|
val &= ~(1 << pos);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
byte Z80free_doIncDec (Z80FREE *processor, byte val, int isDec) {
|
||||||
|
|
||||||
|
if (isDec) {
|
||||||
|
Z80free_valFlag(processor,F_PV, (val & 0x80) && !((val - 1) & 0x80));
|
||||||
|
val--;
|
||||||
|
Z80free_valFlag(processor,F_H, (val & 0x0F)==0x0F);
|
||||||
|
} else {
|
||||||
|
Z80free_valFlag(processor,F_PV, !(val & 0x80) && ((val + 1) & 0x80));
|
||||||
|
val++;
|
||||||
|
Z80free_valFlag(processor,F_H, (val & 0x0F)==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_S, ((val & 0x80) != 0));
|
||||||
|
Z80free_valFlag(processor,F_Z, (val == 0));
|
||||||
|
Z80free_valFlag(processor,F_N, isDec);
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, val);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
word Z80free_doIncDec16 (Z80FREE *processor, word val, int isDec) {
|
||||||
|
|
||||||
|
if (isDec) {
|
||||||
|
val--;
|
||||||
|
} else {
|
||||||
|
val++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte Z80free_doRLC (Z80FREE *processor, int adjFlags, byte val) {
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_C, (val & 0x80) != 0);
|
||||||
|
val <<= 1;
|
||||||
|
val |= (byte)Z80free_getFlag(processor,F_C);
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, val);
|
||||||
|
Z80free_resFlag(processor,F_H | F_N);
|
||||||
|
|
||||||
|
if (adjFlags)
|
||||||
|
Z80free_adjustFlagSZP(processor, val);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte Z80free_doRL (Z80FREE *processor, int adjFlags, byte val) {
|
||||||
|
|
||||||
|
int CY = Z80free_getFlag(processor,F_C);
|
||||||
|
Z80free_valFlag(processor,F_C, (val & 0x80) != 0);
|
||||||
|
val <<= 1;
|
||||||
|
val |= (byte)CY;
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, val);
|
||||||
|
Z80free_resFlag(processor,F_H | F_N);
|
||||||
|
|
||||||
|
if (adjFlags)
|
||||||
|
Z80free_adjustFlagSZP(processor, val);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte Z80free_doRRC (Z80FREE *processor, int adjFlags, byte val) {
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_C, (val & 0x01) != 0);
|
||||||
|
val >>= 1;
|
||||||
|
val |= ((byte)Z80free_getFlag(processor,F_C) << 7);
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, val);
|
||||||
|
Z80free_resFlag(processor,F_H | F_N);
|
||||||
|
|
||||||
|
if (adjFlags)
|
||||||
|
Z80free_adjustFlagSZP(processor, val);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte Z80free_doRR (Z80FREE *processor, int adjFlags, byte val) {
|
||||||
|
|
||||||
|
int CY = Z80free_getFlag(processor,F_C);
|
||||||
|
Z80free_valFlag(processor,F_C, (val & 0x01));
|
||||||
|
val >>= 1;
|
||||||
|
val |= (CY << 7);
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, val);
|
||||||
|
Z80free_resFlag(processor,F_H | F_N);
|
||||||
|
|
||||||
|
if (adjFlags)
|
||||||
|
Z80free_adjustFlagSZP(processor, val);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte Z80free_doSL (Z80FREE *processor, int isArith, byte val) {
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_C, (val & 0x80) != 0);
|
||||||
|
val <<= 1;
|
||||||
|
|
||||||
|
if (isArith)
|
||||||
|
val |= 1;
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, val);
|
||||||
|
Z80free_resFlag(processor,F_H | F_N);
|
||||||
|
Z80free_adjustFlagSZP(processor, val);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte Z80free_doSR (Z80FREE *processor, int isArith, byte val) {
|
||||||
|
|
||||||
|
static int b;
|
||||||
|
|
||||||
|
b = (val & 0x80);
|
||||||
|
|
||||||
|
Z80free_valFlag(processor,F_C, (val & 0x01) != 0);
|
||||||
|
val >>= 1;
|
||||||
|
|
||||||
|
if (isArith)
|
||||||
|
val |= (byte)b;
|
||||||
|
|
||||||
|
Z80free_adjustFlags(processor, val);
|
||||||
|
Z80free_resFlag(processor,F_H | F_N);
|
||||||
|
Z80free_adjustFlagSZP(processor, val);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80free_doRLD(Z80FREE *processor) {
|
||||||
|
|
||||||
|
static byte tmp,tmp2;
|
||||||
|
|
||||||
|
tmp=processor->Rm.br.A;
|
||||||
|
tmp2=Z80free_Rd(processor->Rm.wr.HL);
|
||||||
|
processor->Rm.br.A&=0xF0;
|
||||||
|
processor->Rm.br.A|=(0x0F&(tmp2>>4));
|
||||||
|
Z80free_Wr(processor->Rm.wr.HL,((tmp2<<4)&0xF0)|(tmp&0x0F));
|
||||||
|
|
||||||
|
Z80free_resFlag(processor,F_H | F_N);
|
||||||
|
Z80free_adjustFlagSZP(processor, processor->Rm.br.A);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80free_doRRD(Z80FREE *processor) {
|
||||||
|
|
||||||
|
static byte tmp,tmp2;
|
||||||
|
|
||||||
|
tmp=processor->Rm.br.A;
|
||||||
|
tmp2=Z80free_Rd(processor->Rm.wr.HL);
|
||||||
|
processor->Rm.br.A&=0xF0;
|
||||||
|
processor->Rm.br.A|=(0x0F&tmp2);
|
||||||
|
Z80free_Wr(processor->Rm.wr.HL,((tmp2>>4)&0x0F)|((tmp<<4)&0xF0));
|
||||||
|
|
||||||
|
Z80free_resFlag(processor,F_H | F_N);
|
||||||
|
Z80free_adjustFlagSZP(processor, processor->Rm.br.A);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80free_doPush (Z80FREE *processor, word val) {
|
||||||
|
|
||||||
|
processor->Rm.wr.SP-=2;
|
||||||
|
Z80free_write16(processor->Rm.wr.SP, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
word Z80free_doPop (Z80FREE *processor) {
|
||||||
|
|
||||||
|
static word val;
|
||||||
|
|
||||||
|
val = Z80free_read16(processor->Rm.wr.SP);
|
||||||
|
processor->Rm.wr.SP+=2;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The DAA opcode
|
||||||
|
* According to the value in A and the flags set, add a value to A
|
||||||
|
*
|
||||||
|
* Flags set Byte (0..9)(0..9)
|
||||||
|
* --------------------------------------------
|
||||||
|
* (None) + &00
|
||||||
|
* Carry:+ &60
|
||||||
|
* Subtract:+ &00
|
||||||
|
* Subtract+Carry:+ &A0
|
||||||
|
* Half-carry:+ &06
|
||||||
|
* Half-carry+Carry:+ &66
|
||||||
|
* Half-carry+Subtract:+ &FA
|
||||||
|
* Half-carry+Subtract+Carry:+ &9A
|
||||||
|
*
|
||||||
|
* Flags set Byte (0..9)(A..F)
|
||||||
|
* --------------------------------------------
|
||||||
|
* (None) + &06
|
||||||
|
* Carry:+ &66
|
||||||
|
* Subtract:+ &00
|
||||||
|
* Subtract+Carry:+ &a0
|
||||||
|
* Half-carry:+ &06
|
||||||
|
* Half-carry+Carry:+ &66
|
||||||
|
* Half-carry+Subtract:+ &fa
|
||||||
|
* Half-carry+Subtract+Carry:+ &9A
|
||||||
|
*
|
||||||
|
* Flags set Byte (A..F)(0..9)
|
||||||
|
* --------------------------------------------
|
||||||
|
* (None) + &60
|
||||||
|
* Carry:+ &60
|
||||||
|
* Subtract:+ &00
|
||||||
|
* Subtract+Carry:+ &A0
|
||||||
|
* Half-carry:+ &66
|
||||||
|
* Half-carry+Carry:+ &66
|
||||||
|
* Half-carry+Subtract:+ &fa
|
||||||
|
* Half-carry+Subtract+Carry:+ &9A
|
||||||
|
*
|
||||||
|
* Flags set Byte (A..F)(A..F)
|
||||||
|
* --------------------------------------------
|
||||||
|
* (None) + &66
|
||||||
|
* Carry:+ &66
|
||||||
|
* Subtract:+ &00
|
||||||
|
* Subtract+Carry:+ &a0
|
||||||
|
* Half-carry:+ &66
|
||||||
|
* Half-carry+Carry:+ &66
|
||||||
|
* Half-carry+Subtract:+ &fa
|
||||||
|
* Half-carry+Subtract+Carry:+ &9A
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int Z80free_DAA_BYTETYPE1[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 };
|
||||||
|
static int Z80free_DAA_BYTETYPE2[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2 };
|
||||||
|
|
||||||
|
static byte Z80free_DAA_ADJUSTMENT[4][6] = {
|
||||||
|
{0x00,0x06,0x00,0x66,0x60,0x66},
|
||||||
|
{0x06,0x06,0x06,0x66,0x66,0x66},
|
||||||
|
{0x60,0x66,0x60,0x66,0x60,0x66},
|
||||||
|
{0x66,0x66,0x66,0x66,0x66,0x66} };
|
||||||
|
|
||||||
|
void Z80free_doDAA (Z80FREE *processor) {
|
||||||
|
|
||||||
|
byte oldval;
|
||||||
|
int byteType;
|
||||||
|
int flagMask = 0;
|
||||||
|
|
||||||
|
/* (0..8)(0..9) = 0 */
|
||||||
|
/* (0..8)(A..F) = 1 */
|
||||||
|
/* (9) (0..9) = 2 */
|
||||||
|
/* (9) (A..F) = 3 */
|
||||||
|
/* (A..F)(0..9) = 4 */
|
||||||
|
/* (A..F)(A..F) = 5 */
|
||||||
|
byteType = Z80free_DAA_BYTETYPE1[(processor->Rm.br.A&0x0F)] | ((Z80free_DAA_BYTETYPE2[(processor->Rm.br.A >> 4)&0x0F]) << 1);
|
||||||
|
oldval=(processor->Rm.br.A&0x0F);
|
||||||
|
|
||||||
|
if (Z80free_getFlag(processor,F_C))
|
||||||
|
flagMask |= 2;
|
||||||
|
if (Z80free_getFlag(processor,F_H))
|
||||||
|
flagMask |= 1;
|
||||||
|
|
||||||
|
if (processor->Rm.br.F&F_N) {
|
||||||
|
processor->Rm.br.A -= Z80free_DAA_ADJUSTMENT[flagMask][byteType];
|
||||||
|
} else {
|
||||||
|
processor->Rm.br.A += Z80free_DAA_ADJUSTMENT[flagMask][byteType];
|
||||||
|
}
|
||||||
|
if ((byteType<3)&&((processor->Rm.br.F&F_C)==0)) {
|
||||||
|
Z80free_resFlag(processor,F_C);
|
||||||
|
} else {
|
||||||
|
Z80free_setFlag(processor,F_C);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((processor->Rm.br.F&F_N)==0) {
|
||||||
|
if (oldval>9) {
|
||||||
|
Z80free_setFlag(processor,F_H);
|
||||||
|
} else {
|
||||||
|
Z80free_resFlag(processor,F_H);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (processor->Rm.br.F&F_H) {
|
||||||
|
if (oldval>5) {
|
||||||
|
Z80free_resFlag(processor,F_H);
|
||||||
|
} else {
|
||||||
|
Z80free_setFlag(processor,F_H);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
processor->Rm.br.F&=0x57;
|
||||||
|
processor->Rm.br.F|=(processor->Rm.br.A&0xA4);
|
||||||
|
if (processor->Rm.br.A) {
|
||||||
|
Z80free_resFlag(processor,F_Z);
|
||||||
|
} else {
|
||||||
|
Z80free_setFlag(processor,F_Z);
|
||||||
|
}
|
||||||
|
Z80free_valFlag(processor,F_PV, Z80free_parityBit[processor->Rm.br.A]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80free_jump_relative(Z80FREE *processor,byte relvar) {
|
||||||
|
|
||||||
|
static word rel2;
|
||||||
|
|
||||||
|
rel2=(word)relvar;
|
||||||
|
if (relvar&0x080) {
|
||||||
|
rel2|=0xFF00;
|
||||||
|
}
|
||||||
|
processor->PC+=rel2;
|
||||||
|
}
|
||||||
|
|
||||||
|
word Z80free_addr_relative(Z80FREE *processor,word address) {
|
||||||
|
|
||||||
|
static word rel2;
|
||||||
|
|
||||||
|
if (processor->IAddr_done) {
|
||||||
|
return (processor->IAddr);
|
||||||
|
}
|
||||||
|
processor->IAddr_done=1;
|
||||||
|
rel2=(word)Z80free_read_param_8(processor);
|
||||||
|
if (rel2&0x080) {
|
||||||
|
rel2|=0xFF00;
|
||||||
|
}
|
||||||
|
processor->IAddr=address+rel2;
|
||||||
|
return (address+rel2);
|
||||||
|
}
|
||||||
|
|
||||||
|
word Z80free_addr_relativeXDCB(Z80FREE *processor,word address,byte d1) {
|
||||||
|
|
||||||
|
static word rel2;
|
||||||
|
|
||||||
|
rel2=(word)d1;
|
||||||
|
if (rel2&0x080) {
|
||||||
|
rel2|=0xFF00;
|
||||||
|
}
|
||||||
|
processor->IAddr=address+rel2;
|
||||||
|
return (address+rel2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80free_write16 (register word addr,register word val) {
|
||||||
|
|
||||||
|
Z80free_Wr(addr, (byte)(val & 0xFF));
|
||||||
|
val >>= 8;
|
||||||
|
addr++;
|
||||||
|
Z80free_Wr(addr, (byte)(val & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
word Z80free_read16 (register word addr) {
|
||||||
|
|
||||||
|
static word v1;
|
||||||
|
v1=((word)Z80free_Rd(addr))&0x00FF;
|
||||||
|
addr++;
|
||||||
|
return (v1 + ((((word)Z80free_Rd(addr)) << 8)&0xFF00));
|
||||||
|
}
|
||||||
|
|
||||||
|
byte Z80free_read_param_8(Z80FREE *processor) {
|
||||||
|
|
||||||
|
return(Z80free_Rd(processor->PC++));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
word Z80free_read_param_16(Z80FREE *processor) {
|
||||||
|
|
||||||
|
static word value;
|
||||||
|
value=Z80free_read16(processor->PC);
|
||||||
|
processor->PC+=2;
|
||||||
|
return (value);
|
||||||
|
}
|
||||||
|
|
153
src/z80free/Z80free.h
Normal file
153
src/z80free/Z80free.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of Z80Free, with some bits extracted
|
||||||
|
* and fixed from libZ80 (from Gabriel Gambetta)
|
||||||
|
*
|
||||||
|
* Z80Free 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Z80Free 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Z80FREE_H
|
||||||
|
#define Z80FREE_H
|
||||||
|
|
||||||
|
#include <machine/endian.h>
|
||||||
|
#ifndef Z80_H
|
||||||
|
typedef unsigned short int word;
|
||||||
|
typedef unsigned char byte;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define F_S 0x80
|
||||||
|
#define F_Z 0x40
|
||||||
|
#define F_5 0x20
|
||||||
|
#define F_H 0x10
|
||||||
|
#define F_3 0x08
|
||||||
|
#define F_PV 0x04
|
||||||
|
#define F_N 0x02
|
||||||
|
#define F_C 0x01
|
||||||
|
|
||||||
|
//enum Z80free_prefix {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD};
|
||||||
|
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
/** Word registers. */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
word AF, BC, DE, HL, IX, IY, SP;
|
||||||
|
} wr;
|
||||||
|
|
||||||
|
/** Byte registers. SP can be accessed partially to simplify the load/save code. */
|
||||||
|
|
||||||
|
|
||||||
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
byte F,A, C,B, E,D, L,H, IXl,IXh, IYl,IYh, P,S;
|
||||||
|
} br;
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
byte A,F, B,C, D,E, H,L, IXh,IXl, IYh,IYl, S,P;
|
||||||
|
} br;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} Z80FRegs;
|
||||||
|
|
||||||
|
/** A Z80 execution context. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Z80FRegs Ra; /* Alternate register set (R) */
|
||||||
|
Z80FRegs Rm; /* Main register set (R) */
|
||||||
|
word PC; /* Program counter */
|
||||||
|
byte R; /* Refresh */
|
||||||
|
byte R2; /* Upper bit for Refresh */
|
||||||
|
byte I;
|
||||||
|
byte IFF1; /* Interrupt Flipflop 1. If it's 2, decrement it and don't allow INT */
|
||||||
|
byte IFF2; /* Interrupt Flipflop 2 */
|
||||||
|
byte IM; /* Interrupt mode */
|
||||||
|
byte HALT; /* HALT status */
|
||||||
|
byte INT_P; /* INT pending */
|
||||||
|
byte NMI_P; /* NMI pending */
|
||||||
|
byte empty_bus; /* value for empty bus when procesing a maskable int */
|
||||||
|
word IAddr; /* address with offset for IX+d and IY+d */
|
||||||
|
byte IAddr_done; /* if 1, IAddr contains a valid data */
|
||||||
|
enum {Z80XX, Z80CB, Z80DD, Z80ED, Z80FD, Z80INT} Status;
|
||||||
|
} Z80FREE;
|
||||||
|
|
||||||
|
/* internal Z80 methods */
|
||||||
|
|
||||||
|
void Z80free_setFlag(Z80FREE *processor, byte flag);
|
||||||
|
void Z80free_resFlag(Z80FREE *processor, byte flag);
|
||||||
|
void Z80free_valFlag(Z80FREE *processor, byte flag, int val);
|
||||||
|
int Z80free_getFlag(Z80FREE *processor, byte flag);
|
||||||
|
void Z80free_adjustFlags (Z80FREE *processor, byte val);
|
||||||
|
void Z80free_adjustFlagSZP (Z80FREE *processor, byte val);
|
||||||
|
void Z80free_adjustLogicFlag (Z80FREE *processor, int flagH);
|
||||||
|
byte Z80free_doArithmetic (Z80FREE *processor, byte value1,byte value2, int withCarry, int isSub);
|
||||||
|
word Z80free_doArithmetic16 (Z80FREE *processor, word value1,word value2, int withCarry, int isSub);
|
||||||
|
void Z80free_doAND (Z80FREE *processor, byte value);
|
||||||
|
void Z80free_doOR (Z80FREE *processor, byte value);
|
||||||
|
void Z80free_doXOR (Z80FREE *processor, byte value);
|
||||||
|
void Z80free_doBIT (Z80FREE *processor, int b, byte val);
|
||||||
|
byte Z80free_doSetRes (Z80FREE *processor, int bit, int pos, byte val);
|
||||||
|
byte Z80free_doIncDec (Z80FREE *processor, byte val, int isDec);
|
||||||
|
word Z80free_doIncDec16 (Z80FREE *processor, word val, int isDec);
|
||||||
|
byte Z80free_doRLC (Z80FREE *processor, int adjFlags, byte val);
|
||||||
|
byte Z80free_doRL (Z80FREE *processor, int adjFlags, byte val);
|
||||||
|
byte Z80free_doRRC (Z80FREE *processor, int adjFlags, byte val);
|
||||||
|
byte Z80free_doRR (Z80FREE *processor, int adjFlags, byte val);
|
||||||
|
byte Z80free_doSL (Z80FREE *processor, int isArith, byte val);
|
||||||
|
byte Z80free_doSR (Z80FREE *processor, int isArith, byte val);
|
||||||
|
void Z80free_doPush (Z80FREE *processor, word val);
|
||||||
|
word Z80free_doPop (Z80FREE *processor);
|
||||||
|
void Z80free_doDAA (Z80FREE *processor);
|
||||||
|
byte Z80free_readR(Z80FREE *processor);
|
||||||
|
void Z80free_setR(Z80FREE *processor,byte value);
|
||||||
|
byte Z80free_readI(Z80FREE *processor);
|
||||||
|
void Z80free_doRRD(Z80FREE *processor);
|
||||||
|
void Z80free_doRLD(Z80FREE *processor);
|
||||||
|
|
||||||
|
void Z80free_jump_relative(Z80FREE *processor,byte relvar);
|
||||||
|
word Z80free_addr_relative(Z80FREE *processor,word address);
|
||||||
|
word Z80free_addr_relativeXDCB(Z80FREE *processor,word address,byte d1);
|
||||||
|
byte Z80free_read_param_8(Z80FREE *z80);
|
||||||
|
word Z80free_read_param_16(Z80FREE *z80);
|
||||||
|
word Z80free_read16 (register word addr);
|
||||||
|
void Z80free_write16 (register word addr,register word val);
|
||||||
|
|
||||||
|
/* external Z80 methods */
|
||||||
|
|
||||||
|
void Z80free_reset(Z80FREE *);
|
||||||
|
int Z80free_step(Z80FREE *);
|
||||||
|
int Z80free_ustep(Z80FREE *);
|
||||||
|
void Z80free_INT(Z80FREE *,byte);
|
||||||
|
|
||||||
|
byte Z80free_Rd (register word Addr);
|
||||||
|
void Z80free_Wr (register word Addr, register byte Value);
|
||||||
|
byte Z80free_In (register word Port);
|
||||||
|
void Z80free_Out (register word Port, register byte Value);
|
||||||
|
|
||||||
|
/* Opcode functions */
|
||||||
|
|
||||||
|
int Z80free_codes (Z80FREE *processor,byte opcode);
|
||||||
|
int Z80free_codesCB (Z80FREE *processor,byte opcode);
|
||||||
|
int Z80free_codesDD (Z80FREE *processor,byte opcode);
|
||||||
|
int Z80free_codesED (Z80FREE *processor,byte opcode);
|
||||||
|
int Z80free_codesFD (Z80FREE *processor,byte opcode);
|
||||||
|
int Z80free_codesDDCB (Z80FREE *processor,byte d1);
|
||||||
|
int Z80free_codesFDCB (Z80FREE *processor,byte d1);
|
||||||
|
|
||||||
|
#endif
|
1242
src/z80free/Z80free_codes.c
Normal file
1242
src/z80free/Z80free_codes.c
Normal file
File diff suppressed because it is too large
Load Diff
259
src/z80free/Z80free_codes.txt
Normal file
259
src/z80free/Z80free_codes.txt
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
# OPCODES, TSTATES and INSTRUCTIONS for not prefixed instructions
|
||||||
|
# some syntax have been modified (like JP (HL) to JP HL, or Carry
|
||||||
|
# condition from C to CF) to simplify the parser
|
||||||
|
00 4 NOP
|
||||||
|
01 10 LD BC,nn
|
||||||
|
02 7 LD (BC),A
|
||||||
|
03 6 INC BC
|
||||||
|
04 4 INC B
|
||||||
|
05 4 DEC B
|
||||||
|
06 7 LD B,n
|
||||||
|
07 4 RLCA
|
||||||
|
08 4 EX AF,AF'
|
||||||
|
09 11 ADD HL,BC
|
||||||
|
0A 7 LD A,(BC)
|
||||||
|
0B 6 DEC BC
|
||||||
|
0C 4 INC C
|
||||||
|
0D 4 DEC C
|
||||||
|
0E 7 LD C,n
|
||||||
|
0F 4 RRCA
|
||||||
|
10 13/8 DJNZ n
|
||||||
|
11 10 LD DE,nn
|
||||||
|
12 7 LD (DE),A
|
||||||
|
13 6 INC DE
|
||||||
|
14 4 INC D
|
||||||
|
15 4 DEC D
|
||||||
|
16 7 LD D,n
|
||||||
|
17 4 RLA
|
||||||
|
18 12 JR n
|
||||||
|
19 11 ADD HL,DE
|
||||||
|
1A 7 LD A,(DE)
|
||||||
|
1B 6 DEC DE
|
||||||
|
1C 4 INC E
|
||||||
|
1D 4 DEC E
|
||||||
|
1E 7 LD E,n
|
||||||
|
1F 4 RRA
|
||||||
|
20 12/7 JR NZ,n
|
||||||
|
21 10 LD HL,nn
|
||||||
|
22 16 LD (nn),HL
|
||||||
|
23 6 INC HL
|
||||||
|
24 4 INC H
|
||||||
|
25 4 DEC H
|
||||||
|
26 7 LD H,n
|
||||||
|
27 4 DAA
|
||||||
|
28 12/7 JR Z,n
|
||||||
|
29 11 ADD HL,HL
|
||||||
|
2A 16 LD HL,(nn)
|
||||||
|
2B 6 DEC HL
|
||||||
|
2C 4 INC L
|
||||||
|
2D 4 DEC L
|
||||||
|
2E 7 LD L,n
|
||||||
|
2F 4 CPL
|
||||||
|
30 12/7 JR NC,n
|
||||||
|
31 10 LD SP,nn
|
||||||
|
32 13 LD (nn),A
|
||||||
|
33 6 INC SP
|
||||||
|
34 11 INC b(HL)
|
||||||
|
35 11 DEC b(HL)
|
||||||
|
36 10 LD (HL),n
|
||||||
|
37 4 SCF
|
||||||
|
38 12/7 JR CF,n
|
||||||
|
39 11 ADD HL,SP
|
||||||
|
3A 13 LD A,(nn)
|
||||||
|
3B 6 DEC SP
|
||||||
|
3C 4 INC A
|
||||||
|
3D 4 DEC A
|
||||||
|
3E 7 LD A,n
|
||||||
|
3F 4 CCF
|
||||||
|
40 4 LD B,B
|
||||||
|
41 4 LD B,C
|
||||||
|
42 4 LD B,D
|
||||||
|
43 4 LD B,E
|
||||||
|
44 4 LD B,H
|
||||||
|
45 4 LD B,L
|
||||||
|
46 7 LD B,(HL)
|
||||||
|
47 4 LD B,A
|
||||||
|
48 4 LD C,B
|
||||||
|
49 4 LD C,C
|
||||||
|
4A 4 LD C,D
|
||||||
|
4B 4 LD C,E
|
||||||
|
4C 4 LD C,H
|
||||||
|
4D 4 LD C,L
|
||||||
|
4E 7 LD C,(HL)
|
||||||
|
4F 4 LD C,A
|
||||||
|
50 4 LD D,B
|
||||||
|
51 4 LD D,C
|
||||||
|
52 4 LD D,D
|
||||||
|
53 4 LD D,E
|
||||||
|
54 4 LD D,H
|
||||||
|
55 4 LD D,L
|
||||||
|
56 7 LD D,(HL)
|
||||||
|
57 4 LD D,A
|
||||||
|
58 4 LD E,B
|
||||||
|
59 4 LD E,C
|
||||||
|
5A 4 LD E,D
|
||||||
|
5B 4 LD E,E
|
||||||
|
5C 4 LD E,H
|
||||||
|
5D 4 LD E,L
|
||||||
|
5E 7 LD E,(HL)
|
||||||
|
5F 4 LD E,A
|
||||||
|
60 4 LD H,B
|
||||||
|
61 4 LD H,C
|
||||||
|
62 4 LD H,D
|
||||||
|
63 4 LD H,E
|
||||||
|
64 4 LD H,H
|
||||||
|
65 4 LD H,L
|
||||||
|
66 7 LD H,(HL)
|
||||||
|
67 4 LD H,A
|
||||||
|
68 4 LD L,B
|
||||||
|
69 4 LD L,C
|
||||||
|
6A 4 LD L,D
|
||||||
|
6B 4 LD L,E
|
||||||
|
6C 4 LD L,H
|
||||||
|
6D 4 LD L,L
|
||||||
|
6E 7 LD L,(HL)
|
||||||
|
6F 4 LD L,A
|
||||||
|
70 7 LD (HL),B
|
||||||
|
71 7 LD (HL),C
|
||||||
|
72 7 LD (HL),D
|
||||||
|
73 7 LD (HL),E
|
||||||
|
74 7 LD (HL),H
|
||||||
|
75 7 LD (HL),L
|
||||||
|
76 4 HALT
|
||||||
|
77 7 LD (HL),A
|
||||||
|
78 4 LD A,B
|
||||||
|
79 4 LD A,C
|
||||||
|
7A 4 LD A,D
|
||||||
|
7B 4 LD A,E
|
||||||
|
7C 4 LD A,H
|
||||||
|
7D 4 LD A,L
|
||||||
|
7E 7 LD A,(HL)
|
||||||
|
7F 4 LD A,A
|
||||||
|
80 4 ADD A,B
|
||||||
|
81 4 ADD A,C
|
||||||
|
82 4 ADD A,D
|
||||||
|
83 4 ADD A,E
|
||||||
|
84 4 ADD A,H
|
||||||
|
85 4 ADD A,L
|
||||||
|
86 7 ADD A,(HL)
|
||||||
|
87 4 ADD A,A
|
||||||
|
88 4 ADC A,B
|
||||||
|
89 4 ADC A,C
|
||||||
|
8A 4 ADC A,D
|
||||||
|
8B 4 ADC A,E
|
||||||
|
8C 4 ADC A,H
|
||||||
|
8D 4 ADC A,L
|
||||||
|
8E 7 ADC A,(HL)
|
||||||
|
8F 4 ADC A,A
|
||||||
|
90 4 SUB B
|
||||||
|
91 4 SUB C
|
||||||
|
92 4 SUB D
|
||||||
|
93 4 SUB E
|
||||||
|
94 4 SUB H
|
||||||
|
95 4 SUB L
|
||||||
|
96 7 SUB b(HL)
|
||||||
|
97 4 SUB A
|
||||||
|
98 4 SBC A,B
|
||||||
|
99 4 SBC A,C
|
||||||
|
9A 4 SBC A,D
|
||||||
|
9B 4 SBC A,E
|
||||||
|
9C 4 SBC A,H
|
||||||
|
9D 4 SBC A,L
|
||||||
|
9E 7 SBC A,(HL)
|
||||||
|
9F 4 SBC A,A
|
||||||
|
A0 4 AND B
|
||||||
|
A1 4 AND C
|
||||||
|
A2 4 AND D
|
||||||
|
A3 4 AND E
|
||||||
|
A4 4 AND H
|
||||||
|
A5 4 AND L
|
||||||
|
A6 7 AND b(HL)
|
||||||
|
A7 4 AND A
|
||||||
|
A8 4 XOR B
|
||||||
|
A9 4 XOR C
|
||||||
|
AA 4 XOR D
|
||||||
|
AB 4 XOR E
|
||||||
|
AC 4 XOR H
|
||||||
|
AD 4 XOR L
|
||||||
|
AE 7 XOR b(HL)
|
||||||
|
AF 4 XOR A
|
||||||
|
B0 4 OR B
|
||||||
|
B1 4 OR C
|
||||||
|
B2 4 OR D
|
||||||
|
B3 4 OR E
|
||||||
|
B4 4 OR H
|
||||||
|
B5 4 OR L
|
||||||
|
B6 7 OR b(HL)
|
||||||
|
B7 4 OR A
|
||||||
|
B8 4 CP B
|
||||||
|
B9 4 CP C
|
||||||
|
BA 4 CP D
|
||||||
|
BB 4 CP E
|
||||||
|
BC 4 CP H
|
||||||
|
BD 4 CP L
|
||||||
|
BE 7 CP b(HL)
|
||||||
|
BF 4 CP A
|
||||||
|
C0 11/5 RET NZ
|
||||||
|
C1 10 POP BC
|
||||||
|
C2 10 JP NZ,nn
|
||||||
|
C3 10 JP nn
|
||||||
|
C4 17/10 CALL NZ,nn
|
||||||
|
C5 11 PUSH BC
|
||||||
|
C6 7 ADD A,n
|
||||||
|
C7 11 RST 0H
|
||||||
|
C8 11/5 RET Z
|
||||||
|
C9 10 RET
|
||||||
|
CA 10 JP Z,nn
|
||||||
|
CB * PREFIX
|
||||||
|
CC 17/10 CALL Z,nn
|
||||||
|
CD 17 CALL nn
|
||||||
|
CE 7 ADC A,n
|
||||||
|
CF 11 RST 8H
|
||||||
|
D0 11/5 RET NC
|
||||||
|
D1 10 POP DE
|
||||||
|
D2 10 JP NC,nn
|
||||||
|
D3 11 OUT n,A
|
||||||
|
D4 17/10 CALL NC,nn
|
||||||
|
D5 11 PUSH DE
|
||||||
|
D6 7 SUB n
|
||||||
|
D7 11 RST 10H
|
||||||
|
D8 11/5 RET CF
|
||||||
|
D9 4 EXX
|
||||||
|
DA 10 JP CF,nn
|
||||||
|
DB 11 IN A,n
|
||||||
|
DC 17/10 CALL CF,nn
|
||||||
|
DD * PREFIX
|
||||||
|
DE 7 SBC A,n
|
||||||
|
DF 11 RST 18H
|
||||||
|
E0 11/5 RET PO
|
||||||
|
E1 10 POP HL
|
||||||
|
E2 10 JP PO,nn
|
||||||
|
E3 19 EX (SP),HL
|
||||||
|
E4 17/10 CALL PO,nn
|
||||||
|
E5 11 PUSH HL
|
||||||
|
E6 7 AND n
|
||||||
|
E7 11 RST 20H
|
||||||
|
E8 11/5 RET PE
|
||||||
|
E9 4 JP HL
|
||||||
|
EA 10 JP PE,nn
|
||||||
|
EB 4 EX DE,HL
|
||||||
|
EC 17/10 CALL PE,nn
|
||||||
|
ED * PREFIX
|
||||||
|
EE 7 XOR n
|
||||||
|
EF 11 RST 28H
|
||||||
|
F0 11/5 RET P
|
||||||
|
F1 10 POP AF
|
||||||
|
F2 10 JP P,nn
|
||||||
|
F3 4 DI
|
||||||
|
F4 17/10 CALL P,nn
|
||||||
|
F5 11 PUSH AF
|
||||||
|
F6 7 OR n
|
||||||
|
F7 11 RST 30H
|
||||||
|
F8 11/5 RET M
|
||||||
|
F9 6 LD SP,HL
|
||||||
|
FA 10 JP M,nn
|
||||||
|
FB 4 EI
|
||||||
|
FC 17/10 CALL M,nn
|
||||||
|
FD * PREFIX
|
||||||
|
FE 7 CP n
|
||||||
|
FF 11 RST 38H
|
1052
src/z80free/Z80free_codesCB.c
Normal file
1052
src/z80free/Z80free_codesCB.c
Normal file
File diff suppressed because it is too large
Load Diff
259
src/z80free/Z80free_codesCB.txt
Normal file
259
src/z80free/Z80free_codesCB.txt
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
# OPCODES, TSTATES and INSTRUCTIONS for CB prefixed instructions
|
||||||
|
# The TSTATES are 4 less than the real ones because they are counted
|
||||||
|
# when executing the CB prefix
|
||||||
|
00 4 RLC B
|
||||||
|
01 4 RLC C
|
||||||
|
02 4 RLC D
|
||||||
|
03 4 RLC E
|
||||||
|
04 4 RLC H
|
||||||
|
05 4 RLC L
|
||||||
|
06 11 RLC b(HL)
|
||||||
|
07 4 RLC A
|
||||||
|
08 4 RRC B
|
||||||
|
09 4 RRC C
|
||||||
|
0A 4 RRC D
|
||||||
|
0B 4 RRC E
|
||||||
|
0C 4 RRC H
|
||||||
|
0D 4 RRC L
|
||||||
|
0E 11 RRC b(HL)
|
||||||
|
0F 4 RRC A
|
||||||
|
10 4 RL B
|
||||||
|
11 4 RL C
|
||||||
|
12 4 RL D
|
||||||
|
13 4 RL E
|
||||||
|
14 4 RL H
|
||||||
|
15 4 RL L
|
||||||
|
16 11 RL b(HL)
|
||||||
|
17 4 RL A
|
||||||
|
18 4 RR B
|
||||||
|
19 4 RR C
|
||||||
|
1A 4 RR D
|
||||||
|
1B 4 RR E
|
||||||
|
1C 4 RR H
|
||||||
|
1D 4 RR L
|
||||||
|
1E 11 RR b(HL)
|
||||||
|
1F 4 RR A
|
||||||
|
20 4 SLA B
|
||||||
|
21 4 SLA C
|
||||||
|
22 4 SLA D
|
||||||
|
23 4 SLA E
|
||||||
|
24 4 SLA H
|
||||||
|
25 4 SLA L
|
||||||
|
26 11 SLA b(HL)
|
||||||
|
27 4 SLA A
|
||||||
|
28 4 SRA B
|
||||||
|
29 4 SRA C
|
||||||
|
2A 4 SRA D
|
||||||
|
2B 4 SRA E
|
||||||
|
2C 4 SRA H
|
||||||
|
2D 4 SRA L
|
||||||
|
2E 11 SRA b(HL)
|
||||||
|
2F 4 SRA A
|
||||||
|
30 4 SLL B
|
||||||
|
31 4 SLL C
|
||||||
|
32 4 SLL D
|
||||||
|
33 4 SLL E
|
||||||
|
34 4 SLL H
|
||||||
|
35 4 SLL L
|
||||||
|
36 11 SLL b(HL)
|
||||||
|
37 4 SLL A
|
||||||
|
38 4 SRL B
|
||||||
|
39 4 SRL C
|
||||||
|
3A 4 SRL D
|
||||||
|
3B 4 SRL E
|
||||||
|
3C 4 SRL H
|
||||||
|
3D 4 SRL L
|
||||||
|
3E 11 SRL b(HL)
|
||||||
|
3F 4 SRL A
|
||||||
|
40 4 BIT 0,B
|
||||||
|
41 4 BIT 0,C
|
||||||
|
42 4 BIT 0,D
|
||||||
|
43 4 BIT 0,E
|
||||||
|
44 4 BIT 0,H
|
||||||
|
45 4 BIT 0,L
|
||||||
|
46 8 BIT 0,(HL)
|
||||||
|
47 4 BIT 0,A
|
||||||
|
48 4 BIT 1,B
|
||||||
|
49 4 BIT 1,C
|
||||||
|
4A 4 BIT 1,D
|
||||||
|
4B 4 BIT 1,E
|
||||||
|
4C 4 BIT 1,H
|
||||||
|
4D 4 BIT 1,L
|
||||||
|
4E 8 BIT 1,(HL)
|
||||||
|
4F 4 BIT 1,A
|
||||||
|
50 4 BIT 2,B
|
||||||
|
51 4 BIT 2,C
|
||||||
|
52 4 BIT 2,D
|
||||||
|
53 4 BIT 2,E
|
||||||
|
54 4 BIT 2,H
|
||||||
|
55 4 BIT 2,L
|
||||||
|
56 8 BIT 2,(HL)
|
||||||
|
57 4 BIT 2,A
|
||||||
|
58 4 BIT 3,B
|
||||||
|
59 4 BIT 3,C
|
||||||
|
5A 4 BIT 3,D
|
||||||
|
5B 4 BIT 3,E
|
||||||
|
5C 4 BIT 3,H
|
||||||
|
5D 4 BIT 3,L
|
||||||
|
5E 8 BIT 3,(HL)
|
||||||
|
5F 4 BIT 3,A
|
||||||
|
60 4 BIT 4,B
|
||||||
|
61 4 BIT 4,C
|
||||||
|
62 4 BIT 4,D
|
||||||
|
63 4 BIT 4,E
|
||||||
|
64 4 BIT 4,H
|
||||||
|
65 4 BIT 4,L
|
||||||
|
66 8 BIT 4,(HL)
|
||||||
|
67 4 BIT 4,A
|
||||||
|
68 4 BIT 5,B
|
||||||
|
69 4 BIT 5,C
|
||||||
|
6A 4 BIT 5,D
|
||||||
|
6B 4 BIT 5,E
|
||||||
|
6C 4 BIT 5,H
|
||||||
|
6D 4 BIT 5,L
|
||||||
|
6E 8 BIT 5,(HL)
|
||||||
|
6F 4 BIT 5,A
|
||||||
|
70 4 BIT 6,B
|
||||||
|
71 4 BIT 6,C
|
||||||
|
72 4 BIT 6,D
|
||||||
|
73 4 BIT 6,E
|
||||||
|
74 4 BIT 6,H
|
||||||
|
75 4 BIT 6,L
|
||||||
|
76 8 BIT 6,(HL)
|
||||||
|
77 4 BIT 6,A
|
||||||
|
78 4 BIT 7,B
|
||||||
|
79 4 BIT 7,C
|
||||||
|
7A 4 BIT 7,D
|
||||||
|
7B 4 BIT 7,E
|
||||||
|
7C 4 BIT 7,H
|
||||||
|
7D 4 BIT 7,L
|
||||||
|
7E 8 BIT 7,(HL)
|
||||||
|
7F 4 BIT 7,A
|
||||||
|
80 4 RES 0,B
|
||||||
|
81 4 RES 0,C
|
||||||
|
82 4 RES 0,D
|
||||||
|
83 4 RES 0,E
|
||||||
|
84 4 RES 0,H
|
||||||
|
85 4 RES 0,L
|
||||||
|
86 11 RES 0,(HL)
|
||||||
|
87 4 RES 0,A
|
||||||
|
88 4 RES 1,B
|
||||||
|
89 4 RES 1,C
|
||||||
|
8A 4 RES 1,D
|
||||||
|
8B 4 RES 1,E
|
||||||
|
8C 4 RES 1,H
|
||||||
|
8D 4 RES 1,L
|
||||||
|
8E 11 RES 1,(HL)
|
||||||
|
8F 4 RES 1,A
|
||||||
|
90 4 RES 2,B
|
||||||
|
91 4 RES 2,C
|
||||||
|
92 4 RES 2,D
|
||||||
|
93 4 RES 2,E
|
||||||
|
94 4 RES 2,H
|
||||||
|
95 4 RES 2,L
|
||||||
|
96 11 RES 2,(HL)
|
||||||
|
97 4 RES 2,A
|
||||||
|
98 4 RES 3,B
|
||||||
|
99 4 RES 3,C
|
||||||
|
9A 4 RES 3,D
|
||||||
|
9B 4 RES 3,E
|
||||||
|
9C 4 RES 3,H
|
||||||
|
9D 4 RES 3,L
|
||||||
|
9E 11 RES 3,(HL)
|
||||||
|
9F 4 RES 3,A
|
||||||
|
A0 4 RES 4,B
|
||||||
|
A1 4 RES 4,C
|
||||||
|
A2 4 RES 4,D
|
||||||
|
A3 4 RES 4,E
|
||||||
|
A4 4 RES 4,H
|
||||||
|
A5 4 RES 4,L
|
||||||
|
A6 11 RES 4,(HL)
|
||||||
|
A7 4 RES 4,A
|
||||||
|
A8 4 RES 5,B
|
||||||
|
A9 4 RES 5,C
|
||||||
|
AA 4 RES 5,D
|
||||||
|
AB 4 RES 5,E
|
||||||
|
AC 4 RES 5,H
|
||||||
|
AD 4 RES 5,L
|
||||||
|
AE 11 RES 5,(HL)
|
||||||
|
AF 4 RES 5,A
|
||||||
|
B0 4 RES 6,B
|
||||||
|
B1 4 RES 6,C
|
||||||
|
B2 4 RES 6,D
|
||||||
|
B3 4 RES 6,E
|
||||||
|
B4 4 RES 6,H
|
||||||
|
B5 4 RES 6,L
|
||||||
|
B6 11 RES 6,(HL)
|
||||||
|
B7 4 RES 6,A
|
||||||
|
B8 4 RES 7,B
|
||||||
|
B9 4 RES 7,C
|
||||||
|
BA 4 RES 7,D
|
||||||
|
BB 4 RES 7,E
|
||||||
|
BC 4 RES 7,H
|
||||||
|
BD 4 RES 7,L
|
||||||
|
BE 11 RES 7,(HL)
|
||||||
|
BF 4 RES 7,A
|
||||||
|
C0 4 SET 0,B
|
||||||
|
C1 4 SET 0,C
|
||||||
|
C2 4 SET 0,D
|
||||||
|
C3 4 SET 0,E
|
||||||
|
C4 4 SET 0,H
|
||||||
|
C5 4 SET 0,L
|
||||||
|
C6 11 SET 0,(HL)
|
||||||
|
C7 4 SET 0,A
|
||||||
|
C8 4 SET 1,B
|
||||||
|
C9 4 SET 1,C
|
||||||
|
CA 4 SET 1,D
|
||||||
|
CB 4 SET 1,E
|
||||||
|
CC 4 SET 1,H
|
||||||
|
CD 4 SET 1,L
|
||||||
|
CE 11 SET 1,(HL)
|
||||||
|
CF 4 SET 1,A
|
||||||
|
D0 4 SET 2,B
|
||||||
|
D1 4 SET 2,C
|
||||||
|
D2 4 SET 2,D
|
||||||
|
D3 4 SET 2,E
|
||||||
|
D4 4 SET 2,H
|
||||||
|
D5 4 SET 2,L
|
||||||
|
D6 11 SET 2,(HL)
|
||||||
|
D7 4 SET 2,A
|
||||||
|
D8 4 SET 3,B
|
||||||
|
D9 4 SET 3,C
|
||||||
|
DA 4 SET 3,D
|
||||||
|
DB 4 SET 3,E
|
||||||
|
DC 4 SET 3,H
|
||||||
|
DD 4 SET 3,L
|
||||||
|
DE 11 SET 3,(HL)
|
||||||
|
DF 4 SET 3,A
|
||||||
|
E0 4 SET 4,B
|
||||||
|
E1 4 SET 4,C
|
||||||
|
E2 4 SET 4,D
|
||||||
|
E3 4 SET 4,E
|
||||||
|
E4 4 SET 4,H
|
||||||
|
E5 4 SET 4,L
|
||||||
|
E6 11 SET 4,(HL)
|
||||||
|
E7 4 SET 4,A
|
||||||
|
E8 4 SET 5,B
|
||||||
|
E9 4 SET 5,C
|
||||||
|
EA 4 SET 5,D
|
||||||
|
EB 4 SET 5,E
|
||||||
|
EC 4 SET 5,H
|
||||||
|
ED 4 SET 5,L
|
||||||
|
EE 11 SET 5,(HL)
|
||||||
|
EF 4 SET 5,A
|
||||||
|
F0 4 SET 6,B
|
||||||
|
F1 4 SET 6,C
|
||||||
|
F2 4 SET 6,D
|
||||||
|
F3 4 SET 6,E
|
||||||
|
F4 4 SET 6,H
|
||||||
|
F5 4 SET 6,L
|
||||||
|
F6 11 SET 6,(HL)
|
||||||
|
F7 4 SET 6,A
|
||||||
|
F8 4 SET 7,B
|
||||||
|
F9 4 SET 7,C
|
||||||
|
FA 4 SET 7,D
|
||||||
|
FB 4 SET 7,E
|
||||||
|
FC 4 SET 7,H
|
||||||
|
FD 4 SET 7,L
|
||||||
|
FE 11 SET 7,(HL)
|
||||||
|
FF 4 SET 7,A
|
890
src/z80free/Z80free_codesDD.c
Normal file
890
src/z80free/Z80free_codesDD.c
Normal file
@ -0,0 +1,890 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008-2009 Sergio Costas (Raster Software Vigo)
|
||||||
|
* This file is part of Z80Free
|
||||||
|
*
|
||||||
|
* Z80Free 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Z80Free 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Z80free.h"
|
||||||
|
|
||||||
|
int Z80free_codesDD (Z80FREE *processor,byte opcode) {
|
||||||
|
static byte tmp1;
|
||||||
|
static word tmp2;
|
||||||
|
|
||||||
|
switch(opcode) {
|
||||||
|
case 0: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 1: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 2: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 3: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 4: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 5: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 6: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 7: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 8: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 9: // ADD IX,BC
|
||||||
|
processor->Rm.wr.IX=Z80free_doArithmetic16(processor,processor->Rm.wr.IX,processor->Rm.wr.BC,0,0);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 10: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 11: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 12: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 13: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 14: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 15: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 16: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 17: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 18: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 19: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 20: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 21: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 22: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 23: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 24: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 25: // ADD IX,DE
|
||||||
|
processor->Rm.wr.IX=Z80free_doArithmetic16(processor,processor->Rm.wr.IX,processor->Rm.wr.DE,0,0);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 26: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 27: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 28: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 29: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 30: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 31: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 32: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 33: // LD IX,nn
|
||||||
|
processor->Rm.wr.IX=Z80free_read_param_16(processor);
|
||||||
|
return (10);
|
||||||
|
break;
|
||||||
|
case 34: // LD (nn),IX
|
||||||
|
Z80free_write16(Z80free_read_param_16(processor),processor->Rm.wr.IX);
|
||||||
|
return (16);
|
||||||
|
break;
|
||||||
|
case 35: // INC IX
|
||||||
|
processor->Rm.wr.IX=Z80free_doIncDec16(processor,processor->Rm.wr.IX,0);
|
||||||
|
return (6);
|
||||||
|
break;
|
||||||
|
case 36: // INC IXH
|
||||||
|
processor->Rm.br.IXh=Z80free_doIncDec(processor,processor->Rm.br.IXh,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 37: // DEC IXH
|
||||||
|
processor->Rm.br.IXh=Z80free_doIncDec(processor,processor->Rm.br.IXh,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 38: // LD IXH,n
|
||||||
|
processor->Rm.br.IXh=Z80free_read_param_8(processor);
|
||||||
|
return (7);
|
||||||
|
break;
|
||||||
|
case 39: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 40: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 41: // ADD IX,IX
|
||||||
|
processor->Rm.wr.IX=Z80free_doArithmetic16(processor,processor->Rm.wr.IX,processor->Rm.wr.IX,0,0);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 42: // LD IX,(nn)
|
||||||
|
processor->Rm.wr.IX=Z80free_read16(Z80free_read_param_16(processor));
|
||||||
|
return (16);
|
||||||
|
break;
|
||||||
|
case 43: // DEC IX
|
||||||
|
processor->Rm.wr.IX=Z80free_doIncDec16(processor,processor->Rm.wr.IX,1);
|
||||||
|
return (6);
|
||||||
|
break;
|
||||||
|
case 44: // INC IXL
|
||||||
|
processor->Rm.br.IXl=Z80free_doIncDec(processor,processor->Rm.br.IXl,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 45: // DEC IXL
|
||||||
|
processor->Rm.br.IXl=Z80free_doIncDec(processor,processor->Rm.br.IXl,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 46: // LD IXL,n
|
||||||
|
processor->Rm.br.IXl=Z80free_read_param_8(processor);
|
||||||
|
return (7);
|
||||||
|
break;
|
||||||
|
case 47: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 48: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 49: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 50: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 51: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 52: // INC b(IX+d)
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),Z80free_doIncDec(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)),0));
|
||||||
|
return (19);
|
||||||
|
break;
|
||||||
|
case 53: // DEC b(IX+d)
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),Z80free_doIncDec(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)),1));
|
||||||
|
return (19);
|
||||||
|
break;
|
||||||
|
case 54: // LD2 IX+d,n
|
||||||
|
tmp2=Z80free_addr_relative(processor,processor->Rm.wr.IX);
|
||||||
|
Z80free_Wr(tmp2,Z80free_read_param_8(processor));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 55: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 56: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 57: // ADD IX,SP
|
||||||
|
processor->Rm.wr.IX=Z80free_doArithmetic16(processor,processor->Rm.wr.IX,processor->Rm.wr.SP,0,0);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 58: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 59: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 60: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 61: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 62: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 63: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 64: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 65: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 66: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 67: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 68: // LD B,IXH
|
||||||
|
processor->Rm.br.B=processor->Rm.br.IXh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 69: // LD B,IXL
|
||||||
|
processor->Rm.br.B=processor->Rm.br.IXl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 70: // LD B,(IX+d)
|
||||||
|
processor->Rm.br.B=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 71: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 72: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 73: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 74: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 75: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 76: // LD C,IXH
|
||||||
|
processor->Rm.br.C=processor->Rm.br.IXh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 77: // LD C,IXL
|
||||||
|
processor->Rm.br.C=processor->Rm.br.IXl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 78: // LD C,(IX+d)
|
||||||
|
processor->Rm.br.C=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 79: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 80: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 81: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 82: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 83: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 84: // LD D,IXH
|
||||||
|
processor->Rm.br.D=processor->Rm.br.IXh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 85: // LD D,IXL
|
||||||
|
processor->Rm.br.D=processor->Rm.br.IXl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 86: // LD D,(IX+d)
|
||||||
|
processor->Rm.br.D=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 87: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 88: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 89: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 90: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 91: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 92: // LD E,IXH
|
||||||
|
processor->Rm.br.E=processor->Rm.br.IXh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 93: // LD E,IXL
|
||||||
|
processor->Rm.br.E=processor->Rm.br.IXl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 94: // LD E,(IX+d)
|
||||||
|
processor->Rm.br.E=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 95: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 96: // LD IXH,B
|
||||||
|
processor->Rm.br.IXh=processor->Rm.br.B;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 97: // LD IXH,C
|
||||||
|
processor->Rm.br.IXh=processor->Rm.br.C;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 98: // LD IXH,D
|
||||||
|
processor->Rm.br.IXh=processor->Rm.br.D;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 99: // LD IXH,E
|
||||||
|
processor->Rm.br.IXh=processor->Rm.br.E;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 100: // LD IXH,IXH
|
||||||
|
processor->Rm.br.IXh=processor->Rm.br.IXh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 101: // LD IXH,IXL
|
||||||
|
processor->Rm.br.IXh=processor->Rm.br.IXl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 102: // LD H,(IX+d)
|
||||||
|
processor->Rm.br.H=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 103: // LD IXH,A
|
||||||
|
processor->Rm.br.IXh=processor->Rm.br.A;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 104: // LD IXL,B
|
||||||
|
processor->Rm.br.IXl=processor->Rm.br.B;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 105: // LD IXL,C
|
||||||
|
processor->Rm.br.IXl=processor->Rm.br.C;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 106: // LD IXL,D
|
||||||
|
processor->Rm.br.IXl=processor->Rm.br.D;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 107: // LD IXL,E
|
||||||
|
processor->Rm.br.IXl=processor->Rm.br.E;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 108: // LD IXL,IXH
|
||||||
|
processor->Rm.br.IXl=processor->Rm.br.IXh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 109: // LD IXL,IXL
|
||||||
|
processor->Rm.br.IXl=processor->Rm.br.IXl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 110: // LD L,(IX+d)
|
||||||
|
processor->Rm.br.L=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 111: // LD IXL,A
|
||||||
|
processor->Rm.br.IXl=processor->Rm.br.A;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 112: // LD (IX+d),B
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),processor->Rm.br.B);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 113: // LD (IX+d),C
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),processor->Rm.br.C);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 114: // LD (IX+d),D
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),processor->Rm.br.D);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 115: // LD (IX+d),E
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),processor->Rm.br.E);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 116: // LD (IX+d),H
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),processor->Rm.br.H);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 117: // LD (IX+d),L
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),processor->Rm.br.L);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 118: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 119: // LD (IX+d),A
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IX),processor->Rm.br.A);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 120: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 121: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 122: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 123: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 124: // LD A,IXH
|
||||||
|
processor->Rm.br.A=processor->Rm.br.IXh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 125: // LD A,IXL
|
||||||
|
processor->Rm.br.A=processor->Rm.br.IXl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 126: // LD A,(IX+d)
|
||||||
|
processor->Rm.br.A=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 127: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 128: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 129: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 130: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 131: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 132: // ADD A,IXH
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IXh,0,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 133: // ADD A,IXL
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IXl,0,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 134: // ADD A,(IX+d)
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)),0,0);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 135: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 136: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 137: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 138: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 139: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 140: // ADC A,IXH
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IXh,1,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 141: // ADC A,IXL
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IXl,1,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 142: // ADC A,(IX+d)
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)),1,0);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 143: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 144: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 145: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 146: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 147: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 148: // SUB IXH
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IXh,0,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 149: // SUB IXL
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IXl,0,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 150: // SUB b(IX+d)
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)),0,1);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 151: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 152: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 153: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 154: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 155: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 156: // SBC A,IXH
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IXh,1,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 157: // SBC A,IXL
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IXl,1,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 158: // SBC A,(IX+d)
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)),1,1);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 159: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 160: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 161: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 162: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 163: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 164: // AND IXH
|
||||||
|
Z80free_doAND(processor,processor->Rm.br.IXh);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 165: // AND IXL
|
||||||
|
Z80free_doAND(processor,processor->Rm.br.IXl);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 166: // AND b(IX+d)
|
||||||
|
Z80free_doAND(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 167: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 168: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 169: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 170: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 171: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 172: // XOR IXH
|
||||||
|
Z80free_doXOR(processor,processor->Rm.br.IXh);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 173: // XOR IXL
|
||||||
|
Z80free_doXOR(processor,processor->Rm.br.IXl);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 174: // XOR b(IX+d)
|
||||||
|
Z80free_doXOR(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 175: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 176: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 177: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 178: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 179: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 180: // OR IXH
|
||||||
|
Z80free_doOR(processor,processor->Rm.br.IXh);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 181: // OR IXL
|
||||||
|
Z80free_doOR(processor,processor->Rm.br.IXl);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 182: // OR b(IX+d)
|
||||||
|
Z80free_doOR(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX)));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 183: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 184: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 185: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 186: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 187: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 188: // CP IXH
|
||||||
|
tmp1=processor->Rm.br.IXh;
|
||||||
|
Z80free_doArithmetic(processor,processor->Rm.br.A,tmp1,0,1);
|
||||||
|
Z80free_adjustFlags(processor,tmp1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 189: // CP IXL
|
||||||
|
tmp1=processor->Rm.br.IXl;
|
||||||
|
Z80free_doArithmetic(processor,processor->Rm.br.A,tmp1,0,1);
|
||||||
|
Z80free_adjustFlags(processor,tmp1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 190: // CP b(IX+d)
|
||||||
|
tmp1=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IX));
|
||||||
|
Z80free_doArithmetic(processor,processor->Rm.br.A,tmp1,0,1);
|
||||||
|
Z80free_adjustFlags(processor,tmp1);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 191: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 192: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 193: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 194: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 195: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 196: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 197: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 198: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 199: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 200: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 201: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 202: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 204: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 205: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 206: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 207: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 208: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 209: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 210: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 211: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 212: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 213: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 214: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 215: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 216: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 217: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 218: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 219: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 220: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 221: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 222: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 223: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 224: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 225: // POP IX
|
||||||
|
processor->Rm.wr.IX=Z80free_doPop(processor);
|
||||||
|
return (10);
|
||||||
|
break;
|
||||||
|
case 226: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 227: // EX (SP),IX
|
||||||
|
tmp2=Z80free_read16(processor->Rm.wr.SP);
|
||||||
|
Z80free_write16(processor->Rm.wr.SP,processor->Rm.wr.IX);
|
||||||
|
processor->Rm.wr.IX=tmp2;
|
||||||
|
return (19);
|
||||||
|
break;
|
||||||
|
case 228: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 229: // PUSH IX
|
||||||
|
Z80free_doPush(processor,processor->Rm.wr.IX);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 230: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 231: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 232: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 233: // JP IX
|
||||||
|
tmp2=processor->Rm.wr.IX;
|
||||||
|
processor->PC=tmp2;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 234: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 235: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 236: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 237: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 238: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 239: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 240: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 241: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 242: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 243: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 244: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 245: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 246: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 247: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 248: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 249: // LD SP,IX
|
||||||
|
processor->Rm.wr.SP=processor->Rm.wr.IX;
|
||||||
|
return (6);
|
||||||
|
break;
|
||||||
|
case 250: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 251: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 252: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 253: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 254: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 255: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
262
src/z80free/Z80free_codesDD.txt
Normal file
262
src/z80free/Z80free_codesDD.txt
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
# OPCODE, TSTATES and instruction for DD prefixed instructions
|
||||||
|
# The TSTATES are 4 less than the real ones, because we already had count
|
||||||
|
# them when exexuting the DD prefix
|
||||||
|
# DEFAULT opcode do the same than the unprefixed ones, using 4 TStates more
|
||||||
|
# Some opcodes have been modified to better adapt to the parser, like
|
||||||
|
# LD (IX+d),n, which now is LD2 IX+d,n
|
||||||
|
00 1 DEFAULT
|
||||||
|
01 1 DEFAULT
|
||||||
|
02 1 DEFAULT
|
||||||
|
03 1 DEFAULT
|
||||||
|
04 1 DEFAULT
|
||||||
|
05 1 DEFAULT
|
||||||
|
06 1 DEFAULT
|
||||||
|
07 1 DEFAULT
|
||||||
|
08 1 DEFAULT
|
||||||
|
09 11 ADD IX,BC
|
||||||
|
0A 1 DEFAULT
|
||||||
|
0B 1 DEFAULT
|
||||||
|
0C 1 DEFAULT
|
||||||
|
0D 1 DEFAULT
|
||||||
|
0E 1 DEFAULT
|
||||||
|
0F 1 DEFAULT
|
||||||
|
10 1 DEFAULT
|
||||||
|
11 1 DEFAULT
|
||||||
|
12 1 DEFAULT
|
||||||
|
13 1 DEFAULT
|
||||||
|
14 1 DEFAULT
|
||||||
|
15 1 DEFAULT
|
||||||
|
16 1 DEFAULT
|
||||||
|
17 1 DEFAULT
|
||||||
|
18 1 DEFAULT
|
||||||
|
19 11 ADD IX,DE
|
||||||
|
1A 1 DEFAULT
|
||||||
|
1B 1 DEFAULT
|
||||||
|
1C 1 DEFAULT
|
||||||
|
1D 1 DEFAULT
|
||||||
|
1E 1 DEFAULT
|
||||||
|
1F 1 DEFAULT
|
||||||
|
20 1 DEFAULT
|
||||||
|
21 10 LD IX,nn
|
||||||
|
22 16 LD (nn),IX
|
||||||
|
23 6 INC IX
|
||||||
|
24 4 INC IXH
|
||||||
|
25 4 DEC IXH
|
||||||
|
26 7 LD IXH,n
|
||||||
|
27 1 DEFAULT
|
||||||
|
28 1 DEFAULT
|
||||||
|
29 11 ADD IX,IX
|
||||||
|
2A 16 LD IX,(nn)
|
||||||
|
2B 6 DEC IX
|
||||||
|
2C 4 INC IXL
|
||||||
|
2D 4 DEC IXL
|
||||||
|
2E 7 LD IXL,n
|
||||||
|
2F 1 DEFAULT
|
||||||
|
30 1 DEFAULT
|
||||||
|
31 1 DEFAULT
|
||||||
|
32 1 DEFAULT
|
||||||
|
33 1 DEFAULT
|
||||||
|
34 19 INC b(IX+d)
|
||||||
|
35 19 DEC b(IX+d)
|
||||||
|
36 15 LD2 IX+d,n
|
||||||
|
37 1 DEFAULT
|
||||||
|
38 1 DEFAULT
|
||||||
|
39 11 ADD IX,SP
|
||||||
|
3A 1 DEFAULT
|
||||||
|
3B 1 DEFAULT
|
||||||
|
3C 1 DEFAULT
|
||||||
|
3D 1 DEFAULT
|
||||||
|
3E 1 DEFAULT
|
||||||
|
3F 1 DEFAULT
|
||||||
|
40 1 DEFAULT
|
||||||
|
41 1 DEFAULT
|
||||||
|
42 1 DEFAULT
|
||||||
|
43 1 DEFAULT
|
||||||
|
44 4 LD B,IXH
|
||||||
|
45 4 LD B,IXL
|
||||||
|
46 15 LD B,(IX+d)
|
||||||
|
47 1 DEFAULT
|
||||||
|
48 1 DEFAULT
|
||||||
|
49 1 DEFAULT
|
||||||
|
4A 1 DEFAULT
|
||||||
|
4B 1 DEFAULT
|
||||||
|
4C 4 LD C,IXH
|
||||||
|
4D 4 LD C,IXL
|
||||||
|
4E 15 LD C,(IX+d)
|
||||||
|
4F 1 DEFAULT
|
||||||
|
50 1 DEFAULT
|
||||||
|
51 1 DEFAULT
|
||||||
|
52 1 DEFAULT
|
||||||
|
53 1 DEFAULT
|
||||||
|
54 4 LD D,IXH
|
||||||
|
55 4 LD D,IXL
|
||||||
|
56 15 LD D,(IX+d)
|
||||||
|
57 1 DEFAULT
|
||||||
|
58 1 DEFAULT
|
||||||
|
59 1 DEFAULT
|
||||||
|
5A 1 DEFAULT
|
||||||
|
5B 1 DEFAULT
|
||||||
|
5C 4 LD E,IXH
|
||||||
|
5D 4 LD E,IXL
|
||||||
|
5E 15 LD E,(IX+d)
|
||||||
|
5F 1 DEFAULT
|
||||||
|
60 4 LD IXH,B
|
||||||
|
61 4 LD IXH,C
|
||||||
|
62 4 LD IXH,D
|
||||||
|
63 4 LD IXH,E
|
||||||
|
64 4 LD IXH,IXH
|
||||||
|
65 4 LD IXH,IXL
|
||||||
|
66 15 LD H,(IX+d)
|
||||||
|
67 4 LD IXH,A
|
||||||
|
68 4 LD IXL,B
|
||||||
|
69 4 LD IXL,C
|
||||||
|
6A 4 LD IXL,D
|
||||||
|
6B 4 LD IXL,E
|
||||||
|
6C 4 LD IXL,IXH
|
||||||
|
6D 4 LD IXL,IXL
|
||||||
|
6E 15 LD L,(IX+d)
|
||||||
|
6F 4 LD IXL,A
|
||||||
|
70 15 LD (IX+d),B
|
||||||
|
71 15 LD (IX+d),C
|
||||||
|
72 15 LD (IX+d),D
|
||||||
|
73 15 LD (IX+d),E
|
||||||
|
74 15 LD (IX+d),H
|
||||||
|
75 15 LD (IX+d),L
|
||||||
|
76 1 DEFAULT
|
||||||
|
77 15 LD (IX+d),A
|
||||||
|
78 1 DEFAULT
|
||||||
|
79 1 DEFAULT
|
||||||
|
7A 1 DEFAULT
|
||||||
|
7B 1 DEFAULT
|
||||||
|
7C 4 LD A,IXH
|
||||||
|
7D 4 LD A,IXL
|
||||||
|
7E 15 LD A,(IX+d)
|
||||||
|
7F 1 DEFAULT
|
||||||
|
80 1 DEFAULT
|
||||||
|
81 1 DEFAULT
|
||||||
|
82 1 DEFAULT
|
||||||
|
83 1 DEFAULT
|
||||||
|
84 4 ADD A,IXH
|
||||||
|
85 4 ADD A,IXL
|
||||||
|
86 15 ADD A,(IX+d)
|
||||||
|
87 1 DEFAULT
|
||||||
|
88 1 DEFAULT
|
||||||
|
89 1 DEFAULT
|
||||||
|
8A 1 DEFAULT
|
||||||
|
8B 1 DEFAULT
|
||||||
|
8C 4 ADC A,IXH
|
||||||
|
8D 4 ADC A,IXL
|
||||||
|
8E 15 ADC A,(IX+d)
|
||||||
|
8F 1 DEFAULT
|
||||||
|
90 1 DEFAULT
|
||||||
|
91 1 DEFAULT
|
||||||
|
92 1 DEFAULT
|
||||||
|
93 1 DEFAULT
|
||||||
|
94 4 SUB IXH
|
||||||
|
95 4 SUB IXL
|
||||||
|
96 15 SUB b(IX+d)
|
||||||
|
97 1 DEFAULT
|
||||||
|
98 1 DEFAULT
|
||||||
|
99 1 DEFAULT
|
||||||
|
9A 1 DEFAULT
|
||||||
|
9B 1 DEFAULT
|
||||||
|
9C 4 SBC A,IXH
|
||||||
|
9D 4 SBC A,IXL
|
||||||
|
9E 15 SBC A,(IX+d)
|
||||||
|
9F 1 DEFAULT
|
||||||
|
A0 1 DEFAULT
|
||||||
|
A1 1 DEFAULT
|
||||||
|
A2 1 DEFAULT
|
||||||
|
A3 1 DEFAULT
|
||||||
|
A4 4 AND IXH
|
||||||
|
A5 4 AND IXL
|
||||||
|
A6 15 AND b(IX+d)
|
||||||
|
A7 1 DEFAULT
|
||||||
|
A8 1 DEFAULT
|
||||||
|
A9 1 DEFAULT
|
||||||
|
AA 1 DEFAULT
|
||||||
|
AB 1 DEFAULT
|
||||||
|
AC 4 XOR IXH
|
||||||
|
AD 4 XOR IXL
|
||||||
|
AE 15 XOR b(IX+d)
|
||||||
|
AF 1 DEFAULT
|
||||||
|
B0 1 DEFAULT
|
||||||
|
B1 1 DEFAULT
|
||||||
|
B2 1 DEFAULT
|
||||||
|
B3 1 DEFAULT
|
||||||
|
B4 4 OR IXH
|
||||||
|
B5 4 OR IXL
|
||||||
|
B6 15 OR b(IX+d)
|
||||||
|
B7 1 DEFAULT
|
||||||
|
B8 1 DEFAULT
|
||||||
|
B9 1 DEFAULT
|
||||||
|
BA 1 DEFAULT
|
||||||
|
BB 1 DEFAULT
|
||||||
|
BC 4 CP IXH
|
||||||
|
BD 4 CP IXL
|
||||||
|
BE 15 CP b(IX+d)
|
||||||
|
BF 1 DEFAULT
|
||||||
|
C0 1 DEFAULT
|
||||||
|
C1 1 DEFAULT
|
||||||
|
C2 1 DEFAULT
|
||||||
|
C3 1 DEFAULT
|
||||||
|
C4 1 DEFAULT
|
||||||
|
C5 1 DEFAULT
|
||||||
|
C6 1 DEFAULT
|
||||||
|
C7 1 DEFAULT
|
||||||
|
C8 1 DEFAULT
|
||||||
|
C9 1 DEFAULT
|
||||||
|
CA 1 DEFAULT
|
||||||
|
CB * PREFIX
|
||||||
|
CC 1 DEFAULT
|
||||||
|
CD 1 DEFAULT
|
||||||
|
CE 1 DEFAULT
|
||||||
|
CF 1 DEFAULT
|
||||||
|
D0 1 DEFAULT
|
||||||
|
D1 1 DEFAULT
|
||||||
|
D2 1 DEFAULT
|
||||||
|
D3 1 DEFAULT
|
||||||
|
D4 1 DEFAULT
|
||||||
|
D5 1 DEFAULT
|
||||||
|
D6 1 DEFAULT
|
||||||
|
D7 1 DEFAULT
|
||||||
|
D8 1 DEFAULT
|
||||||
|
D9 1 DEFAULT
|
||||||
|
DA 1 DEFAULT
|
||||||
|
DB 1 DEFAULT
|
||||||
|
DC 1 DEFAULT
|
||||||
|
DD 1 DEFAULT
|
||||||
|
DE 1 DEFAULT
|
||||||
|
DF 1 DEFAULT
|
||||||
|
E0 1 DEFAULT
|
||||||
|
E1 10 POP IX
|
||||||
|
E2 1 DEFAULT
|
||||||
|
E3 19 EX (SP),IX
|
||||||
|
E4 1 DEFAULT
|
||||||
|
E5 11 PUSH IX
|
||||||
|
E6 1 DEFAULT
|
||||||
|
E7 1 DEFAULT
|
||||||
|
E8 1 DEFAULT
|
||||||
|
E9 4 JP IX
|
||||||
|
EA 1 DEFAULT
|
||||||
|
EB 1 DEFAULT
|
||||||
|
EC 1 DEFAULT
|
||||||
|
ED 1 DEFAULT
|
||||||
|
EE 1 DEFAULT
|
||||||
|
EF 1 DEFAULT
|
||||||
|
F0 1 DEFAULT
|
||||||
|
F1 1 DEFAULT
|
||||||
|
F2 1 DEFAULT
|
||||||
|
F3 1 DEFAULT
|
||||||
|
F4 1 DEFAULT
|
||||||
|
F5 1 DEFAULT
|
||||||
|
F6 1 DEFAULT
|
||||||
|
F7 1 DEFAULT
|
||||||
|
F8 1 DEFAULT
|
||||||
|
F9 6 LD SP,IX
|
||||||
|
FA 1 DEFAULT
|
||||||
|
FB 1 DEFAULT
|
||||||
|
FC 1 DEFAULT
|
||||||
|
FD 1 DEFAULT
|
||||||
|
FE 1 DEFAULT
|
||||||
|
FF 1 DEFAULT
|
1391
src/z80free/Z80free_codesDDCB.c
Normal file
1391
src/z80free/Z80free_codesDDCB.c
Normal file
File diff suppressed because it is too large
Load Diff
262
src/z80free/Z80free_codesDDCB.txt
Normal file
262
src/z80free/Z80free_codesDDCB.txt
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
# OPCODES, TSTATES and INSTRUCTIONS for DDCB prefixed instructions
|
||||||
|
# The TSTATES are 4 less than the real ones because they are counted
|
||||||
|
# when executing the DDCB prefix
|
||||||
|
#
|
||||||
|
# Instructions of the format LD r,XXX (IX+d) (like LD B,RLC (IX+d) )
|
||||||
|
# are modified to the format LD_XXX r,(IX+d) to simplify the parser
|
||||||
|
00 19 LD_RLC B,(IX+d)
|
||||||
|
01 19 LD_RLC C,(IX+d)
|
||||||
|
02 19 LD_RLC D,(IX+d)
|
||||||
|
03 19 LD_RLC E,(IX+d)
|
||||||
|
04 19 LD_RLC H,(IX+d)
|
||||||
|
05 19 LD_RLC L,(IX+d)
|
||||||
|
06 19 RLC b(IX+d)
|
||||||
|
07 19 LD_RLC A,(IX+d)
|
||||||
|
08 19 LD_RRC B,(IX+d)
|
||||||
|
09 19 LD_RRC C,(IX+d)
|
||||||
|
0A 19 LD_RRC D,(IX+d)
|
||||||
|
0B 19 LD_RRC E,(IX+d)
|
||||||
|
0C 19 LD_RRC H,(IX+d)
|
||||||
|
0D 19 LD_RRC L,(IX+d)
|
||||||
|
0E 19 RRC b(IX+d)
|
||||||
|
0F 19 LD_RRC A,(IX+d)
|
||||||
|
10 19 LD_RL B,(IX+d)
|
||||||
|
11 19 LD_RL C,(IX+d)
|
||||||
|
12 19 LD_RL D,(IX+d)
|
||||||
|
13 19 LD_RL E,(IX+d)
|
||||||
|
14 19 LD_RL H,(IX+d)
|
||||||
|
15 19 LD_RL L,(IX+d)
|
||||||
|
16 19 RL b(IX+d)
|
||||||
|
17 19 LD_RL A,(IX+d)
|
||||||
|
18 19 LD_RR B,(IX+d)
|
||||||
|
19 19 LD_RR C,(IX+d)
|
||||||
|
1A 19 LD_RR D,(IX+d)
|
||||||
|
1B 19 LD_RR E,(IX+d)
|
||||||
|
1C 19 LD_RR H,(IX+d)
|
||||||
|
1D 19 LD_RR L,(IX+d)
|
||||||
|
1E 19 RR b(IX+d)
|
||||||
|
1F 19 LD_RR A,(IX+d)
|
||||||
|
20 19 LD_SLA B,(IX+d)
|
||||||
|
21 19 LD_SLA C,(IX+d)
|
||||||
|
22 19 LD_SLA D,(IX+d)
|
||||||
|
23 19 LD_SLA E,(IX+d)
|
||||||
|
24 19 LD_SLA H,(IX+d)
|
||||||
|
25 19 LD_SLA L,(IX+d)
|
||||||
|
26 19 SLA b(IX+d)
|
||||||
|
27 19 LD_SLA A,(IX+d)
|
||||||
|
28 19 LD_SRA B,(IX+d)
|
||||||
|
29 19 LD_SRA C,(IX+d)
|
||||||
|
2A 19 LD_SRA D,(IX+d)
|
||||||
|
2B 19 LD_SRA E,(IX+d)
|
||||||
|
2C 19 LD_SRA H,(IX+d)
|
||||||
|
2D 19 LD_SRA L,(IX+d)
|
||||||
|
2E 19 SRA b(IX+d)
|
||||||
|
2F 19 LD_SRA A,(IX+d)
|
||||||
|
30 19 LD_SLL B,(IX+d)
|
||||||
|
31 19 LD_SLL C,(IX+d)
|
||||||
|
32 19 LD_SLL D,(IX+d)
|
||||||
|
33 19 LD_SLL E,(IX+d)
|
||||||
|
34 19 LD_SLL H,(IX+d)
|
||||||
|
35 19 LD_SLL L,(IX+d)
|
||||||
|
36 19 SLL b(IX+d)
|
||||||
|
37 19 LD_SLL A,(IX+d)
|
||||||
|
38 19 LD_SRL B,(IX+d)
|
||||||
|
39 19 LD_SRL C,(IX+d)
|
||||||
|
3A 19 LD_SRL D,(IX+d)
|
||||||
|
3B 19 LD_SRL E,(IX+d)
|
||||||
|
3C 19 LD_SRL H,(IX+d)
|
||||||
|
3D 19 LD_SRL L,(IX+d)
|
||||||
|
3E 19 SRL b(IX+d)
|
||||||
|
3F 19 LD_SRL A,(IX+d)
|
||||||
|
40 16 BIT 0,(IX+d)
|
||||||
|
41 16 BIT 0,(IX+d)
|
||||||
|
42 16 BIT 0,(IX+d)
|
||||||
|
43 16 BIT 0,(IX+d)
|
||||||
|
44 16 BIT 0,(IX+d)
|
||||||
|
45 16 BIT 0,(IX+d)
|
||||||
|
46 16 BIT 0,(IX+d)
|
||||||
|
47 16 BIT 0,(IX+d)
|
||||||
|
48 16 BIT 1,(IX+d)
|
||||||
|
49 16 BIT 1,(IX+d)
|
||||||
|
4A 16 BIT 1,(IX+d)
|
||||||
|
4B 16 BIT 1,(IX+d)
|
||||||
|
4C 16 BIT 1,(IX+d)
|
||||||
|
4D 16 BIT 1,(IX+d)
|
||||||
|
4E 16 BIT 1,(IX+d)
|
||||||
|
4F 16 BIT 1,(IX+d)
|
||||||
|
50 16 BIT 2,(IX+d)
|
||||||
|
51 16 BIT 2,(IX+d)
|
||||||
|
52 16 BIT 2,(IX+d)
|
||||||
|
53 16 BIT 2,(IX+d)
|
||||||
|
54 16 BIT 2,(IX+d)
|
||||||
|
55 16 BIT 2,(IX+d)
|
||||||
|
56 16 BIT 2,(IX+d)
|
||||||
|
57 16 BIT 2,(IX+d)
|
||||||
|
58 16 BIT 3,(IX+d)
|
||||||
|
59 16 BIT 3,(IX+d)
|
||||||
|
5A 16 BIT 3,(IX+d)
|
||||||
|
5B 16 BIT 3,(IX+d)
|
||||||
|
5C 16 BIT 3,(IX+d)
|
||||||
|
5D 16 BIT 3,(IX+d)
|
||||||
|
5E 16 BIT 3,(IX+d)
|
||||||
|
5F 16 BIT 3,(IX+d)
|
||||||
|
60 16 BIT 4,(IX+d)
|
||||||
|
61 16 BIT 4,(IX+d)
|
||||||
|
62 16 BIT 4,(IX+d)
|
||||||
|
63 16 BIT 4,(IX+d)
|
||||||
|
64 16 BIT 4,(IX+d)
|
||||||
|
65 16 BIT 4,(IX+d)
|
||||||
|
66 16 BIT 4,(IX+d)
|
||||||
|
67 16 BIT 4,(IX+d)
|
||||||
|
68 16 BIT 5,(IX+d)
|
||||||
|
69 16 BIT 5,(IX+d)
|
||||||
|
6A 16 BIT 5,(IX+d)
|
||||||
|
6B 16 BIT 5,(IX+d)
|
||||||
|
6C 16 BIT 5,(IX+d)
|
||||||
|
6D 16 BIT 5,(IX+d)
|
||||||
|
6E 16 BIT 5,(IX+d)
|
||||||
|
6F 16 BIT 5,(IX+d)
|
||||||
|
70 16 BIT 6,(IX+d)
|
||||||
|
71 16 BIT 6,(IX+d)
|
||||||
|
72 16 BIT 6,(IX+d)
|
||||||
|
73 16 BIT 6,(IX+d)
|
||||||
|
74 16 BIT 6,(IX+d)
|
||||||
|
75 16 BIT 6,(IX+d)
|
||||||
|
76 16 BIT 6,(IX+d)
|
||||||
|
77 16 BIT 6,(IX+d)
|
||||||
|
78 16 BIT 7,(IX+d)
|
||||||
|
79 16 BIT 7,(IX+d)
|
||||||
|
7A 16 BIT 7,(IX+d)
|
||||||
|
7B 16 BIT 7,(IX+d)
|
||||||
|
7C 16 BIT 7,(IX+d)
|
||||||
|
7D 16 BIT 7,(IX+d)
|
||||||
|
7E 16 BIT 7,(IX+d)
|
||||||
|
7F 16 BIT 7,(IX+d)
|
||||||
|
80 19 LD_RES B,0,(IX+d)
|
||||||
|
81 19 LD_RES C,0,(IX+d)
|
||||||
|
82 19 LD_RES D,0,(IX+d)
|
||||||
|
83 19 LD_RES E,0,(IX+d)
|
||||||
|
84 19 LD_RES H,0,(IX+d)
|
||||||
|
85 19 LD_RES L,0,(IX+d)
|
||||||
|
86 19 RES 0,(IX+d)
|
||||||
|
87 19 LD_RES A,0,(IX+d)
|
||||||
|
88 19 LD_RES B,1,(IX+d)
|
||||||
|
89 19 LD_RES C,1,(IX+d)
|
||||||
|
8A 19 LD_RES D,1,(IX+d)
|
||||||
|
8B 19 LD_RES E,1,(IX+d)
|
||||||
|
8C 19 LD_RES H,1,(IX+d)
|
||||||
|
8D 19 LD_RES L,1,(IX+d)
|
||||||
|
8E 19 RES 1,(IX+d)
|
||||||
|
8F 19 LD_RES A,1,(IX+d)
|
||||||
|
90 19 LD_RES B,2,(IX+d)
|
||||||
|
91 19 LD_RES C,2,(IX+d)
|
||||||
|
92 19 LD_RES D,2,(IX+d)
|
||||||
|
93 19 LD_RES E,2,(IX+d)
|
||||||
|
94 19 LD_RES H,2,(IX+d)
|
||||||
|
95 19 LD_RES L,2,(IX+d)
|
||||||
|
96 19 RES 2,(IX+d)
|
||||||
|
97 19 LD_RES A,2,(IX+d)
|
||||||
|
98 19 LD_RES B,3,(IX+d)
|
||||||
|
99 19 LD_RES C,3,(IX+d)
|
||||||
|
9A 19 LD_RES D,3,(IX+d)
|
||||||
|
9B 19 LD_RES E,3,(IX+d)
|
||||||
|
9C 19 LD_RES H,3,(IX+d)
|
||||||
|
9D 19 LD_RES L,3,(IX+d)
|
||||||
|
9E 19 RES 3,(IX+d)
|
||||||
|
9F 19 LD_RES A,3,(IX+d)
|
||||||
|
A0 19 LD_RES B,4,(IX+d)
|
||||||
|
A1 19 LD_RES C,4,(IX+d)
|
||||||
|
A2 19 LD_RES D,4,(IX+d)
|
||||||
|
A3 19 LD_RES E,4,(IX+d)
|
||||||
|
A4 19 LD_RES H,4,(IX+d)
|
||||||
|
A5 19 LD_RES L,4,(IX+d)
|
||||||
|
A6 19 RES 4,(IX+d)
|
||||||
|
A7 19 LD_RES A,4,(IX+d)
|
||||||
|
A8 19 LD_RES B,5,(IX+d)
|
||||||
|
A9 19 LD_RES C,5,(IX+d)
|
||||||
|
AA 19 LD_RES D,5,(IX+d)
|
||||||
|
AB 19 LD_RES E,5,(IX+d)
|
||||||
|
AC 19 LD_RES H,5,(IX+d)
|
||||||
|
AD 19 LD_RES L,5,(IX+d)
|
||||||
|
AE 19 RES 5,(IX+d)
|
||||||
|
AF 19 LD_RES A,5,(IX+d)
|
||||||
|
B0 19 LD_RES B,6,(IX+d)
|
||||||
|
B1 19 LD_RES C,6,(IX+d)
|
||||||
|
B2 19 LD_RES D,6,(IX+d)
|
||||||
|
B3 19 LD_RES E,6,(IX+d)
|
||||||
|
B4 19 LD_RES H,6,(IX+d)
|
||||||
|
B5 19 LD_RES L,6,(IX+d)
|
||||||
|
B6 19 RES 6,(IX+d)
|
||||||
|
B7 19 LD_RES A,6,(IX+d)
|
||||||
|
B8 19 LD_RES B,7,(IX+d)
|
||||||
|
B9 19 LD_RES C,7,(IX+d)
|
||||||
|
BA 19 LD_RES D,7,(IX+d)
|
||||||
|
BB 19 LD_RES E,7,(IX+d)
|
||||||
|
BC 19 LD_RES H,7,(IX+d)
|
||||||
|
BD 19 LD_RES L,7,(IX+d)
|
||||||
|
BE 19 RES 7,(IX+d)
|
||||||
|
BF 19 LD_RES A,7,(IX+d)
|
||||||
|
C0 19 LD_SET B,0,(IX+d)
|
||||||
|
C1 19 LD_SET C,0,(IX+d)
|
||||||
|
C2 19 LD_SET D,0,(IX+d)
|
||||||
|
C3 19 LD_SET E,0,(IX+d)
|
||||||
|
C4 19 LD_SET H,0,(IX+d)
|
||||||
|
C5 19 LD_SET L,0,(IX+d)
|
||||||
|
C6 19 SET 0,(IX+d)
|
||||||
|
C7 19 LD_SET A,0,(IX+d)
|
||||||
|
C8 19 LD_SET B,1,(IX+d)
|
||||||
|
C9 19 LD_SET C,1,(IX+d)
|
||||||
|
CA 19 LD_SET D,1,(IX+d)
|
||||||
|
CB 19 LD_SET E,1,(IX+d)
|
||||||
|
CC 19 LD_SET H,1,(IX+d)
|
||||||
|
CD 19 LD_SET L,1,(IX+d)
|
||||||
|
CE 19 SET 1,(IX+d)
|
||||||
|
CF 19 LD_SET A,1,(IX+d)
|
||||||
|
D0 19 LD_SET B,2,(IX+d)
|
||||||
|
D1 19 LD_SET C,2,(IX+d)
|
||||||
|
D2 19 LD_SET D,2,(IX+d)
|
||||||
|
D3 19 LD_SET E,2,(IX+d)
|
||||||
|
D4 19 LD_SET H,2,(IX+d)
|
||||||
|
D5 19 LD_SET L,2,(IX+d)
|
||||||
|
D6 19 SET 2,(IX+d)
|
||||||
|
D7 19 LD_SET A,2,(IX+d)
|
||||||
|
D8 19 LD_SET B,3,(IX+d)
|
||||||
|
D9 19 LD_SET C,3,(IX+d)
|
||||||
|
DA 19 LD_SET D,3,(IX+d)
|
||||||
|
DB 19 LD_SET E,3,(IX+d)
|
||||||
|
DC 19 LD_SET H,3,(IX+d)
|
||||||
|
DD 19 LD_SET L,3,(IX+d)
|
||||||
|
DE 19 SET 3,(IX+d)
|
||||||
|
DF 19 LD_SET A,3,(IX+d)
|
||||||
|
E0 19 LD_SET B,4,(IX+d)
|
||||||
|
E1 19 LD_SET C,4,(IX+d)
|
||||||
|
E2 19 LD_SET D,4,(IX+d)
|
||||||
|
E3 19 LD_SET E,4,(IX+d)
|
||||||
|
E4 19 LD_SET H,4,(IX+d)
|
||||||
|
E5 19 LD_SET L,4,(IX+d)
|
||||||
|
E6 19 SET 4,(IX+d)
|
||||||
|
E7 19 LD_SET A,4,(IX+d)
|
||||||
|
E8 19 LD_SET B,5,(IX+d)
|
||||||
|
E9 19 LD_SET C,5,(IX+d)
|
||||||
|
EA 19 LD_SET D,5,(IX+d)
|
||||||
|
EB 19 LD_SET E,5,(IX+d)
|
||||||
|
EC 19 LD_SET H,5,(IX+d)
|
||||||
|
ED 19 LD_SET L,5,(IX+d)
|
||||||
|
EE 19 SET 5,(IX+d)
|
||||||
|
EF 19 LD_SET A,5,(IX+d)
|
||||||
|
F0 19 LD_SET B,6,(IX+d)
|
||||||
|
F1 19 LD_SET C,6,(IX+d)
|
||||||
|
F2 19 LD_SET D,6,(IX+d)
|
||||||
|
F3 19 LD_SET E,6,(IX+d)
|
||||||
|
F4 19 LD_SET H,6,(IX+d)
|
||||||
|
F5 19 LD_SET L,6,(IX+d)
|
||||||
|
F6 19 SET 6,(IX+d)
|
||||||
|
F7 19 LD_SET A,6,(IX+d)
|
||||||
|
F8 19 LD_SET B,7,(IX+d)
|
||||||
|
F9 19 LD_SET C,7,(IX+d)
|
||||||
|
FA 19 LD_SET D,7,(IX+d)
|
||||||
|
FB 19 LD_SET E,7,(IX+d)
|
||||||
|
FC 19 LD_SET H,7,(IX+d)
|
||||||
|
FD 19 LD_SET L,7,(IX+d)
|
||||||
|
FE 19 SET 7,(IX+d)
|
||||||
|
FF 19 LD_SET A,7,(IX+d)
|
1025
src/z80free/Z80free_codesED.c
Normal file
1025
src/z80free/Z80free_codesED.c
Normal file
File diff suppressed because it is too large
Load Diff
260
src/z80free/Z80free_codesED.txt
Normal file
260
src/z80free/Z80free_codesED.txt
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
# OPCODES, TSTATES and INSTRUCTIONS for ED prefixed instructions
|
||||||
|
# The TSTATES are 4 less than the real ones because they are counted
|
||||||
|
# when executing the ED prefix
|
||||||
|
# IN and OUT syntax has been modified to simplify the parser
|
||||||
|
00 4 NOP
|
||||||
|
01 4 NOP
|
||||||
|
02 4 NOP
|
||||||
|
03 4 NOP
|
||||||
|
04 4 NOP
|
||||||
|
05 4 NOP
|
||||||
|
06 4 NOP
|
||||||
|
07 4 NOP
|
||||||
|
08 4 NOP
|
||||||
|
09 4 NOP
|
||||||
|
0A 4 NOP
|
||||||
|
0B 4 NOP
|
||||||
|
0C 4 NOP
|
||||||
|
0D 4 NOP
|
||||||
|
0E 4 NOP
|
||||||
|
0F 4 NOP
|
||||||
|
10 4 NOP
|
||||||
|
11 4 NOP
|
||||||
|
12 4 NOP
|
||||||
|
13 4 NOP
|
||||||
|
14 4 NOP
|
||||||
|
15 4 NOP
|
||||||
|
16 4 NOP
|
||||||
|
17 4 NOP
|
||||||
|
18 4 NOP
|
||||||
|
19 4 NOP
|
||||||
|
1A 4 NOP
|
||||||
|
1B 4 NOP
|
||||||
|
1C 4 NOP
|
||||||
|
1D 4 NOP
|
||||||
|
1E 4 NOP
|
||||||
|
1F 4 NOP
|
||||||
|
20 4 NOP
|
||||||
|
21 4 NOP
|
||||||
|
22 4 NOP
|
||||||
|
23 4 NOP
|
||||||
|
24 4 NOP
|
||||||
|
25 4 NOP
|
||||||
|
26 4 NOP
|
||||||
|
27 4 NOP
|
||||||
|
28 4 NOP
|
||||||
|
29 4 NOP
|
||||||
|
2A 4 NOP
|
||||||
|
2B 4 NOP
|
||||||
|
2C 4 NOP
|
||||||
|
2D 4 NOP
|
||||||
|
2E 4 NOP
|
||||||
|
2F 4 NOP
|
||||||
|
30 4 NOP
|
||||||
|
31 4 NOP
|
||||||
|
32 4 NOP
|
||||||
|
33 4 NOP
|
||||||
|
34 4 NOP
|
||||||
|
35 4 NOP
|
||||||
|
36 4 NOP
|
||||||
|
37 4 NOP
|
||||||
|
38 4 NOP
|
||||||
|
39 4 NOP
|
||||||
|
3A 4 NOP
|
||||||
|
3B 4 NOP
|
||||||
|
3C 4 NOP
|
||||||
|
3D 4 NOP
|
||||||
|
3E 4 NOP
|
||||||
|
3F 4 NOP
|
||||||
|
40 8 IN_BC B
|
||||||
|
41 8 OUT_BC B
|
||||||
|
42 11 SBC HL,BC
|
||||||
|
43 16 LD (nn),BC
|
||||||
|
44 4 NEG
|
||||||
|
45 10 RETN
|
||||||
|
46 4 IM 0
|
||||||
|
47 5 LD I,A
|
||||||
|
48 8 IN_BC C
|
||||||
|
49 8 OUT_BC C
|
||||||
|
4A 11 ADC HL,BC
|
||||||
|
4B 16 LD BC,(nn)
|
||||||
|
4C 4 NEG
|
||||||
|
4D 10 RETI
|
||||||
|
4E 4 IM 1
|
||||||
|
4F 5 LD R,A
|
||||||
|
50 8 IN_BC D
|
||||||
|
51 8 OUT_BC D
|
||||||
|
52 11 SBC HL,DE
|
||||||
|
53 16 LD (nn),DE
|
||||||
|
54 4 NEG
|
||||||
|
55 10 RETN
|
||||||
|
56 4 IM 1
|
||||||
|
57 5 LD A,I
|
||||||
|
58 8 IN_BC E
|
||||||
|
59 8 OUT_BC E
|
||||||
|
5A 11 ADC HL,DE
|
||||||
|
5B 16 LD DE,(nn)
|
||||||
|
5C 4 NEG
|
||||||
|
5D 10 RETN
|
||||||
|
5E 4 IM 2
|
||||||
|
5F 5 LD A,R
|
||||||
|
60 8 IN_BC H
|
||||||
|
61 8 OUT_BC H
|
||||||
|
62 11 SBC HL,HL
|
||||||
|
63 16 LD (nn),HL
|
||||||
|
64 4 NEG
|
||||||
|
65 10 RETN
|
||||||
|
66 4 IM 0
|
||||||
|
67 14 RRD
|
||||||
|
68 8 IN_BC L
|
||||||
|
69 8 OUT_BC L
|
||||||
|
6A 11 ADC HL,HL
|
||||||
|
6B 16 LD HL,(nn)
|
||||||
|
6C 4 NEG
|
||||||
|
6D 10 RETN
|
||||||
|
6E 4 IM 0
|
||||||
|
6F 14 RLD
|
||||||
|
70 8 IN_BC
|
||||||
|
71 8 OUT_BC 0
|
||||||
|
72 11 SBC HL,SP
|
||||||
|
73 16 LD (nn),SP
|
||||||
|
74 4 NEG
|
||||||
|
75 10 RETN
|
||||||
|
76 4 IM 1
|
||||||
|
77 4 NOP
|
||||||
|
78 8 IN_BC A
|
||||||
|
79 8 OUT_BC A
|
||||||
|
7A 11 ADC HL,SP
|
||||||
|
7B 16 LD SP,(nn)
|
||||||
|
7C 4 NEG
|
||||||
|
7D 10 RETN
|
||||||
|
7E 4 IM 2
|
||||||
|
7F 4 NOP
|
||||||
|
80 4 NOP
|
||||||
|
81 4 NOP
|
||||||
|
82 4 NOP
|
||||||
|
83 4 NOP
|
||||||
|
84 4 NOP
|
||||||
|
85 4 NOP
|
||||||
|
86 4 NOP
|
||||||
|
87 4 NOP
|
||||||
|
88 4 NOP
|
||||||
|
89 4 NOP
|
||||||
|
8A 4 NOP
|
||||||
|
8B 4 NOP
|
||||||
|
8C 4 NOP
|
||||||
|
8D 4 NOP
|
||||||
|
8E 4 NOP
|
||||||
|
8F 4 NOP
|
||||||
|
90 4 NOP
|
||||||
|
91 4 NOP
|
||||||
|
92 4 NOP
|
||||||
|
93 4 NOP
|
||||||
|
94 4 NOP
|
||||||
|
95 4 NOP
|
||||||
|
96 4 NOP
|
||||||
|
97 4 NOP
|
||||||
|
98 4 NOP
|
||||||
|
99 4 NOP
|
||||||
|
9A 4 NOP
|
||||||
|
9B 4 NOP
|
||||||
|
9C 4 NOP
|
||||||
|
9D 4 NOP
|
||||||
|
9E 4 NOP
|
||||||
|
9F 4 NOP
|
||||||
|
A0 12 LDI
|
||||||
|
A1 12 CPI
|
||||||
|
A2 12 INI
|
||||||
|
A3 12 OUTI
|
||||||
|
A4 4 NOP
|
||||||
|
A5 4 NOP
|
||||||
|
A6 4 NOP
|
||||||
|
A7 4 NOP
|
||||||
|
A8 12 LDD
|
||||||
|
A9 12 CPD
|
||||||
|
AA 12 IND
|
||||||
|
AB 12 OUTD
|
||||||
|
AC 4 NOP
|
||||||
|
AD 4 NOP
|
||||||
|
AE 4 NOP
|
||||||
|
AF 4 NOP
|
||||||
|
B0 17/12 LDIR
|
||||||
|
B1 17/12 CPIR
|
||||||
|
B2 17/12 INIR
|
||||||
|
B3 17/12 OTIR
|
||||||
|
B4 4 NOP
|
||||||
|
B5 4 NOP
|
||||||
|
B6 4 NOP
|
||||||
|
B7 4 NOP
|
||||||
|
B8 17/12 LDDR
|
||||||
|
B9 17/12 CPDR
|
||||||
|
BA 17/12 INDR
|
||||||
|
BB 17/12 OTDR
|
||||||
|
BC 4 NOP
|
||||||
|
BD 4 NOP
|
||||||
|
BE 4 NOP
|
||||||
|
BF 4 NOP
|
||||||
|
C0 4 NOP
|
||||||
|
C1 4 NOP
|
||||||
|
C2 4 NOP
|
||||||
|
C3 4 NOP
|
||||||
|
C4 4 NOP
|
||||||
|
C5 4 NOP
|
||||||
|
C6 4 NOP
|
||||||
|
C7 4 NOP
|
||||||
|
C8 4 NOP
|
||||||
|
C9 4 NOP
|
||||||
|
CA 4 NOP
|
||||||
|
CB 4 NOP
|
||||||
|
CC 4 NOP
|
||||||
|
CD 4 NOP
|
||||||
|
CE 4 NOP
|
||||||
|
CF 4 NOP
|
||||||
|
D0 4 NOP
|
||||||
|
D1 4 NOP
|
||||||
|
D2 4 NOP
|
||||||
|
D3 4 NOP
|
||||||
|
D4 4 NOP
|
||||||
|
D5 4 NOP
|
||||||
|
D6 4 NOP
|
||||||
|
D7 4 NOP
|
||||||
|
D8 4 NOP
|
||||||
|
D9 4 NOP
|
||||||
|
DA 4 NOP
|
||||||
|
DB 4 NOP
|
||||||
|
DC 4 NOP
|
||||||
|
DD 4 NOP
|
||||||
|
DE 4 NOP
|
||||||
|
DF 4 NOP
|
||||||
|
E0 4 NOP
|
||||||
|
E1 4 NOP
|
||||||
|
E2 4 NOP
|
||||||
|
E3 4 NOP
|
||||||
|
E4 4 NOP
|
||||||
|
E5 4 NOP
|
||||||
|
E6 4 NOP
|
||||||
|
E7 4 NOP
|
||||||
|
E8 4 NOP
|
||||||
|
E9 4 NOP
|
||||||
|
EA 4 NOP
|
||||||
|
EB 4 NOP
|
||||||
|
EC 4 NOP
|
||||||
|
ED 4 NOP
|
||||||
|
EE 4 NOP
|
||||||
|
EF 4 NOP
|
||||||
|
F0 4 NOP
|
||||||
|
F1 4 NOP
|
||||||
|
F2 4 NOP
|
||||||
|
F3 4 NOP
|
||||||
|
F4 4 NOP
|
||||||
|
F5 4 NOP
|
||||||
|
F6 4 NOP
|
||||||
|
F7 4 NOP
|
||||||
|
F8 4 NOP
|
||||||
|
F9 4 NOP
|
||||||
|
FA 4 NOP
|
||||||
|
FB 4 NOP
|
||||||
|
FC 4 NOP
|
||||||
|
FD 4 NOP
|
||||||
|
FE 4 NOP
|
||||||
|
FF 4 NOP
|
890
src/z80free/Z80free_codesFD.c
Normal file
890
src/z80free/Z80free_codesFD.c
Normal file
@ -0,0 +1,890 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008-2009 Sergio Costas (Raster Software Vigo)
|
||||||
|
* This file is part of Z80Free
|
||||||
|
*
|
||||||
|
* Z80Free 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Z80Free 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Z80free.h"
|
||||||
|
|
||||||
|
int Z80free_codesFD (Z80FREE *processor,byte opcode) {
|
||||||
|
static byte tmp1;
|
||||||
|
static word tmp2;
|
||||||
|
|
||||||
|
switch(opcode) {
|
||||||
|
case 0: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 1: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 2: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 3: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 4: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 5: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 6: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 7: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 8: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 9: // ADD IY,BC
|
||||||
|
processor->Rm.wr.IY=Z80free_doArithmetic16(processor,processor->Rm.wr.IY,processor->Rm.wr.BC,0,0);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 10: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 11: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 12: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 13: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 14: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 15: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 16: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 17: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 18: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 19: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 20: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 21: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 22: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 23: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 24: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 25: // ADD IY,DE
|
||||||
|
processor->Rm.wr.IY=Z80free_doArithmetic16(processor,processor->Rm.wr.IY,processor->Rm.wr.DE,0,0);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 26: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 27: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 28: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 29: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 30: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 31: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 32: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 33: // LD IY,nn
|
||||||
|
processor->Rm.wr.IY=Z80free_read_param_16(processor);
|
||||||
|
return (10);
|
||||||
|
break;
|
||||||
|
case 34: // LD (nn),IY
|
||||||
|
Z80free_write16(Z80free_read_param_16(processor),processor->Rm.wr.IY);
|
||||||
|
return (16);
|
||||||
|
break;
|
||||||
|
case 35: // INC IY
|
||||||
|
processor->Rm.wr.IY=Z80free_doIncDec16(processor,processor->Rm.wr.IY,0);
|
||||||
|
return (6);
|
||||||
|
break;
|
||||||
|
case 36: // INC IYH
|
||||||
|
processor->Rm.br.IYh=Z80free_doIncDec(processor,processor->Rm.br.IYh,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 37: // DEC IYH
|
||||||
|
processor->Rm.br.IYh=Z80free_doIncDec(processor,processor->Rm.br.IYh,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 38: // LD IYH,n
|
||||||
|
processor->Rm.br.IYh=Z80free_read_param_8(processor);
|
||||||
|
return (7);
|
||||||
|
break;
|
||||||
|
case 39: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 40: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 41: // ADD IY,IY
|
||||||
|
processor->Rm.wr.IY=Z80free_doArithmetic16(processor,processor->Rm.wr.IY,processor->Rm.wr.IY,0,0);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 42: // LD IY,(nn)
|
||||||
|
processor->Rm.wr.IY=Z80free_read16(Z80free_read_param_16(processor));
|
||||||
|
return (16);
|
||||||
|
break;
|
||||||
|
case 43: // DEC IY
|
||||||
|
processor->Rm.wr.IY=Z80free_doIncDec16(processor,processor->Rm.wr.IY,1);
|
||||||
|
return (6);
|
||||||
|
break;
|
||||||
|
case 44: // INC IYL
|
||||||
|
processor->Rm.br.IYl=Z80free_doIncDec(processor,processor->Rm.br.IYl,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 45: // DEC IYL
|
||||||
|
processor->Rm.br.IYl=Z80free_doIncDec(processor,processor->Rm.br.IYl,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 46: // LD IYL,n
|
||||||
|
processor->Rm.br.IYl=Z80free_read_param_8(processor);
|
||||||
|
return (7);
|
||||||
|
break;
|
||||||
|
case 47: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 48: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 49: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 50: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 51: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 52: // INC b(IY+d)
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),Z80free_doIncDec(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)),0));
|
||||||
|
return (19);
|
||||||
|
break;
|
||||||
|
case 53: // DEC b(IY+d)
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),Z80free_doIncDec(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)),1));
|
||||||
|
return (19);
|
||||||
|
break;
|
||||||
|
case 54: // LD2 IY+d,n
|
||||||
|
tmp2=Z80free_addr_relative(processor,processor->Rm.wr.IY);
|
||||||
|
Z80free_Wr(tmp2,Z80free_read_param_8(processor));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 55: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 56: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 57: // ADD IY,SP
|
||||||
|
processor->Rm.wr.IY=Z80free_doArithmetic16(processor,processor->Rm.wr.IY,processor->Rm.wr.SP,0,0);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 58: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 59: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 60: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 61: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 62: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 63: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 64: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 65: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 66: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 67: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 68: // LD B,IYH
|
||||||
|
processor->Rm.br.B=processor->Rm.br.IYh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 69: // LD B,IYL
|
||||||
|
processor->Rm.br.B=processor->Rm.br.IYl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 70: // LD B,(IY+d)
|
||||||
|
processor->Rm.br.B=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 71: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 72: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 73: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 74: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 75: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 76: // LD C,IYH
|
||||||
|
processor->Rm.br.C=processor->Rm.br.IYh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 77: // LD C,IYL
|
||||||
|
processor->Rm.br.C=processor->Rm.br.IYl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 78: // LD C,(IY+d)
|
||||||
|
processor->Rm.br.C=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 79: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 80: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 81: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 82: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 83: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 84: // LD D,IYH
|
||||||
|
processor->Rm.br.D=processor->Rm.br.IYh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 85: // LD D,IYL
|
||||||
|
processor->Rm.br.D=processor->Rm.br.IYl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 86: // LD D,(IY+d)
|
||||||
|
processor->Rm.br.D=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 87: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 88: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 89: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 90: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 91: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 92: // LD E,IYH
|
||||||
|
processor->Rm.br.E=processor->Rm.br.IYh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 93: // LD E,IYL
|
||||||
|
processor->Rm.br.E=processor->Rm.br.IYl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 94: // LD E,(IY+d)
|
||||||
|
processor->Rm.br.E=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 95: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 96: // LD IYH,B
|
||||||
|
processor->Rm.br.IYh=processor->Rm.br.B;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 97: // LD IYH,C
|
||||||
|
processor->Rm.br.IYh=processor->Rm.br.C;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 98: // LD IYH,D
|
||||||
|
processor->Rm.br.IYh=processor->Rm.br.D;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 99: // LD IYH,E
|
||||||
|
processor->Rm.br.IYh=processor->Rm.br.E;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 100: // LD IYH,IYH
|
||||||
|
processor->Rm.br.IYh=processor->Rm.br.IYh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 101: // LD IYH,IYL
|
||||||
|
processor->Rm.br.IYh=processor->Rm.br.IYl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 102: // LD H,(IY+d)
|
||||||
|
processor->Rm.br.H=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 103: // LD IYH,A
|
||||||
|
processor->Rm.br.IYh=processor->Rm.br.A;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 104: // LD IYL,B
|
||||||
|
processor->Rm.br.IYl=processor->Rm.br.B;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 105: // LD IYL,C
|
||||||
|
processor->Rm.br.IYl=processor->Rm.br.C;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 106: // LD IYL,D
|
||||||
|
processor->Rm.br.IYl=processor->Rm.br.D;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 107: // LD IYL,E
|
||||||
|
processor->Rm.br.IYl=processor->Rm.br.E;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 108: // LD IYL,IYH
|
||||||
|
processor->Rm.br.IYl=processor->Rm.br.IYh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 109: // LD IYL,IYL
|
||||||
|
processor->Rm.br.IYl=processor->Rm.br.IYl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 110: // LD L,(IY+d)
|
||||||
|
processor->Rm.br.L=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 111: // LD IYL,A
|
||||||
|
processor->Rm.br.IYl=processor->Rm.br.A;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 112: // LD (IY+d),B
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),processor->Rm.br.B);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 113: // LD (IY+d),C
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),processor->Rm.br.C);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 114: // LD (IY+d),D
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),processor->Rm.br.D);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 115: // LD (IY+d),E
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),processor->Rm.br.E);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 116: // LD (IY+d),H
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),processor->Rm.br.H);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 117: // LD (IY+d),L
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),processor->Rm.br.L);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 118: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 119: // LD (IY+d),A
|
||||||
|
Z80free_Wr(Z80free_addr_relative(processor,processor->Rm.wr.IY),processor->Rm.br.A);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 120: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 121: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 122: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 123: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 124: // LD A,IYH
|
||||||
|
processor->Rm.br.A=processor->Rm.br.IYh;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 125: // LD A,IYL
|
||||||
|
processor->Rm.br.A=processor->Rm.br.IYl;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 126: // LD A,(IY+d)
|
||||||
|
processor->Rm.br.A=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 127: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 128: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 129: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 130: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 131: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 132: // ADD A,IYH
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IYh,0,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 133: // ADD A,IYL
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IYl,0,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 134: // ADD A,(IY+d)
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)),0,0);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 135: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 136: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 137: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 138: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 139: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 140: // ADC A,IYH
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IYh,1,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 141: // ADC A,IYL
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IYl,1,0);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 142: // ADC A,(IY+d)
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)),1,0);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 143: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 144: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 145: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 146: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 147: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 148: // SUB IYH
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IYh,0,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 149: // SUB IYL
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IYl,0,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 150: // SUB b(IY+d)
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)),0,1);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 151: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 152: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 153: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 154: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 155: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 156: // SBC A,IYH
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IYh,1,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 157: // SBC A,IYL
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,processor->Rm.br.IYl,1,1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 158: // SBC A,(IY+d)
|
||||||
|
processor->Rm.br.A=Z80free_doArithmetic(processor,processor->Rm.br.A,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)),1,1);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 159: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 160: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 161: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 162: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 163: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 164: // AND IYH
|
||||||
|
Z80free_doAND(processor,processor->Rm.br.IYh);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 165: // AND IYL
|
||||||
|
Z80free_doAND(processor,processor->Rm.br.IYl);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 166: // AND b(IY+d)
|
||||||
|
Z80free_doAND(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 167: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 168: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 169: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 170: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 171: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 172: // XOR IYH
|
||||||
|
Z80free_doXOR(processor,processor->Rm.br.IYh);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 173: // XOR IYL
|
||||||
|
Z80free_doXOR(processor,processor->Rm.br.IYl);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 174: // XOR b(IY+d)
|
||||||
|
Z80free_doXOR(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 175: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 176: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 177: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 178: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 179: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 180: // OR IYH
|
||||||
|
Z80free_doOR(processor,processor->Rm.br.IYh);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 181: // OR IYL
|
||||||
|
Z80free_doOR(processor,processor->Rm.br.IYl);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 182: // OR b(IY+d)
|
||||||
|
Z80free_doOR(processor,Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY)));
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 183: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 184: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 185: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 186: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 187: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 188: // CP IYH
|
||||||
|
tmp1=processor->Rm.br.IYh;
|
||||||
|
Z80free_doArithmetic(processor,processor->Rm.br.A,tmp1,0,1);
|
||||||
|
Z80free_adjustFlags(processor,tmp1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 189: // CP IYL
|
||||||
|
tmp1=processor->Rm.br.IYl;
|
||||||
|
Z80free_doArithmetic(processor,processor->Rm.br.A,tmp1,0,1);
|
||||||
|
Z80free_adjustFlags(processor,tmp1);
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 190: // CP b(IY+d)
|
||||||
|
tmp1=Z80free_Rd(Z80free_addr_relative(processor,processor->Rm.wr.IY));
|
||||||
|
Z80free_doArithmetic(processor,processor->Rm.br.A,tmp1,0,1);
|
||||||
|
Z80free_adjustFlags(processor,tmp1);
|
||||||
|
return (15);
|
||||||
|
break;
|
||||||
|
case 191: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 192: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 193: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 194: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 195: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 196: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 197: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 198: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 199: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 200: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 201: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 202: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 204: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 205: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 206: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 207: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 208: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 209: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 210: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 211: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 212: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 213: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 214: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 215: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 216: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 217: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 218: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 219: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 220: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 221: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 222: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 223: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 224: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 225: // POP IY
|
||||||
|
processor->Rm.wr.IY=Z80free_doPop(processor);
|
||||||
|
return (10);
|
||||||
|
break;
|
||||||
|
case 226: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 227: // EX (SP),IY
|
||||||
|
tmp2=Z80free_read16(processor->Rm.wr.SP);
|
||||||
|
Z80free_write16(processor->Rm.wr.SP,processor->Rm.wr.IY);
|
||||||
|
processor->Rm.wr.IY=tmp2;
|
||||||
|
return (19);
|
||||||
|
break;
|
||||||
|
case 228: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 229: // PUSH IY
|
||||||
|
Z80free_doPush(processor,processor->Rm.wr.IY);
|
||||||
|
return (11);
|
||||||
|
break;
|
||||||
|
case 230: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 231: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 232: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 233: // JP IY
|
||||||
|
tmp2=processor->Rm.wr.IY;
|
||||||
|
processor->PC=tmp2;
|
||||||
|
return (4);
|
||||||
|
break;
|
||||||
|
case 234: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 235: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 236: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 237: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 238: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 239: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 240: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 241: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 242: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 243: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 244: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 245: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 246: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 247: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 248: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 249: // LD SP,IY
|
||||||
|
processor->Rm.wr.SP=processor->Rm.wr.IY;
|
||||||
|
return (6);
|
||||||
|
break;
|
||||||
|
case 250: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 251: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 252: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 253: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 254: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
case 255: // DEFAULT
|
||||||
|
return (Z80free_codes(processor,opcode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
262
src/z80free/Z80free_codesFD.txt
Normal file
262
src/z80free/Z80free_codesFD.txt
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
# OPCODE, TSTATES and instruction for FD prefixed instructions
|
||||||
|
# The TSTATES are 4 less than the real ones, because we already had count
|
||||||
|
# them when exexuting the FD prefix
|
||||||
|
# DEFAULT opcode do the same than the unprefixed ones, using 4 TStates more
|
||||||
|
# Some opcodes have been modified to better adapt to the parser, like
|
||||||
|
# LD (IY+d),n, which now is LD2 IY+d,n
|
||||||
|
00 1 DEFAULT
|
||||||
|
01 1 DEFAULT
|
||||||
|
02 1 DEFAULT
|
||||||
|
03 1 DEFAULT
|
||||||
|
04 1 DEFAULT
|
||||||
|
05 1 DEFAULT
|
||||||
|
06 1 DEFAULT
|
||||||
|
07 1 DEFAULT
|
||||||
|
08 1 DEFAULT
|
||||||
|
09 11 ADD IY,BC
|
||||||
|
0A 1 DEFAULT
|
||||||
|
0B 1 DEFAULT
|
||||||
|
0C 1 DEFAULT
|
||||||
|
0D 1 DEFAULT
|
||||||
|
0E 1 DEFAULT
|
||||||
|
0F 1 DEFAULT
|
||||||
|
10 1 DEFAULT
|
||||||
|
11 1 DEFAULT
|
||||||
|
12 1 DEFAULT
|
||||||
|
13 1 DEFAULT
|
||||||
|
14 1 DEFAULT
|
||||||
|
15 1 DEFAULT
|
||||||
|
16 1 DEFAULT
|
||||||
|
17 1 DEFAULT
|
||||||
|
18 1 DEFAULT
|
||||||
|
19 11 ADD IY,DE
|
||||||
|
1A 1 DEFAULT
|
||||||
|
1B 1 DEFAULT
|
||||||
|
1C 1 DEFAULT
|
||||||
|
1D 1 DEFAULT
|
||||||
|
1E 1 DEFAULT
|
||||||
|
1F 1 DEFAULT
|
||||||
|
20 1 DEFAULT
|
||||||
|
21 10 LD IY,nn
|
||||||
|
22 16 LD (nn),IY
|
||||||
|
23 6 INC IY
|
||||||
|
24 4 INC IYH
|
||||||
|
25 4 DEC IYH
|
||||||
|
26 7 LD IYH,n
|
||||||
|
27 1 DEFAULT
|
||||||
|
28 1 DEFAULT
|
||||||
|
29 11 ADD IY,IY
|
||||||
|
2A 16 LD IY,(nn)
|
||||||
|
2B 6 DEC IY
|
||||||
|
2C 4 INC IYL
|
||||||
|
2D 4 DEC IYL
|
||||||
|
2E 7 LD IYL,n
|
||||||
|
2F 1 DEFAULT
|
||||||
|
30 1 DEFAULT
|
||||||
|
31 1 DEFAULT
|
||||||
|
32 1 DEFAULT
|
||||||
|
33 1 DEFAULT
|
||||||
|
34 19 INC b(IY+d)
|
||||||
|
35 19 DEC b(IY+d)
|
||||||
|
36 15 LD2 IY+d,n
|
||||||
|
37 1 DEFAULT
|
||||||
|
38 1 DEFAULT
|
||||||
|
39 11 ADD IY,SP
|
||||||
|
3A 1 DEFAULT
|
||||||
|
3B 1 DEFAULT
|
||||||
|
3C 1 DEFAULT
|
||||||
|
3D 1 DEFAULT
|
||||||
|
3E 1 DEFAULT
|
||||||
|
3F 1 DEFAULT
|
||||||
|
40 1 DEFAULT
|
||||||
|
41 1 DEFAULT
|
||||||
|
42 1 DEFAULT
|
||||||
|
43 1 DEFAULT
|
||||||
|
44 4 LD B,IYH
|
||||||
|
45 4 LD B,IYL
|
||||||
|
46 15 LD B,(IY+d)
|
||||||
|
47 1 DEFAULT
|
||||||
|
48 1 DEFAULT
|
||||||
|
49 1 DEFAULT
|
||||||
|
4A 1 DEFAULT
|
||||||
|
4B 1 DEFAULT
|
||||||
|
4C 4 LD C,IYH
|
||||||
|
4D 4 LD C,IYL
|
||||||
|
4E 15 LD C,(IY+d)
|
||||||
|
4F 1 DEFAULT
|
||||||
|
50 1 DEFAULT
|
||||||
|
51 1 DEFAULT
|
||||||
|
52 1 DEFAULT
|
||||||
|
53 1 DEFAULT
|
||||||
|
54 4 LD D,IYH
|
||||||
|
55 4 LD D,IYL
|
||||||
|
56 15 LD D,(IY+d)
|
||||||
|
57 1 DEFAULT
|
||||||
|
58 1 DEFAULT
|
||||||
|
59 1 DEFAULT
|
||||||
|
5A 1 DEFAULT
|
||||||
|
5B 1 DEFAULT
|
||||||
|
5C 4 LD E,IYH
|
||||||
|
5D 4 LD E,IYL
|
||||||
|
5E 15 LD E,(IY+d)
|
||||||
|
5F 1 DEFAULT
|
||||||
|
60 4 LD IYH,B
|
||||||
|
61 4 LD IYH,C
|
||||||
|
62 4 LD IYH,D
|
||||||
|
63 4 LD IYH,E
|
||||||
|
64 4 LD IYH,IYH
|
||||||
|
65 4 LD IYH,IYL
|
||||||
|
66 15 LD H,(IY+d)
|
||||||
|
67 4 LD IYH,A
|
||||||
|
68 4 LD IYL,B
|
||||||
|
69 4 LD IYL,C
|
||||||
|
6A 4 LD IYL,D
|
||||||
|
6B 4 LD IYL,E
|
||||||
|
6C 4 LD IYL,IYH
|
||||||
|
6D 4 LD IYL,IYL
|
||||||
|
6E 15 LD L,(IY+d)
|
||||||
|
6F 4 LD IYL,A
|
||||||
|
70 15 LD (IY+d),B
|
||||||
|
71 15 LD (IY+d),C
|
||||||
|
72 15 LD (IY+d),D
|
||||||
|
73 15 LD (IY+d),E
|
||||||
|
74 15 LD (IY+d),H
|
||||||
|
75 15 LD (IY+d),L
|
||||||
|
76 1 DEFAULT
|
||||||
|
77 15 LD (IY+d),A
|
||||||
|
78 1 DEFAULT
|
||||||
|
79 1 DEFAULT
|
||||||
|
7A 1 DEFAULT
|
||||||
|
7B 1 DEFAULT
|
||||||
|
7C 4 LD A,IYH
|
||||||
|
7D 4 LD A,IYL
|
||||||
|
7E 15 LD A,(IY+d)
|
||||||
|
7F 1 DEFAULT
|
||||||
|
80 1 DEFAULT
|
||||||
|
81 1 DEFAULT
|
||||||
|
82 1 DEFAULT
|
||||||
|
83 1 DEFAULT
|
||||||
|
84 4 ADD A,IYH
|
||||||
|
85 4 ADD A,IYL
|
||||||
|
86 15 ADD A,(IY+d)
|
||||||
|
87 1 DEFAULT
|
||||||
|
88 1 DEFAULT
|
||||||
|
89 1 DEFAULT
|
||||||
|
8A 1 DEFAULT
|
||||||
|
8B 1 DEFAULT
|
||||||
|
8C 4 ADC A,IYH
|
||||||
|
8D 4 ADC A,IYL
|
||||||
|
8E 15 ADC A,(IY+d)
|
||||||
|
8F 1 DEFAULT
|
||||||
|
90 1 DEFAULT
|
||||||
|
91 1 DEFAULT
|
||||||
|
92 1 DEFAULT
|
||||||
|
93 1 DEFAULT
|
||||||
|
94 4 SUB IYH
|
||||||
|
95 4 SUB IYL
|
||||||
|
96 15 SUB b(IY+d)
|
||||||
|
97 1 DEFAULT
|
||||||
|
98 1 DEFAULT
|
||||||
|
99 1 DEFAULT
|
||||||
|
9A 1 DEFAULT
|
||||||
|
9B 1 DEFAULT
|
||||||
|
9C 4 SBC A,IYH
|
||||||
|
9D 4 SBC A,IYL
|
||||||
|
9E 15 SBC A,(IY+d)
|
||||||
|
9F 1 DEFAULT
|
||||||
|
A0 1 DEFAULT
|
||||||
|
A1 1 DEFAULT
|
||||||
|
A2 1 DEFAULT
|
||||||
|
A3 1 DEFAULT
|
||||||
|
A4 4 AND IYH
|
||||||
|
A5 4 AND IYL
|
||||||
|
A6 15 AND b(IY+d)
|
||||||
|
A7 1 DEFAULT
|
||||||
|
A8 1 DEFAULT
|
||||||
|
A9 1 DEFAULT
|
||||||
|
AA 1 DEFAULT
|
||||||
|
AB 1 DEFAULT
|
||||||
|
AC 4 XOR IYH
|
||||||
|
AD 4 XOR IYL
|
||||||
|
AE 15 XOR b(IY+d)
|
||||||
|
AF 1 DEFAULT
|
||||||
|
B0 1 DEFAULT
|
||||||
|
B1 1 DEFAULT
|
||||||
|
B2 1 DEFAULT
|
||||||
|
B3 1 DEFAULT
|
||||||
|
B4 4 OR IYH
|
||||||
|
B5 4 OR IYL
|
||||||
|
B6 15 OR b(IY+d)
|
||||||
|
B7 1 DEFAULT
|
||||||
|
B8 1 DEFAULT
|
||||||
|
B9 1 DEFAULT
|
||||||
|
BA 1 DEFAULT
|
||||||
|
BB 1 DEFAULT
|
||||||
|
BC 4 CP IYH
|
||||||
|
BD 4 CP IYL
|
||||||
|
BE 15 CP b(IY+d)
|
||||||
|
BF 1 DEFAULT
|
||||||
|
C0 1 DEFAULT
|
||||||
|
C1 1 DEFAULT
|
||||||
|
C2 1 DEFAULT
|
||||||
|
C3 1 DEFAULT
|
||||||
|
C4 1 DEFAULT
|
||||||
|
C5 1 DEFAULT
|
||||||
|
C6 1 DEFAULT
|
||||||
|
C7 1 DEFAULT
|
||||||
|
C8 1 DEFAULT
|
||||||
|
C9 1 DEFAULT
|
||||||
|
CA 1 DEFAULT
|
||||||
|
CB * PREFIX
|
||||||
|
CC 1 DEFAULT
|
||||||
|
CD 1 DEFAULT
|
||||||
|
CE 1 DEFAULT
|
||||||
|
CF 1 DEFAULT
|
||||||
|
D0 1 DEFAULT
|
||||||
|
D1 1 DEFAULT
|
||||||
|
D2 1 DEFAULT
|
||||||
|
D3 1 DEFAULT
|
||||||
|
D4 1 DEFAULT
|
||||||
|
D5 1 DEFAULT
|
||||||
|
D6 1 DEFAULT
|
||||||
|
D7 1 DEFAULT
|
||||||
|
D8 1 DEFAULT
|
||||||
|
D9 1 DEFAULT
|
||||||
|
DA 1 DEFAULT
|
||||||
|
DB 1 DEFAULT
|
||||||
|
DC 1 DEFAULT
|
||||||
|
DD 1 DEFAULT
|
||||||
|
DE 1 DEFAULT
|
||||||
|
DF 1 DEFAULT
|
||||||
|
E0 1 DEFAULT
|
||||||
|
E1 10 POP IY
|
||||||
|
E2 1 DEFAULT
|
||||||
|
E3 19 EX (SP),IY
|
||||||
|
E4 1 DEFAULT
|
||||||
|
E5 11 PUSH IY
|
||||||
|
E6 1 DEFAULT
|
||||||
|
E7 1 DEFAULT
|
||||||
|
E8 1 DEFAULT
|
||||||
|
E9 4 JP IY
|
||||||
|
EA 1 DEFAULT
|
||||||
|
EB 1 DEFAULT
|
||||||
|
EC 1 DEFAULT
|
||||||
|
ED 1 DEFAULT
|
||||||
|
EE 1 DEFAULT
|
||||||
|
EF 1 DEFAULT
|
||||||
|
F0 1 DEFAULT
|
||||||
|
F1 1 DEFAULT
|
||||||
|
F2 1 DEFAULT
|
||||||
|
F3 1 DEFAULT
|
||||||
|
F4 1 DEFAULT
|
||||||
|
F5 1 DEFAULT
|
||||||
|
F6 1 DEFAULT
|
||||||
|
F7 1 DEFAULT
|
||||||
|
F8 1 DEFAULT
|
||||||
|
F9 6 LD SP,IY
|
||||||
|
FA 1 DEFAULT
|
||||||
|
FB 1 DEFAULT
|
||||||
|
FC 1 DEFAULT
|
||||||
|
FD 1 DEFAULT
|
||||||
|
FE 1 DEFAULT
|
||||||
|
FF 1 DEFAULT
|
1391
src/z80free/Z80free_codesFDCB.c
Normal file
1391
src/z80free/Z80free_codesFDCB.c
Normal file
File diff suppressed because it is too large
Load Diff
262
src/z80free/Z80free_codesFDCB.txt
Normal file
262
src/z80free/Z80free_codesFDCB.txt
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
# OPCODES, TSTATES and INSTRUCTIONS for FDCB prefixed instructions
|
||||||
|
# The TSTATES are 4 less than the real ones because they are counted
|
||||||
|
# when executing the FDCB prefix
|
||||||
|
#
|
||||||
|
# Instructions of the format LD r,XXX (IY+d) (like LD B,RLC (IY+d) )
|
||||||
|
# are modified to the format LD_XXX r,(IY+d) to simplify the parser
|
||||||
|
00 19 LD_RLC B,(IY+d)
|
||||||
|
01 19 LD_RLC C,(IY+d)
|
||||||
|
02 19 LD_RLC D,(IY+d)
|
||||||
|
03 19 LD_RLC E,(IY+d)
|
||||||
|
04 19 LD_RLC H,(IY+d)
|
||||||
|
05 19 LD_RLC L,(IY+d)
|
||||||
|
06 19 RLC b(IY+d)
|
||||||
|
07 19 LD_RLC A,(IY+d)
|
||||||
|
08 19 LD_RRC B,(IY+d)
|
||||||
|
09 19 LD_RRC C,(IY+d)
|
||||||
|
0A 19 LD_RRC D,(IY+d)
|
||||||
|
0B 19 LD_RRC E,(IY+d)
|
||||||
|
0C 19 LD_RRC H,(IY+d)
|
||||||
|
0D 19 LD_RRC L,(IY+d)
|
||||||
|
0E 19 RRC b(IY+d)
|
||||||
|
0F 19 LD_RRC A,(IY+d)
|
||||||
|
10 19 LD_RL B,(IY+d)
|
||||||
|
11 19 LD_RL C,(IY+d)
|
||||||
|
12 19 LD_RL D,(IY+d)
|
||||||
|
13 19 LD_RL E,(IY+d)
|
||||||
|
14 19 LD_RL H,(IY+d)
|
||||||
|
15 19 LD_RL L,(IY+d)
|
||||||
|
16 19 RL b(IY+d)
|
||||||
|
17 19 LD_RL A,(IY+d)
|
||||||
|
18 19 LD_RR B,(IY+d)
|
||||||
|
19 19 LD_RR C,(IY+d)
|
||||||
|
1A 19 LD_RR D,(IY+d)
|
||||||
|
1B 19 LD_RR E,(IY+d)
|
||||||
|
1C 19 LD_RR H,(IY+d)
|
||||||
|
1D 19 LD_RR L,(IY+d)
|
||||||
|
1E 19 RR b(IY+d)
|
||||||
|
1F 19 LD_RR A,(IY+d)
|
||||||
|
20 19 LD_SLA B,(IY+d)
|
||||||
|
21 19 LD_SLA C,(IY+d)
|
||||||
|
22 19 LD_SLA D,(IY+d)
|
||||||
|
23 19 LD_SLA E,(IY+d)
|
||||||
|
24 19 LD_SLA H,(IY+d)
|
||||||
|
25 19 LD_SLA L,(IY+d)
|
||||||
|
26 19 SLA b(IY+d)
|
||||||
|
27 19 LD_SLA A,(IY+d)
|
||||||
|
28 19 LD_SRA B,(IY+d)
|
||||||
|
29 19 LD_SRA C,(IY+d)
|
||||||
|
2A 19 LD_SRA D,(IY+d)
|
||||||
|
2B 19 LD_SRA E,(IY+d)
|
||||||
|
2C 19 LD_SRA H,(IY+d)
|
||||||
|
2D 19 LD_SRA L,(IY+d)
|
||||||
|
2E 19 SRA b(IY+d)
|
||||||
|
2F 19 LD_SRA A,(IY+d)
|
||||||
|
30 19 LD_SLL B,(IY+d)
|
||||||
|
31 19 LD_SLL C,(IY+d)
|
||||||
|
32 19 LD_SLL D,(IY+d)
|
||||||
|
33 19 LD_SLL E,(IY+d)
|
||||||
|
34 19 LD_SLL H,(IY+d)
|
||||||
|
35 19 LD_SLL L,(IY+d)
|
||||||
|
36 19 SLL b(IY+d)
|
||||||
|
37 19 LD_SLL A,(IY+d)
|
||||||
|
38 19 LD_SRL B,(IY+d)
|
||||||
|
39 19 LD_SRL C,(IY+d)
|
||||||
|
3A 19 LD_SRL D,(IY+d)
|
||||||
|
3B 19 LD_SRL E,(IY+d)
|
||||||
|
3C 19 LD_SRL H,(IY+d)
|
||||||
|
3D 19 LD_SRL L,(IY+d)
|
||||||
|
3E 19 SRL b(IY+d)
|
||||||
|
3F 19 LD_SRL A,(IY+d)
|
||||||
|
40 16 BIT 0,(IY+d)
|
||||||
|
41 16 BIT 0,(IY+d)
|
||||||
|
42 16 BIT 0,(IY+d)
|
||||||
|
43 16 BIT 0,(IY+d)
|
||||||
|
44 16 BIT 0,(IY+d)
|
||||||
|
45 16 BIT 0,(IY+d)
|
||||||
|
46 16 BIT 0,(IY+d)
|
||||||
|
47 16 BIT 0,(IY+d)
|
||||||
|
48 16 BIT 1,(IY+d)
|
||||||
|
49 16 BIT 1,(IY+d)
|
||||||
|
4A 16 BIT 1,(IY+d)
|
||||||
|
4B 16 BIT 1,(IY+d)
|
||||||
|
4C 16 BIT 1,(IY+d)
|
||||||
|
4D 16 BIT 1,(IY+d)
|
||||||
|
4E 16 BIT 1,(IY+d)
|
||||||
|
4F 16 BIT 1,(IY+d)
|
||||||
|
50 16 BIT 2,(IY+d)
|
||||||
|
51 16 BIT 2,(IY+d)
|
||||||
|
52 16 BIT 2,(IY+d)
|
||||||
|
53 16 BIT 2,(IY+d)
|
||||||
|
54 16 BIT 2,(IY+d)
|
||||||
|
55 16 BIT 2,(IY+d)
|
||||||
|
56 16 BIT 2,(IY+d)
|
||||||
|
57 16 BIT 2,(IY+d)
|
||||||
|
58 16 BIT 3,(IY+d)
|
||||||
|
59 16 BIT 3,(IY+d)
|
||||||
|
5A 16 BIT 3,(IY+d)
|
||||||
|
5B 16 BIT 3,(IY+d)
|
||||||
|
5C 16 BIT 3,(IY+d)
|
||||||
|
5D 16 BIT 3,(IY+d)
|
||||||
|
5E 16 BIT 3,(IY+d)
|
||||||
|
5F 16 BIT 3,(IY+d)
|
||||||
|
60 16 BIT 4,(IY+d)
|
||||||
|
61 16 BIT 4,(IY+d)
|
||||||
|
62 16 BIT 4,(IY+d)
|
||||||
|
63 16 BIT 4,(IY+d)
|
||||||
|
64 16 BIT 4,(IY+d)
|
||||||
|
65 16 BIT 4,(IY+d)
|
||||||
|
66 16 BIT 4,(IY+d)
|
||||||
|
67 16 BIT 4,(IY+d)
|
||||||
|
68 16 BIT 5,(IY+d)
|
||||||
|
69 16 BIT 5,(IY+d)
|
||||||
|
6A 16 BIT 5,(IY+d)
|
||||||
|
6B 16 BIT 5,(IY+d)
|
||||||
|
6C 16 BIT 5,(IY+d)
|
||||||
|
6D 16 BIT 5,(IY+d)
|
||||||
|
6E 16 BIT 5,(IY+d)
|
||||||
|
6F 16 BIT 5,(IY+d)
|
||||||
|
70 16 BIT 6,(IY+d)
|
||||||
|
71 16 BIT 6,(IY+d)
|
||||||
|
72 16 BIT 6,(IY+d)
|
||||||
|
73 16 BIT 6,(IY+d)
|
||||||
|
74 16 BIT 6,(IY+d)
|
||||||
|
75 16 BIT 6,(IY+d)
|
||||||
|
76 16 BIT 6,(IY+d)
|
||||||
|
77 16 BIT 6,(IY+d)
|
||||||
|
78 16 BIT 7,(IY+d)
|
||||||
|
79 16 BIT 7,(IY+d)
|
||||||
|
7A 16 BIT 7,(IY+d)
|
||||||
|
7B 16 BIT 7,(IY+d)
|
||||||
|
7C 16 BIT 7,(IY+d)
|
||||||
|
7D 16 BIT 7,(IY+d)
|
||||||
|
7E 16 BIT 7,(IY+d)
|
||||||
|
7F 16 BIT 7,(IY+d)
|
||||||
|
80 19 LD_RES B,0,(IY+d)
|
||||||
|
81 19 LD_RES C,0,(IY+d)
|
||||||
|
82 19 LD_RES D,0,(IY+d)
|
||||||
|
83 19 LD_RES E,0,(IY+d)
|
||||||
|
84 19 LD_RES H,0,(IY+d)
|
||||||
|
85 19 LD_RES L,0,(IY+d)
|
||||||
|
86 19 RES 0,(IY+d)
|
||||||
|
87 19 LD_RES A,0,(IY+d)
|
||||||
|
88 19 LD_RES B,1,(IY+d)
|
||||||
|
89 19 LD_RES C,1,(IY+d)
|
||||||
|
8A 19 LD_RES D,1,(IY+d)
|
||||||
|
8B 19 LD_RES E,1,(IY+d)
|
||||||
|
8C 19 LD_RES H,1,(IY+d)
|
||||||
|
8D 19 LD_RES L,1,(IY+d)
|
||||||
|
8E 19 RES 1,(IY+d)
|
||||||
|
8F 19 LD_RES A,1,(IY+d)
|
||||||
|
90 19 LD_RES B,2,(IY+d)
|
||||||
|
91 19 LD_RES C,2,(IY+d)
|
||||||
|
92 19 LD_RES D,2,(IY+d)
|
||||||
|
93 19 LD_RES E,2,(IY+d)
|
||||||
|
94 19 LD_RES H,2,(IY+d)
|
||||||
|
95 19 LD_RES L,2,(IY+d)
|
||||||
|
96 19 RES 2,(IY+d)
|
||||||
|
97 19 LD_RES A,2,(IY+d)
|
||||||
|
98 19 LD_RES B,3,(IY+d)
|
||||||
|
99 19 LD_RES C,3,(IY+d)
|
||||||
|
9A 19 LD_RES D,3,(IY+d)
|
||||||
|
9B 19 LD_RES E,3,(IY+d)
|
||||||
|
9C 19 LD_RES H,3,(IY+d)
|
||||||
|
9D 19 LD_RES L,3,(IY+d)
|
||||||
|
9E 19 RES 3,(IY+d)
|
||||||
|
9F 19 LD_RES A,3,(IY+d)
|
||||||
|
A0 19 LD_RES B,4,(IY+d)
|
||||||
|
A1 19 LD_RES C,4,(IY+d)
|
||||||
|
A2 19 LD_RES D,4,(IY+d)
|
||||||
|
A3 19 LD_RES E,4,(IY+d)
|
||||||
|
A4 19 LD_RES H,4,(IY+d)
|
||||||
|
A5 19 LD_RES L,4,(IY+d)
|
||||||
|
A6 19 RES 4,(IY+d)
|
||||||
|
A7 19 LD_RES A,4,(IY+d)
|
||||||
|
A8 19 LD_RES B,5,(IY+d)
|
||||||
|
A9 19 LD_RES C,5,(IY+d)
|
||||||
|
AA 19 LD_RES D,5,(IY+d)
|
||||||
|
AB 19 LD_RES E,5,(IY+d)
|
||||||
|
AC 19 LD_RES H,5,(IY+d)
|
||||||
|
AD 19 LD_RES L,5,(IY+d)
|
||||||
|
AE 19 RES 5,(IY+d)
|
||||||
|
AF 19 LD_RES A,5,(IY+d)
|
||||||
|
B0 19 LD_RES B,6,(IY+d)
|
||||||
|
B1 19 LD_RES C,6,(IY+d)
|
||||||
|
B2 19 LD_RES D,6,(IY+d)
|
||||||
|
B3 19 LD_RES E,6,(IY+d)
|
||||||
|
B4 19 LD_RES H,6,(IY+d)
|
||||||
|
B5 19 LD_RES L,6,(IY+d)
|
||||||
|
B6 19 RES 6,(IY+d)
|
||||||
|
B7 19 LD_RES A,6,(IY+d)
|
||||||
|
B8 19 LD_RES B,7,(IY+d)
|
||||||
|
B9 19 LD_RES C,7,(IY+d)
|
||||||
|
BA 19 LD_RES D,7,(IY+d)
|
||||||
|
BB 19 LD_RES E,7,(IY+d)
|
||||||
|
BC 19 LD_RES H,7,(IY+d)
|
||||||
|
BD 19 LD_RES L,7,(IY+d)
|
||||||
|
BE 19 RES 7,(IY+d)
|
||||||
|
BF 19 LD_RES A,7,(IY+d)
|
||||||
|
C0 19 LD_SET B,0,(IY+d)
|
||||||
|
C1 19 LD_SET C,0,(IY+d)
|
||||||
|
C2 19 LD_SET D,0,(IY+d)
|
||||||
|
C3 19 LD_SET E,0,(IY+d)
|
||||||
|
C4 19 LD_SET H,0,(IY+d)
|
||||||
|
C5 19 LD_SET L,0,(IY+d)
|
||||||
|
C6 19 SET 0,(IY+d)
|
||||||
|
C7 19 LD_SET A,0,(IY+d)
|
||||||
|
C8 19 LD_SET B,1,(IY+d)
|
||||||
|
C9 19 LD_SET C,1,(IY+d)
|
||||||
|
CA 19 LD_SET D,1,(IY+d)
|
||||||
|
CB 19 LD_SET E,1,(IY+d)
|
||||||
|
CC 19 LD_SET H,1,(IY+d)
|
||||||
|
CD 19 LD_SET L,1,(IY+d)
|
||||||
|
CE 19 SET 1,(IY+d)
|
||||||
|
CF 19 LD_SET A,1,(IY+d)
|
||||||
|
D0 19 LD_SET B,2,(IY+d)
|
||||||
|
D1 19 LD_SET C,2,(IY+d)
|
||||||
|
D2 19 LD_SET D,2,(IY+d)
|
||||||
|
D3 19 LD_SET E,2,(IY+d)
|
||||||
|
D4 19 LD_SET H,2,(IY+d)
|
||||||
|
D5 19 LD_SET L,2,(IY+d)
|
||||||
|
D6 19 SET 2,(IY+d)
|
||||||
|
D7 19 LD_SET A,2,(IY+d)
|
||||||
|
D8 19 LD_SET B,3,(IY+d)
|
||||||
|
D9 19 LD_SET C,3,(IY+d)
|
||||||
|
DA 19 LD_SET D,3,(IY+d)
|
||||||
|
DB 19 LD_SET E,3,(IY+d)
|
||||||
|
DC 19 LD_SET H,3,(IY+d)
|
||||||
|
DD 19 LD_SET L,3,(IY+d)
|
||||||
|
DE 19 SET 3,(IY+d)
|
||||||
|
DF 19 LD_SET A,3,(IY+d)
|
||||||
|
E0 19 LD_SET B,4,(IY+d)
|
||||||
|
E1 19 LD_SET C,4,(IY+d)
|
||||||
|
E2 19 LD_SET D,4,(IY+d)
|
||||||
|
E3 19 LD_SET E,4,(IY+d)
|
||||||
|
E4 19 LD_SET H,4,(IY+d)
|
||||||
|
E5 19 LD_SET L,4,(IY+d)
|
||||||
|
E6 19 SET 4,(IY+d)
|
||||||
|
E7 19 LD_SET A,4,(IY+d)
|
||||||
|
E8 19 LD_SET B,5,(IY+d)
|
||||||
|
E9 19 LD_SET C,5,(IY+d)
|
||||||
|
EA 19 LD_SET D,5,(IY+d)
|
||||||
|
EB 19 LD_SET E,5,(IY+d)
|
||||||
|
EC 19 LD_SET H,5,(IY+d)
|
||||||
|
ED 19 LD_SET L,5,(IY+d)
|
||||||
|
EE 19 SET 5,(IY+d)
|
||||||
|
EF 19 LD_SET A,5,(IY+d)
|
||||||
|
F0 19 LD_SET B,6,(IY+d)
|
||||||
|
F1 19 LD_SET C,6,(IY+d)
|
||||||
|
F2 19 LD_SET D,6,(IY+d)
|
||||||
|
F3 19 LD_SET E,6,(IY+d)
|
||||||
|
F4 19 LD_SET H,6,(IY+d)
|
||||||
|
F5 19 LD_SET L,6,(IY+d)
|
||||||
|
F6 19 SET 6,(IY+d)
|
||||||
|
F7 19 LD_SET A,6,(IY+d)
|
||||||
|
F8 19 LD_SET B,7,(IY+d)
|
||||||
|
F9 19 LD_SET C,7,(IY+d)
|
||||||
|
FA 19 LD_SET D,7,(IY+d)
|
||||||
|
FB 19 LD_SET E,7,(IY+d)
|
||||||
|
FC 19 LD_SET H,7,(IY+d)
|
||||||
|
FD 19 LD_SET L,7,(IY+d)
|
||||||
|
FE 19 SET 7,(IY+d)
|
||||||
|
FF 19 LD_SET A,7,(IY+d)
|
18395
src/z80free/tests.expected
Normal file
18395
src/z80free/tests.expected
Normal file
File diff suppressed because it is too large
Load Diff
9011
src/z80free/tests.in
Normal file
9011
src/z80free/tests.in
Normal file
File diff suppressed because it is too large
Load Diff
14752
src/z80free/tests.z80free
Normal file
14752
src/z80free/tests.z80free
Normal file
File diff suppressed because it is too large
Load Diff
1
src/z80free/z80_test.pnproj
Normal file
1
src/z80free/z80_test.pnproj
Normal file
@ -0,0 +1 @@
|
|||||||
|
<Project name="z80_test"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="z80free" path=""><MagicFolder excludeFolders="CVS;.svn" filter="*" name="build" path="build\"><File path="Z80free.d"></File><File path="Z80free.o"></File><File path="Z80free_codes.d"></File><File path="Z80free_codes.o"></File><File path="Z80free_codesCB.d"></File><File path="Z80free_codesCB.o"></File><File path="Z80free_codesDD.d"></File><File path="Z80free_codesDD.o"></File><File path="Z80free_codesDDCB.d"></File><File path="Z80free_codesDDCB.o"></File><File path="Z80free_codesED.d"></File><File path="Z80free_codesED.o"></File><File path="Z80free_codesFD.d"></File><File path="Z80free_codesFD.o"></File><File path="Z80free_codesFDCB.d"></File><File path="Z80free_codesFDCB.o"></File><File path="z80free_tester.d"></File><File path="z80free_tester.o"></File><File path="z80_test.elf.map"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="prova union" path="prova union\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="build" path="build\"><File path="Z80free_prova.d"></File><File path="Z80free_prova.o"></File><File path="z80_prova.elf.map"></File></MagicFolder><File path="logfile_big_endian.txt"></File><File path="logfile_big_endian.zip"></File><File path="logfile_little_endian.txt"></File><File path="logfile_little_endian.zip"></File><File path="Makefile"></File><File path="Z80free_prova.c"></File><File path="z80_prova.dol"></File><File path="z80_prova.elf"></File><File path="z80_test.pnproj"></File><File path="z80_test.pnps"></File></MagicFolder><File path="COPYING"></File><File path="Makefile"></File><File path="Makefile.ori"></File><File path="README.txt"></File><File path="tests.expected"></File><File path="tests.in"></File><File path="tests.z80free"></File><File path="Z80free.c"></File><File path="Z80free.h"></File><File path="Z80free_codes.c"></File><File path="Z80free_codes.txt"></File><File path="Z80free_codesCB.c"></File><File path="Z80free_codesCB.txt"></File><File path="Z80free_codesDD.c"></File><File path="Z80free_codesDD.txt"></File><File path="Z80free_codesDDCB.c"></File><File path="Z80free_codesDDCB.txt"></File><File path="Z80free_codesED.c"></File><File path="Z80free_codesED.txt"></File><File path="Z80free_codesFD.c"></File><File path="Z80free_codesFD.txt"></File><File path="Z80free_codesFDCB.c"></File><File path="Z80free_codesFDCB.txt"></File><File path="z80free_gencode.py"></File><File path="z80free_tester.c"></File><File path="z80free_testgen.py"></File><File path="z80txt_converter.py"></File><File path="z80_test.dol"></File><File path="z80_test.elf"></File><File path="z80_test.pnproj"></File><File path="z80_test.pnps"></File></MagicFolder><File path="Makefile"></File></Project>
|
1
src/z80free/z80_test.pnps
Normal file
1
src/z80free/z80_test.pnps
Normal file
@ -0,0 +1 @@
|
|||||||
|
<pd><ViewState><e p="z80_test" x="true"></e><e p="z80_test\z80free" x="true"></e><e p="z80_test\z80free\build" x="false"></e><e p="z80_test\z80free\prova union" x="false"></e></ViewState></pd>
|
1308
src/z80free/z80free_gencode.py
Normal file
1308
src/z80free/z80free_gencode.py
Normal file
File diff suppressed because it is too large
Load Diff
286
src/z80free/z80free_tester.c
Normal file
286
src/z80free/z80free_tester.c
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
* This file is part of Z80Free, with some bits extracted
|
||||||
|
* and fixed from libZ80 (from Gabriel Gambetta)
|
||||||
|
*
|
||||||
|
* Z80Free 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Z80Free 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Z80free.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef GEKKO
|
||||||
|
#include <gccore.h>
|
||||||
|
#include <fat.h>
|
||||||
|
|
||||||
|
FILE *fdebug;
|
||||||
|
#define printf(...) fprintf(fdebug,__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Z80FREE emulator,emulator2;
|
||||||
|
unsigned char memory[65536];
|
||||||
|
FILE *infile;
|
||||||
|
char test_name[20];
|
||||||
|
byte ports[256];
|
||||||
|
word portdirs[256];
|
||||||
|
int portpos=0,elements=0;
|
||||||
|
|
||||||
|
#define NO35
|
||||||
|
|
||||||
|
int compare_processors() {
|
||||||
|
|
||||||
|
if (emulator.Rm.br.A!=emulator2.Rm.br.A) {
|
||||||
|
printf("A should be %X but is %X\n",emulator2.Rm.br.A,emulator.Rm.br.A);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NO35
|
||||||
|
if ((emulator.Rm.br.F|0x28)!=(emulator2.Rm.br.F|0x28)) {
|
||||||
|
printf("F should be %X but is %X\n",emulator2.Rm.br.F,emulator.Rm.br.F);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (emulator.Rm.br.F!=emulator2.Rm.br.F) {
|
||||||
|
printf("F should be %X but is %X\n",emulator2.Rm.br.F,emulator.Rm.br.F);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (emulator.Rm.wr.BC!=emulator2.Rm.wr.BC) {
|
||||||
|
printf("BC should be %X but is %X\n",emulator2.Rm.wr.BC,emulator.Rm.wr.BC);
|
||||||
|
}
|
||||||
|
if (emulator.Rm.wr.DE!=emulator2.Rm.wr.DE) {
|
||||||
|
printf("DE should be %X but is %X\n",emulator2.Rm.wr.DE,emulator.Rm.wr.DE);
|
||||||
|
}
|
||||||
|
if (emulator.Rm.wr.HL!=emulator2.Rm.wr.HL) {
|
||||||
|
printf("HL should be %X but is %X\n",emulator2.Rm.wr.HL,emulator.Rm.wr.HL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emulator.Ra.br.A!=emulator2.Ra.br.A) {
|
||||||
|
printf("A' should be %X but is %X\n",emulator2.Ra.br.A,emulator.Ra.br.A);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NO35
|
||||||
|
if ((emulator.Ra.br.F|0x28)!=(emulator2.Ra.br.F|0x28)) {
|
||||||
|
printf("F' should be %X but is %X\n",emulator2.Ra.br.F,emulator.Ra.br.F);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (emulator.Ra.br.F!=emulator2.Ra.br.F) {
|
||||||
|
printf("F' should be %X but is %X\n",emulator2.Ra.br.F,emulator.Ra.br.F);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (emulator.Ra.wr.BC!=emulator2.Ra.wr.BC) {
|
||||||
|
printf("BC' should be %X but is %X\n",emulator2.Ra.wr.BC,emulator.Ra.wr.BC);
|
||||||
|
}
|
||||||
|
if (emulator.Ra.wr.DE!=emulator2.Ra.wr.DE) {
|
||||||
|
printf("DE' should be %X but is %X\n",emulator2.Ra.wr.DE,emulator.Ra.wr.DE);
|
||||||
|
}
|
||||||
|
if (emulator.Ra.wr.HL!=emulator2.Ra.wr.HL) {
|
||||||
|
printf("HL' should be %X but is %X\n",emulator2.Ra.wr.HL,emulator.Ra.wr.HL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emulator.Rm.wr.IX!=emulator2.Rm.wr.IX) {
|
||||||
|
printf("IX should be %X but is %X\n",emulator2.Rm.wr.IX,emulator.Rm.wr.IX);
|
||||||
|
}
|
||||||
|
if (emulator.Rm.wr.IY!=emulator2.Rm.wr.IY) {
|
||||||
|
printf("IY should be %X but is %X\n",emulator2.Rm.wr.IY,emulator.Rm.wr.IY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emulator.PC!=emulator2.PC) {
|
||||||
|
printf("PC should be %X but is %X\n",emulator2.PC,emulator.PC);
|
||||||
|
}
|
||||||
|
if (emulator.Rm.wr.SP!=emulator2.Rm.wr.SP) {
|
||||||
|
printf("SP should be %X but is %X\n",emulator2.Rm.wr.SP,emulator.Rm.wr.SP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emulator.HALT!=emulator2.HALT) {
|
||||||
|
printf("HALT should be %X but is %X\n",emulator2.HALT,emulator.HALT);
|
||||||
|
}
|
||||||
|
if (emulator.I!=emulator2.I) {
|
||||||
|
printf("I should be %X but is %X\n",emulator2.I,emulator.I);
|
||||||
|
}
|
||||||
|
if ((emulator.R&0x7F)!=(emulator2.R&0x7F)) {
|
||||||
|
printf("R should be %X but is %X\n",(emulator2.R&0x7F),(emulator.R&0x7F));
|
||||||
|
}
|
||||||
|
if (emulator.IM!=emulator2.IM) {
|
||||||
|
printf("IM should be %X but is %X\n",emulator2.IM,emulator.IM);
|
||||||
|
}
|
||||||
|
if (emulator.IFF1!=emulator2.IFF1) {
|
||||||
|
printf("IFF1 should be %X but is %X\n",emulator2.IFF1,emulator.IFF1);
|
||||||
|
}
|
||||||
|
if (emulator.IFF2!=emulator2.IFF2) {
|
||||||
|
printf("IFF2 should be %X but is %X\n",emulator2.IFF2,emulator.IFF2);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_elements(Z80FREE *emulador) {
|
||||||
|
|
||||||
|
int tstates,retval;
|
||||||
|
unsigned short int v1,v2,v3,v4,v5,v6,v7,v8,v9,v10;
|
||||||
|
|
||||||
|
|
||||||
|
Z80free_reset(emulador);
|
||||||
|
|
||||||
|
retval=fscanf(infile,"%hx %hx %hx %hx",(unsigned short int *)&emulador->Rm.wr.AF,(unsigned short int *)&emulador->Rm.wr.BC,(unsigned short int *)&emulador->Rm.wr.DE,(unsigned short int *)&emulador->Rm.wr.HL);
|
||||||
|
retval=fscanf(infile,"%hx %hx %hx %hx",&v7,&v8,&v9,&v10);
|
||||||
|
emulador->Ra.wr.AF=v7;
|
||||||
|
emulador->Ra.wr.BC=v8;
|
||||||
|
emulador->Ra.wr.DE=v9;
|
||||||
|
emulador->Ra.wr.HL=v10;
|
||||||
|
retval=fscanf(infile,"%hx %hx %hx %hx",(unsigned short int *)&emulador->Rm.wr.IX,(unsigned short int *)&emulador->Rm.wr.IY,(unsigned short int *)&emulador->Rm.wr.SP,(unsigned short int *)&emulador->PC);
|
||||||
|
retval=fscanf(infile,"%hx %hx %hx %hx %hx %hx %d",&v1,&v2,&v3,&v4,&v5,&v6,&tstates);
|
||||||
|
|
||||||
|
emulador->I=v1;
|
||||||
|
emulador->R=v2;
|
||||||
|
emulador->R2=v2;
|
||||||
|
emulador->IFF1=v3;
|
||||||
|
emulador->IFF2=v4;
|
||||||
|
emulador->IM=v5;
|
||||||
|
emulador->HALT=v6;
|
||||||
|
|
||||||
|
return (tstates);
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_memory(char mode) {
|
||||||
|
// mode=0 : store value in memory
|
||||||
|
// mode=1 : compare value with memory
|
||||||
|
|
||||||
|
int position,retval,value;
|
||||||
|
|
||||||
|
|
||||||
|
retval=fscanf(infile,"%x",&position);
|
||||||
|
if (position==-1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
retval=fscanf(infile,"%x",&value);
|
||||||
|
|
||||||
|
if (value!=-1) {
|
||||||
|
if (mode) {
|
||||||
|
if (memory[position]!=value) {
|
||||||
|
printf("Error in memory, address %X. Expected value: %X, current value: %X\n",position,value,memory[position]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memory[position]= (byte) value;
|
||||||
|
}
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
} while(value!=-1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int read_inports() {
|
||||||
|
|
||||||
|
int retval, value, addr;
|
||||||
|
|
||||||
|
|
||||||
|
portpos=0;
|
||||||
|
elements=0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
retval=fscanf(infile,"%x",&addr);
|
||||||
|
if (addr==-1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
retval=fscanf(infile,"%x",&value);
|
||||||
|
portdirs[elements]=(word) addr;
|
||||||
|
ports[elements]=(byte) value;
|
||||||
|
elements++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int read_test() {
|
||||||
|
|
||||||
|
int retval,tstates,tst2,totaltst;
|
||||||
|
|
||||||
|
retval=fscanf(infile,"%s",test_name);
|
||||||
|
if (retval<=0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("Test %s\n",test_name);
|
||||||
|
tstates=read_elements(&emulator);
|
||||||
|
while(0==read_memory(0)) {
|
||||||
|
}
|
||||||
|
read_inports();
|
||||||
|
totaltst=0;
|
||||||
|
while(totaltst<tstates) {
|
||||||
|
totaltst+=Z80free_step(&emulator);
|
||||||
|
}
|
||||||
|
tst2=read_elements(&emulator2);
|
||||||
|
compare_processors();
|
||||||
|
if (totaltst!=tst2) {
|
||||||
|
printf("Test needed %d tstates, but should needed %d\n",totaltst,tst2);
|
||||||
|
}
|
||||||
|
while(0==read_memory(1)) {
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte Z80free_Rd (register word Addr) {
|
||||||
|
|
||||||
|
return ((byte)memory[Addr]);
|
||||||
|
|
||||||
|
}
|
||||||
|
void Z80free_Wr (register word Addr, register byte Value) {
|
||||||
|
|
||||||
|
memory[Addr]=(unsigned char) Value;
|
||||||
|
|
||||||
|
}
|
||||||
|
byte Z80free_In (register word Port) {
|
||||||
|
|
||||||
|
byte value;
|
||||||
|
|
||||||
|
if (portpos>=elements) {
|
||||||
|
printf("IN beyond values\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Port!=portdirs[portpos])
|
||||||
|
printf("IN to port %X (should be %X)\n",Port,portdirs[portpos]);
|
||||||
|
value=ports[portpos];
|
||||||
|
portpos++;
|
||||||
|
return (value);
|
||||||
|
|
||||||
|
}
|
||||||
|
void Z80free_Out (register word Port, register byte Value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
#ifdef GEKKO
|
||||||
|
|
||||||
|
//initialize libfat library
|
||||||
|
fatInitDefault();
|
||||||
|
|
||||||
|
fdebug = fopen("/logfile_big.txt","w");
|
||||||
|
|
||||||
|
infile=fopen("/apps/z80_test/tests.z80free","r");
|
||||||
|
|
||||||
|
#else
|
||||||
|
infile=fopen("tests.z80free","r");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(0==read_test()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
83
src/z80free/z80free_testgen.py
Normal file
83
src/z80free/z80free_testgen.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2008-2009 (C) Raster Software Vigo (Sergio Costas)
|
||||||
|
|
||||||
|
# This file is part of Z80Free
|
||||||
|
#
|
||||||
|
# Z80Free 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 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Z80Free 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
infile=open("tests.in","r")
|
||||||
|
expected=open("tests.expected","r")
|
||||||
|
|
||||||
|
outfile=open("tests.z80free","w")
|
||||||
|
|
||||||
|
maximo=0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# read the test
|
||||||
|
while True:
|
||||||
|
test_name=""
|
||||||
|
test_name=infile.readline()
|
||||||
|
if test_name!="\n":
|
||||||
|
break
|
||||||
|
if test_name=="": # EOF
|
||||||
|
break
|
||||||
|
print test_name
|
||||||
|
outfile.write(test_name)
|
||||||
|
linea=infile.readline()
|
||||||
|
while linea[:2]!="-1":
|
||||||
|
outfile.write(linea)
|
||||||
|
linea=infile.readline()
|
||||||
|
outfile.write("-1\n")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
test_name2=expected.readline()
|
||||||
|
if test_name2!="\n":
|
||||||
|
break
|
||||||
|
if test_name2=="": #EOF
|
||||||
|
continue
|
||||||
|
if (test_name2!=test_name):
|
||||||
|
print "error, %(entrada)s y %(salida)s no coinciden"%{"entrada":test_name,"salida":test_name2}
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
port=[]
|
||||||
|
while True: # jump over event lines
|
||||||
|
linea=expected.readline()
|
||||||
|
if linea[0]!=' ':
|
||||||
|
break
|
||||||
|
pos=linea.find("PR")
|
||||||
|
if pos==-1:
|
||||||
|
continue
|
||||||
|
port.append(linea[pos+3:])
|
||||||
|
|
||||||
|
print linea
|
||||||
|
for element in port:
|
||||||
|
outfile.write(element)
|
||||||
|
outfile.write(" ")
|
||||||
|
outfile.write("-1\n")
|
||||||
|
outfile.write(linea) # registers
|
||||||
|
linea=expected.readline()
|
||||||
|
print linea
|
||||||
|
while (linea!="\n") and (linea!=""):
|
||||||
|
print linea
|
||||||
|
outfile.write(linea)
|
||||||
|
linea=expected.readline()
|
||||||
|
outfile.write("-1\n\n")
|
||||||
|
|
||||||
|
infile.close()
|
||||||
|
expected.close()
|
||||||
|
outfile.close()
|
67
src/z80free/z80txt_converter.py
Normal file
67
src/z80free/z80txt_converter.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
fichero1=open(sys.argv[1],"r")
|
||||||
|
fichero2=open(sys.argv[2],"w")
|
||||||
|
|
||||||
|
def escribe_linea(thefile,nlinea3,pp2,pp3):
|
||||||
|
|
||||||
|
nlinea2=hex(nlinea3)[2:].upper()
|
||||||
|
while len(nlinea2)<2:
|
||||||
|
nlinea2="0"+nlinea2
|
||||||
|
|
||||||
|
thefile.write(nlinea2+"\t"+pp2+"\t"+pp3+"\n")
|
||||||
|
|
||||||
|
contador2=0
|
||||||
|
for linea in fichero1:
|
||||||
|
if linea[-1]=="\n":
|
||||||
|
linea=linea[:-1]
|
||||||
|
if linea=="":
|
||||||
|
continue
|
||||||
|
contador=0
|
||||||
|
nlinea=""
|
||||||
|
for caracter in linea:
|
||||||
|
if caracter=='\t':
|
||||||
|
nlinea+=(" "*(8-contador))
|
||||||
|
contador=-1
|
||||||
|
else:
|
||||||
|
nlinea+=caracter
|
||||||
|
contador+=1
|
||||||
|
if contador==8:
|
||||||
|
contador=0
|
||||||
|
|
||||||
|
if len(nlinea)<49:
|
||||||
|
nlinea+=" "*(49-len(nlinea))
|
||||||
|
|
||||||
|
p1=nlinea[:9]
|
||||||
|
p2=nlinea[16:40]
|
||||||
|
p3=nlinea[40:48]
|
||||||
|
|
||||||
|
while (p1!="") and (p1[-1]==" "):
|
||||||
|
p1=p1[:-1]
|
||||||
|
while (p2!="") and (p2[-1]==" "):
|
||||||
|
p2=p2[:-1]
|
||||||
|
while (p3!="") and (p3[-1]==" "):
|
||||||
|
p3=p3[:-1]
|
||||||
|
|
||||||
|
try:
|
||||||
|
if ((p1[:4].upper()=="FDCB") or (p1[:4].upper()=="DDCB")) and (len(p1)>8):
|
||||||
|
nlinea=int(p1[7:],16)
|
||||||
|
elif (len(p1)>3) and ((p1[:2].upper()=="CB") or (p1[:2].upper()=="ED") or (p1[:2].upper()=="DD") or (p1[:2].upper()=="FD")):
|
||||||
|
nlinea=int(p1[2:4],16)
|
||||||
|
else:
|
||||||
|
nlinea=int(p1[:2],16)
|
||||||
|
except:
|
||||||
|
print p1
|
||||||
|
|
||||||
|
while contador2<nlinea:
|
||||||
|
escribe_linea(fichero2,contador2,"","")
|
||||||
|
contador2+=1
|
||||||
|
if p3=="":
|
||||||
|
p3="*"
|
||||||
|
escribe_linea(fichero2,nlinea,p3,p2)
|
||||||
|
contador2+=1
|
||||||
|
|
||||||
|
fichero2.close()
|
||||||
|
fichero1.close()
|
Loading…
Reference in New Issue
Block a user