first commit
This commit is contained in:
commit
4b8f46b13d
61 changed files with 6560 additions and 0 deletions
340
COPYING.txt
Normal file
340
COPYING.txt
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
4
CVS/Entries
Normal file
4
CVS/Entries
Normal file
|
@ -0,0 +1,4 @@
|
|||
/COPYING.txt/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/Makefile/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/README.txt/1.2/Mon Oct 28 16:40:18 2002//
|
||||
D
|
3
CVS/Entries.Log
Normal file
3
CVS/Entries.Log
Normal file
|
@ -0,0 +1,3 @@
|
|||
A D/bin////
|
||||
A D/obj////
|
||||
A D/src////
|
1
CVS/Repository
Normal file
1
CVS/Repository
Normal file
|
@ -0,0 +1 @@
|
|||
hpemu
|
1
CVS/Root
Normal file
1
CVS/Root
Normal file
|
@ -0,0 +1 @@
|
|||
:pserver:anonymous@a.cvs.sourceforge.net:/cvsroot/hpemu
|
67
Makefile
Normal file
67
Makefile
Normal file
|
@ -0,0 +1,67 @@
|
|||
# /
|
||||
# /__ ___ ___ ____
|
||||
# / / / / /__/ / / / / /
|
||||
# / / /__/ /__ / / /__/
|
||||
# /
|
||||
# / version 0.9.0
|
||||
#
|
||||
# Copyright 2002 Daniel Nilsson
|
||||
#
|
||||
# This file is part of hpemu.
|
||||
#
|
||||
# Hpemu is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Hpemu 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 hpemu; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
HPEMU = bin/hpemu.exe
|
||||
OBJS = obj/bus.o obj/color.o obj/cpu.o obj/disasm.o obj/display.o obj/emulator.o obj/gui.o obj/hdw.o obj/keyboard.o obj/main.o obj/opcodes.o obj/pabout.o obj/pcalc.o obj/pdebug.o obj/pfiles.o obj/pmenu.o obj/ports.o obj/ram.o obj/rom.o obj/rpl.o obj/timers.o
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Werror -O3
|
||||
|
||||
all: hpemu
|
||||
|
||||
hpemu: $(HPEMU)
|
||||
|
||||
$(HPEMU): $(OBJS)
|
||||
$(CC) -mwindows -o $@ $+ -lalleg
|
||||
|
||||
obj/%.o: src/%.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
obj/bus.o: src/types.h src/rom.h src/ram.h src/ports.h src/hdw.h src/bus.h
|
||||
obj/color.o: src/color.h
|
||||
obj/cpu.o: src/types.h src/emulator.h src/bus.h src/opcodes.h src/cpu.h
|
||||
obj/cpu.o: src/types.h src/opcodes.h src/disasm.h
|
||||
obj/display.o: src/types.h src/bus.h
|
||||
obj/emulator.o: src/types.h src/cpu.h src/bus.h src/timers.h src/display.h src/gui.h src/pdebug.h src/emulator.h
|
||||
obj/gui.o: src/color.h src/pmenu.h src/pcalc.h src/pdebug.h src/pfiles.h src/pabout.h src/gui.h
|
||||
obj/hdw.o: src/types.h src/bus.h src/ports.h src/timers.h src/display.h src/hdw.h
|
||||
obj/keyboard.o: src/types.h src/cpu.h src/keyboard.h
|
||||
obj/main.o: src/types.h src/emulator.h src/gui.h src/color.h
|
||||
obj/opcodes.o: src/types.h src/cpu.h src/bus.h src/keyboard.h src/opcodes.h src/opinline.h
|
||||
obj/pabout.o: src/color.h src/gui.h src/pabout.h
|
||||
obj/pcalc.o: src/color.h src/display.h src/keyboard.h src/gui.h src/pcalc.h
|
||||
obj/pdebug.o: src/types.h src/emulator.h src/cpu.h src/bus.h src/disasm.h src/color.h src/gui.h src/pdebug.h
|
||||
obj/pfiles.o: src/color.h src/gui.h src/rpl.h src/pfiles.h
|
||||
obj/pmenu.o: src/emulator.h src/color.h src/gui.h src/pmenu.h
|
||||
obj/ports.o: src/types.h src/bus.h src/ports.h
|
||||
obj/ram.o: src/types.h src/bus.h src/ram.h
|
||||
obj/rom.o: src/types.h src/bus.h src/rom.h
|
||||
obj/rpl.o: src/types.h src/bus.h src/opinline.h src/rpl.h
|
||||
obj/timers.o: src/types.h src/cpu.h src/timers.h
|
||||
|
||||
|
||||
|
||||
|
||||
|
128
README.txt
Normal file
128
README.txt
Normal file
|
@ -0,0 +1,128 @@
|
|||
/
|
||||
/__ ___ ___ ____
|
||||
/ / / / /__/ / / / / /
|
||||
/ / /__/ /__ / / /__/
|
||||
/
|
||||
/ version 0.9.0
|
||||
|
||||
Copyright 2002 Daniel Nilsson
|
||||
|
||||
This file is part of hpemu.
|
||||
|
||||
Hpemu is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Hpemu 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 hpemu; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
The GNU General Public License is included in the file COPYING.txt
|
||||
|
||||
|
||||
********************
|
||||
*** INTRODUCTION ***
|
||||
********************
|
||||
|
||||
Hpemu is an emulator for the HP48GX calculator.
|
||||
Hpemu is intended for developers of software for the calculator but
|
||||
other people may find it usefull too.
|
||||
It is developed for the windows platform but should be easy to port to
|
||||
other platforms.
|
||||
|
||||
|
||||
****************
|
||||
*** FEATURES ***
|
||||
****************
|
||||
|
||||
Features of the HP48 that are implemented in this version:
|
||||
|
||||
* Saturn CPU (most instructions)
|
||||
* Daisy-chain
|
||||
* ROM
|
||||
* RAM
|
||||
* Card ports 1 & 2 (untested)
|
||||
* Bank-switcher (untested)
|
||||
* Hardware registers (some of them)
|
||||
* Hardware CRC
|
||||
* Timer1 (not complete)
|
||||
* Timer2 (not complete)
|
||||
* Interrup system (not complete)
|
||||
* LCD (grayscale)
|
||||
* Keyboard (not complete)
|
||||
|
||||
Unimplemented features:
|
||||
|
||||
* Indicators above LCD
|
||||
* UART
|
||||
* IR
|
||||
* Speaker
|
||||
* Things marked "not complete"
|
||||
|
||||
********************
|
||||
*** INSTALLATION ***
|
||||
********************
|
||||
|
||||
If you have the Windows binary distribution (hpemu-X.Y.Z-win32.zip):
|
||||
|
||||
1. Unzip the file in a new directory. You should get these files:
|
||||
|
||||
bin\hpemu.exe - The program itself
|
||||
bin\allegNN.dll - Allegro DLL needed to run hpemu
|
||||
README.txt - This file
|
||||
COPYING.txt - The GNU General Public License
|
||||
|
||||
2. Get a dump of the calculator's ROM and save it as hpemu.rom in the
|
||||
same directory as phemu.exe. (ROM revision R is known to work)
|
||||
|
||||
3. Execute hpemu.exe
|
||||
|
||||
|
||||
If you have the source distribution (hpemu-X.Y.Z-src.zip):
|
||||
|
||||
1. Unzip the file in a new directory.
|
||||
You should get a bunch of .c and .h files in the src directory
|
||||
and some other files.
|
||||
|
||||
2. Make sure you have the Allegro library and headers properly
|
||||
installed (http://alleg.sourceforge.net/)
|
||||
|
||||
3a. A makefile for MinGW is included so if that is your compiler just
|
||||
execute make to build the program.
|
||||
|
||||
3b. If you use another compiler or platform you will need to get all
|
||||
files compiled and linked against the Allegro library. If you get
|
||||
hpemu to work on another platform please contact me and tell me if
|
||||
you had any problems.
|
||||
|
||||
4. Get a dump of the calculators ROM and save it as hpemu.rom in the
|
||||
same directory as the executable. (ROM revision R is known to work)
|
||||
|
||||
5. Execute the program.
|
||||
|
||||
|
||||
****************************
|
||||
*** COMMAND LINE OPTIONS ***
|
||||
****************************
|
||||
|
||||
The command line options are:
|
||||
|
||||
-f Run program i fullscreen
|
||||
-w Run program i a window
|
||||
|
||||
|
||||
********************
|
||||
*** CONTACT INFO ***
|
||||
********************
|
||||
|
||||
Latest version of hpemu can allways be found on the hpemu homepage:
|
||||
sourceforge.net/projects/hpemu
|
||||
|
||||
Contact the author:
|
||||
Daniel Nilsson <dannil@users.sourceforge.net>
|
2
bin/CVS/Entries
Normal file
2
bin/CVS/Entries
Normal file
|
@ -0,0 +1,2 @@
|
|||
/tmp.txt/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
D
|
1
bin/CVS/Repository
Normal file
1
bin/CVS/Repository
Normal file
|
@ -0,0 +1 @@
|
|||
hpemu/bin
|
1
bin/CVS/Root
Normal file
1
bin/CVS/Root
Normal file
|
@ -0,0 +1 @@
|
|||
:pserver:anonymous@a.cvs.sourceforge.net:/cvsroot/hpemu
|
1
bin/tmp.txt
Normal file
1
bin/tmp.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Needed to keep empty directory.
|
2
obj/CVS/Entries
Normal file
2
obj/CVS/Entries
Normal file
|
@ -0,0 +1,2 @@
|
|||
/tmp.txt/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
D
|
1
obj/CVS/Repository
Normal file
1
obj/CVS/Repository
Normal file
|
@ -0,0 +1 @@
|
|||
hpemu/obj
|
1
obj/CVS/Root
Normal file
1
obj/CVS/Root
Normal file
|
@ -0,0 +1 @@
|
|||
:pserver:anonymous@a.cvs.sourceforge.net:/cvsroot/hpemu
|
1
obj/tmp.txt
Normal file
1
obj/tmp.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Needed to keep empty directory.
|
44
src/CVS/Entries
Normal file
44
src/CVS/Entries
Normal file
|
@ -0,0 +1,44 @@
|
|||
/bus.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/bus.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/color.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/color.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/cpu.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/cpu.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/disasm.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/disasm.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/display.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/display.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/emulator.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/emulator.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/gui.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/gui.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/hdw.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/hdw.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/keyboard.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/keyboard.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/main.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/opcodes.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/opcodes.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/opinline.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pabout.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pabout.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pcalc.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pcalc.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pdebug.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pdebug.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pfiles.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pfiles.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pmenu.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/pmenu.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/ports.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/ports.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/ram.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/ram.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/rom.c/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/rom.h/1.1.1.1/Mon Oct 28 14:59:01 2002//
|
||||
/rpl.c/1.1.1.1/Mon Oct 28 14:59:02 2002//
|
||||
/rpl.h/1.1.1.1/Mon Oct 28 14:59:02 2002//
|
||||
/timers.c/1.1.1.1/Mon Oct 28 14:59:02 2002//
|
||||
/timers.h/1.1.1.1/Mon Oct 28 14:59:02 2002//
|
||||
/types.h/1.1.1.1/Mon Oct 28 14:59:02 2002//
|
||||
D
|
1
src/CVS/Repository
Normal file
1
src/CVS/Repository
Normal file
|
@ -0,0 +1 @@
|
|||
hpemu/src
|
1
src/CVS/Root
Normal file
1
src/CVS/Root
Normal file
|
@ -0,0 +1 @@
|
|||
:pserver:anonymous@a.cvs.sourceforge.net:/cvsroot/hpemu
|
449
src/bus.c
Normal file
449
src/bus.c
Normal file
|
@ -0,0 +1,449 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "rom.h"
|
||||
#include "ram.h"
|
||||
#include "ports.h"
|
||||
#include "hdw.h"
|
||||
#include "bus.h"
|
||||
|
||||
BusInfo bus_info = {
|
||||
// hdw ram sz ram ce1 sz ce1 ce2 sz ce2 nce3 sz nce3
|
||||
0x00000,0x00000,0x00000,0x00000,0x00000,0x00000,0x00000,0x00000,0x00000, // base or size
|
||||
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, // configured
|
||||
FALSE, FALSE, FALSE, // read only
|
||||
// ce1_bs da19 ben
|
||||
FALSE, FALSE, FALSE,
|
||||
// rom ram ce1 ce2 nce3
|
||||
NULL, NULL, NULL, NULL, NULL, // data
|
||||
0x00000,0x00000,0x00000,0x00000,0x00000 // mask
|
||||
};
|
||||
|
||||
static byte *read_map[256];
|
||||
static byte *write_map[256];
|
||||
static address hdw_seg;
|
||||
|
||||
#define SEG_OF(adr) ((adr)>>12)
|
||||
#define OFFSET_OF(adr) ((adr)&0xFFF)
|
||||
#define CAN_READ(adr) (read_map[SEG_OF(adr)] != NULL)
|
||||
#define CAN_WRITE(adr) (write_map[SEG_OF(adr)] != NULL)
|
||||
#define MAP_READ(adr) (read_map[SEG_OF(adr)]+OFFSET_OF(adr))
|
||||
#define MAP_WRITE(adr) (write_map[SEG_OF(adr)]+OFFSET_OF(adr))
|
||||
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
word crc;
|
||||
|
||||
void bus_init(void)
|
||||
{
|
||||
rom_init();
|
||||
hdw_init();
|
||||
ram_init();
|
||||
ports_init();
|
||||
bus_reset();
|
||||
}
|
||||
|
||||
void bus_exit(void)
|
||||
{
|
||||
rom_exit();
|
||||
hdw_exit();
|
||||
ram_exit();
|
||||
ports_exit();
|
||||
}
|
||||
|
||||
static __inline void update_crc(byte nibble)
|
||||
{
|
||||
crc = (crc >> 4) ^ (((crc ^ nibble) & 0xF) * 0x1081);
|
||||
}
|
||||
|
||||
void bus_read(byte *buf, address adr, address len)
|
||||
{
|
||||
int n, i;
|
||||
|
||||
while (TRUE) {
|
||||
if (hdw_seg == SEG_OF(adr) && ((bus_info.hdw_base ^ adr) & 0xFFFC0) == 0) {
|
||||
n = MIN(len, 0x40 - (adr & 0x3F));
|
||||
for (i = 0; i < n; i++) {
|
||||
buf[i] = hdw_read_nibble((adr & 0x3F) + i);
|
||||
}
|
||||
if (((adr & 0x3F) + n) == 0x40) {
|
||||
update_crc(buf[n-1]);
|
||||
}
|
||||
} else {
|
||||
if (hdw_seg == SEG_OF(adr) && (bus_info.hdw_base & 0xFFFC0) - adr > 0) {
|
||||
n = MIN(len, (bus_info.hdw_base & 0xFFFC0) - adr);
|
||||
} else {
|
||||
n = MIN(len, 0x1000 - OFFSET_OF (adr));
|
||||
}
|
||||
if (CAN_READ(adr)) {
|
||||
memcpy(buf, MAP_READ(adr), n);
|
||||
} else {
|
||||
for (i = 0; i < n; i++) {
|
||||
buf[i] = ((i+adr)&1) ? 0xE : 0xD;
|
||||
}
|
||||
if (bus_info.ce1_bs && bus_info.ce1_cfg &&
|
||||
((bus_info.ce1_base ^ adr) & bus_info.ce1_size)) {
|
||||
ports_switch_bank(OFFSET_OF(adr+n));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
update_crc(buf[i]);
|
||||
}
|
||||
}
|
||||
len -= n;
|
||||
if (!len) {
|
||||
break;
|
||||
}
|
||||
buf += n;
|
||||
adr += n;
|
||||
adr &= 0xFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
void bus_write(byte *buf, address adr, address len)
|
||||
{
|
||||
int n, i;
|
||||
|
||||
while (TRUE) {
|
||||
if (hdw_seg == SEG_OF(adr) && ((bus_info.hdw_base ^ adr) & 0xFFFC0) == 0) {
|
||||
n = MIN(len, 0x40 - (adr & 0x3F));
|
||||
for (i = 0; i < n; i++) {
|
||||
hdw_write_nibble(buf[i], (adr & 0x3F) + i);
|
||||
}
|
||||
} else {
|
||||
if (hdw_seg == SEG_OF(adr) && (bus_info.hdw_base & 0xFFFC0) - adr > 0) {
|
||||
n = MIN(len, (bus_info.hdw_base & 0xFFFC0) - adr);
|
||||
} else {
|
||||
n = MIN(len, 0x1000 - OFFSET_OF (adr));
|
||||
}
|
||||
if (CAN_WRITE(adr)) {
|
||||
memcpy (MAP_WRITE(adr), buf, n);
|
||||
} else if (bus_info.ce1_bs) {
|
||||
if (bus_info.ce1_cfg && ((bus_info.ce1_base ^ adr) & bus_info.ce1_size)) {
|
||||
if (!bus_info.nce3_r_o) {
|
||||
ports_switch_bank(OFFSET_OF(adr+n-1));
|
||||
} else if ((adr+n) & 1) {
|
||||
ports_switch_bank(OFFSET_OF(adr+n-1));
|
||||
} else if (adr & 0x1) {
|
||||
ports_switch_bank(OFFSET_OF(adr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
len -= n;
|
||||
if (!len) {
|
||||
break;
|
||||
}
|
||||
buf += n;
|
||||
adr += n;
|
||||
adr &= 0xFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
static void bus_peek(byte *buf, address adr, address len)
|
||||
{
|
||||
int n, i;
|
||||
|
||||
while (TRUE) {
|
||||
if (hdw_seg == SEG_OF(adr) && ((bus_info.hdw_base ^ adr) & 0xFFFC0) == 0) {
|
||||
n = MIN(len, 0x40 - (adr & 0x3F));
|
||||
for (i = 0; i < n; i++) {
|
||||
buf[i] = hdw_read_nibble((adr & 0x3F) + i);
|
||||
}
|
||||
} else {
|
||||
if (hdw_seg == SEG_OF(adr) && (bus_info.hdw_base & 0xFFFC0) - adr > 0) {
|
||||
n = MIN(len, (bus_info.hdw_base & 0xFFFC0) - adr);
|
||||
} else {
|
||||
n = MIN(len, 0x1000 - OFFSET_OF (adr));
|
||||
}
|
||||
if (CAN_READ(adr)) {
|
||||
memcpy(buf, MAP_READ(adr), n);
|
||||
} else {
|
||||
for (i = 0; i < n; i++) {
|
||||
buf[i] = ((i+adr)&1) ? 0xE : 0xD;
|
||||
}
|
||||
}
|
||||
}
|
||||
len -= n;
|
||||
if (!len) {
|
||||
break;
|
||||
}
|
||||
buf += n;
|
||||
adr += n;
|
||||
adr &= 0xFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call only when you know that hdw is not in the range of nibbles read */
|
||||
static void bus_peek_no_hdw(byte *buf, address adr, address len)
|
||||
{
|
||||
int n, i;
|
||||
|
||||
while (TRUE) {
|
||||
n = MIN(len, 0x1000 - OFFSET_OF(adr));
|
||||
if (CAN_READ(adr)) {
|
||||
memcpy(buf, MAP_READ(adr), n);
|
||||
} else {
|
||||
for (i = 0; i < n; i++) {
|
||||
buf[i] = ((i+adr)&1) ? 0xE : 0xD;
|
||||
}
|
||||
}
|
||||
len -= n;
|
||||
if (!len) {
|
||||
break;
|
||||
}
|
||||
buf += n;
|
||||
adr += n;
|
||||
adr &= 0xFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns a pointer for fast read access to memory (don't write).
|
||||
* If a direct pointer can't be returnd it will use the caller supplied buffer instead.
|
||||
* If the buffer is not used the pointer returned is valid as long as bus_info.map_cnt
|
||||
* has the same value (until a call to bus_remap).
|
||||
* If the buffer is used the pointer returned (== buf) is valid only until the memory
|
||||
* is written to.
|
||||
* Set len to the number of nibbles you want to access. It is changed to the actual number of
|
||||
* nibbles that can safetly be read through the pointer (can be more or less then the original).
|
||||
*/
|
||||
byte *bus_fast_peek(byte *buf, address adr, int *len)
|
||||
{
|
||||
static byte tmp_buf[FAST_PEEK_MAX];
|
||||
static int tmp_len;
|
||||
address adr2;
|
||||
|
||||
if (!buf) {
|
||||
buf = tmp_buf;
|
||||
}
|
||||
if (!len) {
|
||||
tmp_len = FAST_PEEK_MAX;
|
||||
len = &tmp_len;
|
||||
}
|
||||
if (*len > FAST_PEEK_MAX) {
|
||||
*len = FAST_PEEK_MAX;
|
||||
}
|
||||
|
||||
adr2 = adr + *len - 1;
|
||||
|
||||
if ((SEG_OF(adr) == hdw_seg || SEG_OF(adr2) == hdw_seg) &&
|
||||
(((bus_info.hdw_base ^ adr) & 0xFFFC0) == 0 ||
|
||||
((bus_info.hdw_base ^ adr2) & 0xFFFC0) == 0)) {
|
||||
bus_peek(buf, adr, *len);
|
||||
return buf;
|
||||
} else if (!CAN_READ(adr)) {
|
||||
bus_peek_no_hdw(buf, adr, *len);
|
||||
return buf;
|
||||
} else if (SEG_OF(adr) == SEG_OF(adr2)) {
|
||||
if (hdw_seg == SEG_OF(adr) && (bus_info.hdw_base & 0xFFFC0) - adr > 0) {
|
||||
*len = (bus_info.hdw_base & 0xFFFC0) - adr;
|
||||
} else {
|
||||
*len = 0x1000 - OFFSET_OF (adr);
|
||||
}
|
||||
return MAP_READ(adr);
|
||||
} else if (CAN_READ(adr2) && MAP_READ(adr) + *len-1 == MAP_READ(adr2)) {
|
||||
if (hdw_seg == SEG_OF(adr2)) {
|
||||
*len = (bus_info.hdw_base & 0xFFFC0) - adr;
|
||||
} else {
|
||||
*len = 0x2000 - OFFSET_OF(adr);
|
||||
}
|
||||
return MAP_READ(adr);
|
||||
} else {
|
||||
bus_peek_no_hdw(buf, adr, *len);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
void bus_remap(void)
|
||||
{
|
||||
int adr;
|
||||
|
||||
for (adr = 0; adr < 0x100000; adr += 0x01000) {
|
||||
if (bus_info.ram_cfg && ((bus_info.ram_base ^ adr) & bus_info.ram_size) == 0) {
|
||||
read_map[SEG_OF(adr)] = bus_info.ram_data + (adr & bus_info.ram_mask);
|
||||
write_map[SEG_OF(adr)] = bus_info.ram_data + (adr & bus_info.ram_mask);
|
||||
} else if (bus_info.ce2_cfg && ((bus_info.ce2_base ^ adr) & bus_info.ce2_size) == 0) {
|
||||
if (bus_info.ce2_data) {
|
||||
read_map[SEG_OF(adr)] = bus_info.ce2_data + (adr & bus_info.ce2_mask);
|
||||
if (!bus_info.ce2_r_o) {
|
||||
write_map[SEG_OF(adr)] = bus_info.ce2_data + (adr & bus_info.ce2_mask);
|
||||
} else {
|
||||
write_map[SEG_OF(adr)] = NULL;
|
||||
}
|
||||
} else {
|
||||
read_map[SEG_OF(adr)] = NULL;
|
||||
write_map[SEG_OF(adr)] = NULL;
|
||||
}
|
||||
} else if (bus_info.ce1_cfg && ((bus_info.ce1_base ^ adr) & bus_info.ce1_size) == 0) {
|
||||
if (bus_info.ce1_data) {
|
||||
read_map[SEG_OF(adr)] = bus_info.ce1_data + (adr & bus_info.ce1_mask);
|
||||
if (!bus_info.ce1_r_o) {
|
||||
write_map[SEG_OF(adr)] = bus_info.ce1_data + (adr & bus_info.ce1_mask);
|
||||
} else {
|
||||
write_map[SEG_OF(adr)] = NULL;
|
||||
}
|
||||
} else {
|
||||
read_map[SEG_OF(adr)] = NULL;
|
||||
write_map[SEG_OF(adr)] = NULL;
|
||||
}
|
||||
} else if (bus_info.nce3_cfg && ((bus_info.nce3_base ^ adr) & bus_info.nce3_size) == 0) {
|
||||
if (bus_info.nce3_data && bus_info.ben && !bus_info.da19) {
|
||||
read_map[SEG_OF(adr)] = bus_info.nce3_data + (adr & bus_info.nce3_mask);
|
||||
if (!bus_info.nce3_r_o) {
|
||||
write_map[SEG_OF(adr)] = bus_info.nce3_data + (adr & bus_info.nce3_mask);
|
||||
} else {
|
||||
write_map[SEG_OF(adr)] = NULL;
|
||||
}
|
||||
} else {
|
||||
read_map[SEG_OF(adr)] = NULL;
|
||||
write_map[SEG_OF(adr)] = NULL;
|
||||
}
|
||||
} else {
|
||||
read_map[SEG_OF(adr)] = bus_info.rom_data + (adr & bus_info.rom_mask & (bus_info.da19 ? 0xFFFFF : 0x7FFFF));
|
||||
write_map[SEG_OF(adr)] = NULL;
|
||||
}
|
||||
}
|
||||
bus_info.map_cnt++; // Flag that pointers returned by bus_fast_peek may be invalid
|
||||
}
|
||||
|
||||
void bus_configure(address adr)
|
||||
{
|
||||
if (!bus_info.hdw_cfg) {
|
||||
bus_info.hdw_base = adr & 0xFFFC0;
|
||||
bus_info.hdw_cfg = TRUE;
|
||||
hdw_seg = SEG_OF (adr);
|
||||
} else if (!bus_info.ram_sz_cfg) {
|
||||
bus_info.ram_size = adr & 0xFF000;
|
||||
bus_info.ram_sz_cfg = TRUE;
|
||||
} else if (!bus_info.ram_cfg) {
|
||||
bus_info.ram_base = adr & 0xFF000;
|
||||
bus_info.ram_cfg = TRUE;
|
||||
bus_remap();
|
||||
} else if (!bus_info.ce1_sz_cfg) {
|
||||
bus_info.ce1_size = adr & 0xFF000;
|
||||
bus_info.ce1_sz_cfg = TRUE;
|
||||
} else if (!bus_info.ce1_cfg) {
|
||||
bus_info.ce1_base = adr & 0xFF000;
|
||||
bus_info.ce1_cfg = TRUE;
|
||||
bus_remap();
|
||||
} else if (!bus_info.ce2_sz_cfg) {
|
||||
bus_info.ce2_size = adr & 0xFF000;
|
||||
bus_info.ce2_sz_cfg = TRUE;
|
||||
} else if (!bus_info.ce2_cfg) {
|
||||
bus_info.ce2_base = adr & 0xFF000;
|
||||
bus_info.ce2_cfg = TRUE;
|
||||
bus_remap();
|
||||
} else if (!bus_info.nce3_sz_cfg) {
|
||||
bus_info.nce3_size = adr & 0xFF000;
|
||||
bus_info.nce3_sz_cfg = TRUE;
|
||||
} else if (!bus_info.nce3_cfg) {
|
||||
bus_info.nce3_base = adr & 0xFF000;
|
||||
bus_info.nce3_cfg = TRUE;
|
||||
bus_remap();
|
||||
}
|
||||
}
|
||||
|
||||
void bus_unconfigure(address adr)
|
||||
{
|
||||
if (bus_info.hdw_cfg && ((adr ^ bus_info.hdw_base) & 0xFFFC0) == 0) {
|
||||
bus_info.hdw_cfg = FALSE;
|
||||
hdw_seg = -1;
|
||||
} else if (bus_info.ram_cfg && ((adr ^ bus_info.ram_base) & bus_info.ram_size) == 0) {
|
||||
bus_info.ram_cfg = FALSE;
|
||||
bus_info.ram_sz_cfg = FALSE;
|
||||
bus_remap();
|
||||
} else if (bus_info.ce2_cfg && ((adr ^ bus_info.ce2_base) & bus_info.ce2_size) == 0) {
|
||||
bus_info.ce2_cfg = FALSE;
|
||||
bus_info.ce2_sz_cfg = FALSE;
|
||||
bus_remap();
|
||||
} else if (bus_info.ce1_cfg && ((adr ^ bus_info.ce1_base) & bus_info.ce1_size) == 0) {
|
||||
bus_info.ce1_cfg = FALSE;
|
||||
bus_info.ce1_sz_cfg = FALSE;
|
||||
bus_remap();
|
||||
} else if (bus_info.nce3_cfg && ((adr ^ bus_info.nce3_base) & bus_info.nce3_size) == 0) {
|
||||
bus_info.nce3_cfg = FALSE;
|
||||
bus_info.nce3_sz_cfg = FALSE;
|
||||
bus_remap();
|
||||
}
|
||||
}
|
||||
|
||||
void bus_reset(void)
|
||||
{
|
||||
bus_info.hdw_base = 0x00000;
|
||||
bus_info.hdw_cfg = FALSE;
|
||||
|
||||
bus_info.ram_base = 0x00000;
|
||||
bus_info.ram_size = 0x00000;
|
||||
bus_info.ram_cfg = FALSE;
|
||||
bus_info.ram_sz_cfg = FALSE;
|
||||
|
||||
bus_info.ce1_base = 0x00000;
|
||||
bus_info.ce1_size = 0x00000;
|
||||
bus_info.ce1_cfg = FALSE;
|
||||
bus_info.ce1_sz_cfg = FALSE;
|
||||
|
||||
bus_info.ce2_base = 0x00000;
|
||||
bus_info.ce2_size = 0x00000;
|
||||
bus_info.ce2_cfg = FALSE;
|
||||
bus_info.ce2_sz_cfg = FALSE;
|
||||
|
||||
bus_info.nce3_base = 0x00000;
|
||||
bus_info.nce3_size = 0x00000;
|
||||
bus_info.nce3_cfg = FALSE;
|
||||
bus_info.nce3_sz_cfg = FALSE;
|
||||
|
||||
hdw_seg = -1;
|
||||
bus_remap();
|
||||
}
|
||||
|
||||
address bus_get_id(void)
|
||||
{
|
||||
if (!bus_info.hdw_cfg) {
|
||||
return bus_info.hdw_base | 0x00019;
|
||||
} else if (!bus_info.ram_sz_cfg) {
|
||||
return bus_info.ram_size | 0x00003;
|
||||
} else if (!bus_info.ram_cfg) {
|
||||
return bus_info.ram_base | 0x000F4;
|
||||
} else if (!bus_info.ce1_sz_cfg) {
|
||||
return bus_info.ce1_size | 0x00005;
|
||||
} else if (!bus_info.ce1_cfg) {
|
||||
return bus_info.ce1_base | 0x000F6;
|
||||
} else if (!bus_info.ce2_sz_cfg) {
|
||||
return bus_info.ce2_size | 0x00007;
|
||||
} else if (!bus_info.ce2_cfg) {
|
||||
return bus_info.ce2_base | 0x000F8;
|
||||
} else if (!bus_info.nce3_sz_cfg) {
|
||||
return bus_info.nce3_size | 0x00001;
|
||||
} else if (!bus_info.nce3_cfg) {
|
||||
return bus_info.nce3_base | 0x000F2;
|
||||
} else {
|
||||
return 0x00000;
|
||||
}
|
||||
}
|
91
src/bus.h
Normal file
91
src/bus.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __BUS_H
|
||||
#define __BUS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct {
|
||||
address hdw_base;
|
||||
address ram_size;
|
||||
address ram_base;
|
||||
address ce1_size;
|
||||
address ce1_base;
|
||||
address ce2_size;
|
||||
address ce2_base;
|
||||
address nce3_size;
|
||||
address nce3_base;
|
||||
boolean hdw_cfg :1;
|
||||
boolean ram_sz_cfg :1;
|
||||
boolean ram_cfg :1;
|
||||
boolean ce1_sz_cfg :1;
|
||||
boolean ce1_cfg :1;
|
||||
boolean ce2_sz_cfg :1;
|
||||
boolean ce2_cfg :1;
|
||||
boolean nce3_sz_cfg :1;
|
||||
boolean nce3_cfg :1;
|
||||
boolean ce1_r_o :1;
|
||||
boolean ce2_r_o :1;
|
||||
boolean nce3_r_o :1;
|
||||
boolean ce1_bs :1;
|
||||
boolean da19 :1;
|
||||
boolean ben :1;
|
||||
byte *rom_data;
|
||||
byte *ram_data;
|
||||
byte *ce1_data;
|
||||
byte *ce2_data;
|
||||
byte *nce3_data;
|
||||
address rom_mask;
|
||||
address ram_mask;
|
||||
address ce1_mask;
|
||||
address ce2_mask;
|
||||
address nce3_mask;
|
||||
dword map_cnt;
|
||||
} BusInfo;
|
||||
|
||||
extern BusInfo bus_info;
|
||||
|
||||
extern word crc;
|
||||
|
||||
// FAST_PEEK_MAX must not be greater than the size of the hdw registers (64)
|
||||
#define FAST_PEEK_MAX 64
|
||||
|
||||
void bus_init(void);
|
||||
void bus_exit(void);
|
||||
|
||||
void bus_read(byte *buf, address adr, address len);
|
||||
void bus_write(byte *buf, address adr, address len);
|
||||
byte *bus_fast_peek(byte *buf, address adr, address *len);
|
||||
|
||||
void bus_remap(void);
|
||||
void bus_configure(address adr);
|
||||
void bus_unconfigure(address adr);
|
||||
void bus_reset(void);
|
||||
address bus_get_id();
|
||||
|
||||
#endif
|
155
src/color.c
Normal file
155
src/color.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "color.h"
|
||||
|
||||
#define RESERVED_LCD 128
|
||||
|
||||
int color[C_COUNT];
|
||||
|
||||
static PALETTE palette;
|
||||
|
||||
static int lcd_0_r, lcd_0_g, lcd_0_b;
|
||||
static int lcd_1_r, lcd_1_g, lcd_1_b;
|
||||
static int lcd_mode;
|
||||
|
||||
static void set_lcd_color(int i, int v)
|
||||
{
|
||||
palette[i].r = (lcd_0_r * (255 - v) + lcd_1_r * v) / 255;
|
||||
palette[i].g = (lcd_0_g * (255 - v) + lcd_1_g * v) / 255;
|
||||
palette[i].b = (lcd_0_b * (255 - v) + lcd_1_b * v) / 255;
|
||||
}
|
||||
|
||||
static int bit_count(unsigned int i)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
while (i) {
|
||||
n += i & 1;
|
||||
i >>= 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int simple_color(int i)
|
||||
{
|
||||
return (i & 0x40) ? 255 : 0;
|
||||
}
|
||||
|
||||
static int gray4_color(int i)
|
||||
{
|
||||
return bit_count(i & 0x70) * 85;
|
||||
}
|
||||
|
||||
static int gray8_color(int i)
|
||||
{
|
||||
return bit_count(i) * 255 / 7;
|
||||
}
|
||||
|
||||
static int exp_color(int i)
|
||||
{
|
||||
return i * 255 / 127;
|
||||
}
|
||||
|
||||
typedef int (*lcd_color_func)(int i);
|
||||
|
||||
lcd_color_func lcd_color_functions[] = {
|
||||
simple_color,
|
||||
gray4_color,
|
||||
gray8_color,
|
||||
exp_color
|
||||
};
|
||||
|
||||
static void build_lcd_palette(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RESERVED_LCD; i++) {
|
||||
set_lcd_color(i, lcd_color_functions[lcd_mode](i));
|
||||
}
|
||||
|
||||
set_palette_range(palette, 0, RESERVED_LCD-1, FALSE);
|
||||
}
|
||||
|
||||
void color_lcd(int r0, int g0, int b0, int r1, int g1, int b1)
|
||||
{
|
||||
lcd_0_r = r0 >> 2;
|
||||
lcd_0_g = g0 >> 2;
|
||||
lcd_0_b = b0 >> 2;
|
||||
lcd_1_r = r1 >> 2;
|
||||
lcd_1_g = g1 >> 2;
|
||||
lcd_1_b = b1 >> 2;
|
||||
build_lcd_palette();
|
||||
}
|
||||
|
||||
void color_lcd_mode(int mode)
|
||||
{
|
||||
lcd_mode = mode;
|
||||
build_lcd_palette();
|
||||
}
|
||||
|
||||
void color_set(int i, int r, int g, int b)
|
||||
{
|
||||
if (bitmap_color_depth(screen) == 8) {
|
||||
palette[color[i]].r = r >> 2;
|
||||
palette[color[i]].g = g >> 2;
|
||||
palette[color[i]].b = b >> 2;
|
||||
set_color(color[i], palette + color[i]);
|
||||
} else {
|
||||
color[i] = makecol(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
void color_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (bitmap_color_depth(screen) == 8) {
|
||||
for (i = 0; i < C_COUNT; i++) {
|
||||
color[i] = RESERVED_LCD + i;
|
||||
}
|
||||
}
|
||||
color_set(C_BACKGROUND, 0, 0, 0);
|
||||
color_set(C_PANEL_BACK, 64, 64, 64);
|
||||
color_set(C_PANEL_BORDER, 128, 128, 128);
|
||||
color_set(C_PANEL_TEXT, 255, 255, 255);
|
||||
color_set(C_PANEL_DISABLED, 128, 128, 128);
|
||||
color_set(C_BUTTON_BACK, 64, 64, 64);
|
||||
color_set(C_BUTTON_BORDER, 128, 128, 128);
|
||||
color_set(C_BUTTON_PUSHED, 128, 128, 128);
|
||||
color_set(C_BUTTON_TEXT, 255, 255, 255);
|
||||
color_set(C_BUTTON_DISABLED,128, 128, 128);
|
||||
|
||||
color_lcd(128, 192, 128, 0, 0, 64);
|
||||
color_lcd_mode(LCD_MODE_GRAY4);
|
||||
set_palette(palette);
|
||||
set_mouse_sprite(NULL);
|
||||
gui_bg_color = color[C_PANEL_BACK];
|
||||
gui_mg_color = color[C_PANEL_DISABLED];
|
||||
gui_fg_color = color[C_PANEL_TEXT];
|
||||
}
|
59
src/color.h
Normal file
59
src/color.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __COLOR_H
|
||||
#define __COLOR_H
|
||||
|
||||
enum LCD_Modes {
|
||||
LCD_MODE_SIMPLE,
|
||||
LCD_MODE_GRAY4,
|
||||
LCD_MODE_GRAY8,
|
||||
LCD_MODE_EXP
|
||||
};
|
||||
|
||||
enum Colors {
|
||||
C_BACKGROUND,
|
||||
C_PANEL_BACK,
|
||||
C_PANEL_BORDER,
|
||||
C_PANEL_TEXT,
|
||||
C_PANEL_DISABLED,
|
||||
C_BUTTON_BACK,
|
||||
C_BUTTON_BORDER,
|
||||
C_BUTTON_PUSHED,
|
||||
C_BUTTON_TEXT,
|
||||
C_BUTTON_DISABLED,
|
||||
C_COUNT
|
||||
};
|
||||
|
||||
extern int color[C_COUNT];
|
||||
|
||||
void color_lcd(int r0, int g0, int b0, int r1, int g1, int b1);
|
||||
void color_lcd_mode(int mode);
|
||||
void color_set(int i, int r, int g, int b);
|
||||
void color_init(void);
|
||||
|
||||
#endif
|
84
src/cpu.c
Normal file
84
src/cpu.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "emulator.h"
|
||||
#include "bus.h"
|
||||
#include "opcodes.h"
|
||||
#include "cpu.h"
|
||||
|
||||
Cpu cpu;
|
||||
|
||||
#define MAX_OPC_LEN 21
|
||||
|
||||
void cpu_interrupt(void)
|
||||
{
|
||||
if (cpu.inte) {
|
||||
cpu.inte = FALSE;
|
||||
cpu.rstk_ptr = (cpu.rstk_ptr - 1) & 7;
|
||||
cpu.rstk[cpu.rstk_ptr] = cpu.pc;
|
||||
cpu.pc = 0x0000F;
|
||||
}
|
||||
}
|
||||
|
||||
static void decode(byte *ptr)
|
||||
{
|
||||
Opcode *op = opcodes;
|
||||
int i = 0;
|
||||
|
||||
while (op[ptr[i]].next) {
|
||||
op = op[ptr[i]].next;
|
||||
i++;
|
||||
}
|
||||
if (op[ptr[i]].exec) {
|
||||
op[ptr[i]].exec(ptr);
|
||||
cpu.pc &= 0xFFFFF;
|
||||
cpu.inst_cnt++;
|
||||
} else {
|
||||
emulator_set_state(EMULATOR_STOP);
|
||||
}
|
||||
}
|
||||
|
||||
void execute_instruction(void)
|
||||
{
|
||||
static byte buffer[FAST_PEEK_MAX];
|
||||
static byte *ptr;
|
||||
static dword old_map_cnt;
|
||||
static address len;
|
||||
static address adr;
|
||||
|
||||
if (cpu.pc < adr || adr + len < cpu.pc + MAX_OPC_LEN || bus_info.map_cnt != old_map_cnt || !ptr) {
|
||||
len = MAX_OPC_LEN;
|
||||
adr = cpu.pc;
|
||||
ptr = bus_fast_peek(buffer, adr, &len);
|
||||
old_map_cnt = bus_info.map_cnt;
|
||||
if (ptr == buffer) { // Not direct memory access
|
||||
old_map_cnt--; // Force new peek next time
|
||||
}
|
||||
}
|
||||
decode(ptr + cpu.pc - adr);
|
||||
}
|
67
src/cpu.h
Normal file
67
src/cpu.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __CPU_H
|
||||
#define __CPU_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct {
|
||||
byte reg[4][16];
|
||||
byte reg_r[5][16];
|
||||
byte st[4];
|
||||
byte in[4];
|
||||
byte out[3];
|
||||
byte hst;
|
||||
byte p;
|
||||
address d[2];
|
||||
address pc;
|
||||
address rstk[8];
|
||||
int rstk_ptr;
|
||||
boolean carry :1;
|
||||
boolean dec :1;
|
||||
boolean shutdown :1;
|
||||
boolean inte :1;
|
||||
boolean keyscan :1;
|
||||
boolean keyintp :1;
|
||||
dword cycles;
|
||||
dword inst_cnt;
|
||||
} Cpu;
|
||||
|
||||
#define HST_XM 1
|
||||
#define HST_SB 2
|
||||
#define HST_SR 4
|
||||
#define HST_MP 8
|
||||
|
||||
enum RegisterNames { A, B, C, D };
|
||||
|
||||
extern Cpu cpu;
|
||||
|
||||
void cpu_interrupt(void);
|
||||
void execute_instruction(void);
|
||||
|
||||
#endif
|
319
src/disasm.c
Normal file
319
src/disasm.c
Normal file
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "types.h"
|
||||
#include "opcodes.h"
|
||||
#include "disasm.h"
|
||||
|
||||
static const char hex_tab[16] = "0123456789ABCDEF";
|
||||
|
||||
static const char r_tab[11][16] = {
|
||||
"ABCDABCDBCACBCAC", // p
|
||||
"BCAC1111ABCDABCD", // q
|
||||
"ABCDBCACABCDBCAC", // r
|
||||
"BCACABCDBCACABCD", // s
|
||||
"ABCDABCDBCACABCD", // t
|
||||
"ABCDABCDABCDABCD", // u (different than in opcodes.c)
|
||||
"BCACBCACBCACBCAC", // v (different than in opcodes.c)
|
||||
"BCACABCDABCD1111", // w
|
||||
"ABCDABCDBCACABAC", // x
|
||||
"0000BCACABCDBCCD", // y
|
||||
"BCACBCAC00000000", // z
|
||||
};
|
||||
|
||||
static const char *f_tab[8] = { "P", "WP", "XS", "X", "S", "M", "B", "W" };
|
||||
|
||||
#define HEX(x) (hex_tab[x])
|
||||
|
||||
#define ADD_OFFSET(x,s) do { if (*(s) == '+') { \
|
||||
(s)++; \
|
||||
(x) += *(s)++ - '0'; \
|
||||
} } while (0)
|
||||
|
||||
static __inline int nib_to_signed(byte *nib, int len)
|
||||
{
|
||||
int x;
|
||||
|
||||
len--;
|
||||
x = nib[len];
|
||||
if (x & 8) x -= 16;
|
||||
while (len--) {
|
||||
x <<= 4;
|
||||
x |= nib[len];
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static void expand(char *dest, char *src, byte *ptr)
|
||||
{
|
||||
int i, n;
|
||||
int x;
|
||||
|
||||
while (*src) {
|
||||
if (*src != '%') {
|
||||
*dest++ = *src++;
|
||||
} else {
|
||||
src++;
|
||||
switch (*src++) {
|
||||
|
||||
case 'I': // One digit integer
|
||||
i = *src++ - '0';
|
||||
x = ptr[i];
|
||||
ADD_OFFSET(x, src);
|
||||
if (x >= 10) {
|
||||
*dest++ = '0' + x / 10;
|
||||
*dest++ = '0' + x % 10;
|
||||
} else {
|
||||
*dest++ = '0' + x;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X': // Hexadecimal number
|
||||
i = *src++ - '0';
|
||||
n = *src++ - '0';
|
||||
while (n--) {
|
||||
*dest++ = HEX(ptr[i+n]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N': // Variable length hexadecimal number
|
||||
i = *src++ - '0';
|
||||
n = ptr[i] + 1;
|
||||
while (n) {
|
||||
*dest++ = HEX(ptr[i+n]);
|
||||
n--;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R': // Relative address
|
||||
i = *src++ - '0';
|
||||
n = *src++ - '0';
|
||||
x = nib_to_signed(ptr + i, n);
|
||||
ADD_OFFSET(x, src);
|
||||
if (x < 0) {
|
||||
*dest++ = '-';
|
||||
x = -x;
|
||||
} else {
|
||||
*dest++ = '+';
|
||||
}
|
||||
while (n--) {
|
||||
*dest++ = HEX((x >> (n*4)) & 0xF);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T': // Relative address for tests
|
||||
i = *src++ - '0';
|
||||
n = *src++ - '0';
|
||||
x = nib_to_signed(ptr + i, n);
|
||||
if (x == 0) {
|
||||
ADD_OFFSET (x, src); // skip over the optional "+i"
|
||||
break;
|
||||
}
|
||||
ADD_OFFSET (x, src);
|
||||
if (x < 0) {
|
||||
*dest++ = '-';
|
||||
x = -x;
|
||||
} else {
|
||||
*dest++ = '+';
|
||||
}
|
||||
while (n--) {
|
||||
*dest++ = HEX((x >> (n*4)) & 0xF);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G': // "GO" or "RTN" for tests
|
||||
i = *src++ - '0';
|
||||
n = *src++ - '0';
|
||||
x = nib_to_signed(ptr + i, n);
|
||||
if (x == 0) {
|
||||
*dest++ = 'R';
|
||||
*dest++ = 'T';
|
||||
*dest++ = 'N';
|
||||
} else {
|
||||
*dest++ = 'G';
|
||||
*dest++ = 'O';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'F': // Field name
|
||||
i = *src++ - '0';
|
||||
if (*src == 'A') {
|
||||
src++;
|
||||
if (ptr[i] == 0xF) {
|
||||
*dest++ = 'A';
|
||||
break;
|
||||
}
|
||||
}
|
||||
*dest++ = f_tab[ptr[i]&7][0];
|
||||
if (f_tab[ptr[i]&7][1])
|
||||
*dest++ = f_tab[ptr[i]&7][1];
|
||||
break;
|
||||
|
||||
case 'B': // Field A or B
|
||||
i = *src++ -'0';
|
||||
*dest++ = (ptr[i]&8) ? 'B' : 'A';
|
||||
break;
|
||||
|
||||
case 'p': // Subtraction source 1
|
||||
case 'q': // Subtraction source 2
|
||||
case 'r': // Logic destination & source 1
|
||||
case 's': // Logic source 2
|
||||
case 't': // Arithmethic destination & addition source 1
|
||||
case 'u': // Compare source 1
|
||||
case 'v': // Compare source 2 for <, >, <= and >=
|
||||
case 'w': // Addition source 2
|
||||
case 'x': // Assignment destination
|
||||
case 'y': // Assignment source
|
||||
case 'z': // Compare source 2 for = and #
|
||||
i = *src++ - '0';
|
||||
*dest++ = r_tab[src[-2]-'p'][ptr[i]];
|
||||
break;
|
||||
|
||||
case 'a': // "A" or "C"
|
||||
i = *src++ - '0';
|
||||
*dest++ = (ptr[i]&8) ? 'C' : 'A';
|
||||
break;
|
||||
|
||||
case 'i': // R-register number
|
||||
i = *src++ - '0';
|
||||
*dest++ = '0' + ((ptr[i]&7) > 4 ? ptr[i]&3 : ptr[i]&7);
|
||||
break;
|
||||
|
||||
case '#': // "#" or "=" for comparisons
|
||||
i = *src++ - '0';
|
||||
*dest++ = (ptr[i]&4) ? '#' : '=';
|
||||
break;
|
||||
|
||||
case '>': // ">", "<", ">=" or "<=" for comparisons
|
||||
i = *src++ - '0';
|
||||
*dest++ = (ptr[i] & 4) ? '<' : '>';
|
||||
if (ptr[i] & 8) *dest++ = '=';
|
||||
break;
|
||||
|
||||
case '=': // Conditional "=" for assignments
|
||||
i = *src++ - '0';
|
||||
if (ptr[i] < 0xC) *dest++ = '=';
|
||||
break;
|
||||
|
||||
case 'E': // Conditionsl "EX" for assignments
|
||||
i = *src++ - '0';
|
||||
if (ptr[i] >= 0xC) {
|
||||
*dest++ = 'E';
|
||||
*dest++ = 'X';
|
||||
}
|
||||
break;
|
||||
|
||||
case '+': // "+" or "-" for add / dec
|
||||
i = *src++ - '0';
|
||||
*dest++ = (ptr[i] < 0xC) ? '+' : '-';
|
||||
break;
|
||||
|
||||
case '-': // "-" or "+" for sub / inc
|
||||
i = *src++ - '0';
|
||||
*dest++ = ((ptr[i]&0xC) != 0x4) ? '-' : '+';
|
||||
break;
|
||||
|
||||
case '~': // "+" or "-" for +con and -con
|
||||
i = *src++ - '0';
|
||||
*dest++ = (ptr[i]&8) ? '-' : '+';
|
||||
break;
|
||||
|
||||
case '&': // "&" or "!" for and / or
|
||||
i = *src++ - '0';
|
||||
*dest++ = (ptr[i]&8) ? '!' : '&';
|
||||
break;
|
||||
|
||||
case 'D': // DATi=r or r=DATi
|
||||
i = *src++ - '0';
|
||||
if (!(ptr[i]&2)) {
|
||||
*dest++ = 'D';
|
||||
*dest++ = 'A';
|
||||
*dest++ = 'T';
|
||||
*dest++ = '0' + (ptr[i]&1);
|
||||
*dest++ = '=';
|
||||
*dest++ = 'A' + ((ptr[i]&4)>>1);
|
||||
} else {
|
||||
*dest++ = 'A' + ((ptr[i]&4)>>1);
|
||||
*dest++ = '=';
|
||||
*dest++ = 'D';
|
||||
*dest++ = 'A';
|
||||
*dest++ = 'T';
|
||||
*dest++ = '0' + (ptr[i]&1);
|
||||
}
|
||||
break;
|
||||
|
||||
case '%': // Litteral %
|
||||
*(dest++) = '%';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
char *disassemble(byte *ptr)
|
||||
{
|
||||
static char buffer[64];
|
||||
|
||||
Opcode *op = opcodes;
|
||||
int i = 0;
|
||||
|
||||
while (op[ptr[i]].next) {
|
||||
op = op[ptr[i]].next;
|
||||
i++;
|
||||
}
|
||||
if (op[ptr[i]].dissasm) {
|
||||
expand(buffer, op[ptr[i]].dissasm, ptr);
|
||||
} else {
|
||||
sprintf (buffer, "Unknown (%s)", nib_to_hex(ptr, i+1));
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *nib_to_hex(byte *nib, int n)
|
||||
{
|
||||
static char buffer[17];
|
||||
|
||||
buffer[n] = '\0';
|
||||
while (n--) {
|
||||
buffer[n] = HEX(nib[n]);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *nib_to_hex_rev(byte *nib, int n)
|
||||
{
|
||||
static char buffer[17];
|
||||
|
||||
buffer[n] = '\0';
|
||||
while (n--) {
|
||||
buffer[n] = HEX(*nib++);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
35
src/disasm.h
Normal file
35
src/disasm.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __DISASM_H
|
||||
#define __DISASM_H
|
||||
|
||||
char *disassemble(byte *ptr);
|
||||
char *nib_to_hex(byte *nib, int n);
|
||||
char *nib_to_hex_rev(byte *nib, int n);
|
||||
|
||||
#endif
|
155
src/display.c
Normal file
155
src/display.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "types.h"
|
||||
#include "bus.h"
|
||||
|
||||
#define LCD_X 364
|
||||
#define LCD_Y 60
|
||||
|
||||
address menu_base;
|
||||
address display_base;
|
||||
address display_line_offset;
|
||||
byte display_line_count;
|
||||
byte display_height;
|
||||
byte display_offset;
|
||||
boolean display_enable;
|
||||
|
||||
static address cur_adr;
|
||||
static boolean in_menu;
|
||||
static byte off_cur_line;
|
||||
static byte off_line;
|
||||
static int off_cnt;
|
||||
static BITMAP *lcd;
|
||||
|
||||
static void fade_lcd_line(int y)
|
||||
{
|
||||
byte *lcd_line0 = (byte *)lcd->line[y*2];
|
||||
byte *lcd_line1 = (byte *)lcd->line[y*2+1];
|
||||
int x = 0;
|
||||
|
||||
while (x < 131) {
|
||||
lcd_line0[x*2] = lcd_line0[x*2+1] = lcd_line1[x*2] = lcd_line1[x*2+1] = (lcd_line0[x*2] >> 1);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
static address draw_lcd_line(address adr, int y)
|
||||
{
|
||||
int x = 0;
|
||||
int bit = 0;
|
||||
byte data = 0; //Initialized to remove warning
|
||||
byte *ptr;
|
||||
byte *lcd_line0 = (byte *)lcd->line[y*2];
|
||||
byte *lcd_line1 = (byte *)lcd->line[y*2+1];
|
||||
|
||||
ptr = bus_fast_peek(NULL, adr, NULL);
|
||||
|
||||
/* Horisontal pixel offset */
|
||||
if (!in_menu) {
|
||||
if (display_offset > 3) ptr++;
|
||||
data = *ptr++;
|
||||
data >>= display_offset & 3;
|
||||
bit = 4 - (display_offset & 3);
|
||||
}
|
||||
|
||||
while (x < 131) {
|
||||
if (bit == 0) {
|
||||
data = *ptr++;
|
||||
bit = 4;
|
||||
}
|
||||
lcd_line0[x*2] = lcd_line0[x*2+1] = lcd_line1[x*2] = lcd_line1[x*2+1] = (lcd_line0[x*2] >> 1) | ((data & 1) << 6);
|
||||
data >>= 1;
|
||||
bit--;
|
||||
x++;
|
||||
}
|
||||
return (adr + 0x22 + (!in_menu && (display_offset&4)?2:0)) & 0xFFFFF;
|
||||
}
|
||||
|
||||
void display_init(void)
|
||||
{
|
||||
lcd = create_bitmap_ex(8, 131*2, 64*2);
|
||||
clear_to_color(lcd, 0);
|
||||
}
|
||||
|
||||
void display_exit(void)
|
||||
{
|
||||
destroy_bitmap (lcd);
|
||||
lcd = NULL;
|
||||
}
|
||||
|
||||
void display_update(void)
|
||||
{
|
||||
if (!display_enable && !off_cnt) { /* Turn off display */
|
||||
off_cnt = 1;
|
||||
off_cur_line = off_line = display_line_count;
|
||||
display_line_count = 0;
|
||||
} else if (display_enable && off_cnt) { /* Turn on display */
|
||||
off_cnt = 0;
|
||||
display_line_count = 0;
|
||||
in_menu = 0;
|
||||
cur_adr = display_base;
|
||||
}
|
||||
if (!off_cnt) { /* Display is on */
|
||||
cur_adr = draw_lcd_line(cur_adr, display_line_count);
|
||||
|
||||
acquire_screen();
|
||||
scare_mouse_area(LCD_X, LCD_Y+display_line_count*2, 131*2, 2);
|
||||
blit(lcd, screen, 0, display_line_count*2, LCD_X, LCD_Y+display_line_count*2, 131*2, 2);
|
||||
unscare_mouse();
|
||||
release_screen();
|
||||
|
||||
if (!in_menu) {
|
||||
cur_adr += display_line_offset;
|
||||
}
|
||||
if (display_line_count == display_height) {
|
||||
in_menu = 1;
|
||||
cur_adr = menu_base;
|
||||
}
|
||||
display_line_count++;
|
||||
if (display_line_count == 64) {
|
||||
display_line_count = 0;
|
||||
in_menu = 0;
|
||||
cur_adr = display_base;
|
||||
}
|
||||
} else if (off_cnt <= 7) { /* Display is off and still fading */
|
||||
fade_lcd_line(off_cur_line);
|
||||
|
||||
acquire_screen();
|
||||
scare_mouse_area(LCD_X, LCD_Y+off_cur_line*2, 131*2, 2);
|
||||
blit(lcd, screen, 0, off_cur_line*2, LCD_X, LCD_Y+off_cur_line*2, 131*2, 2);
|
||||
unscare_mouse();
|
||||
release_screen();
|
||||
|
||||
off_cur_line++;
|
||||
if (off_cur_line == 64) off_cur_line = 0;
|
||||
if (off_cur_line == off_line) {
|
||||
off_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
46
src/display.h
Normal file
46
src/display.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __DISPLAY_H
|
||||
#define __DISPLAY_H
|
||||
|
||||
#include <allegro.h>
|
||||
#include "types.h"
|
||||
|
||||
extern address menu_base;
|
||||
extern address display_base;
|
||||
extern address display_line_offset;
|
||||
extern byte display_line_count;
|
||||
extern byte display_height;
|
||||
extern byte display_offset;
|
||||
extern boolean display_enable;
|
||||
|
||||
void display_init(void);
|
||||
void display_exit(void);
|
||||
void display_update(void);
|
||||
|
||||
#endif
|
210
src/emulator.c
Normal file
210
src/emulator.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "types.h"
|
||||
#include "cpu.h"
|
||||
#include "bus.h"
|
||||
#include "timers.h"
|
||||
#include "display.h"
|
||||
#include "gui.h"
|
||||
#include "pdebug.h"
|
||||
#include "emulator.h"
|
||||
|
||||
/* Define TRUE_TIMER2 to make timer2 run in true speed (8192 hz).
|
||||
* If it is not defined timer2 is syncronized to the cpu speed.
|
||||
*/
|
||||
#define TRUE_TIMER2
|
||||
|
||||
#define MAX_DELTA 4000
|
||||
|
||||
typedef struct {
|
||||
dword next;
|
||||
dword freq;
|
||||
void (*proc)(void);
|
||||
} CycleEvent;
|
||||
|
||||
typedef struct {
|
||||
volatile int value;
|
||||
int speed;
|
||||
boolean running;
|
||||
void (*proc)(void);
|
||||
} TimerEvent;
|
||||
|
||||
static void true_speed_proc(void);
|
||||
|
||||
static CycleEvent cycle_events[] = {
|
||||
{ 0, 16, timer1_update },
|
||||
#ifndef TRUE_TIMER2
|
||||
{ 0, 8192, timer2_update },
|
||||
#endif
|
||||
{ 0, 4096, display_update },
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
static TimerEvent timer_events[] = {
|
||||
{ 0, BPS_TO_TIMER(20), FALSE, gui_update },
|
||||
{ 0, BPS_TO_TIMER(1), FALSE, true_speed_proc },
|
||||
#ifdef TRUE_TIMER2
|
||||
{ 0, BPS_TO_TIMER(8192), FALSE, timer2_update },
|
||||
#endif
|
||||
{ 0, 0, FALSE, NULL }
|
||||
};
|
||||
|
||||
volatile boolean please_exit = FALSE;
|
||||
dword emulator_speed = 4000000;
|
||||
static int emulator_state = EMULATOR_STOP;
|
||||
|
||||
static void true_speed_proc(void)
|
||||
{
|
||||
static dword last_cycles;
|
||||
|
||||
pdebug_draw_true_speed(cpu.cycles - last_cycles);
|
||||
last_cycles = cpu.cycles;
|
||||
}
|
||||
|
||||
static void timer_event_proc(void *what)
|
||||
{
|
||||
((TimerEvent *)what)->value++;
|
||||
} END_OF_STATIC_FUNCTION(timer_event_proc);
|
||||
|
||||
static void start_timer_proc(void (*proc)(void))
|
||||
{
|
||||
TimerEvent *ptr = timer_events;
|
||||
|
||||
while (ptr->proc && ptr->proc != proc) {
|
||||
ptr++;
|
||||
}
|
||||
if (ptr->proc && !ptr->running) {
|
||||
ptr->value = 0;
|
||||
ptr->running = TRUE;
|
||||
install_param_int_ex(timer_event_proc, (void *)ptr, ptr->speed);
|
||||
}
|
||||
}
|
||||
|
||||
static void stop_timer_proc(void (*proc) (void))
|
||||
{
|
||||
TimerEvent *ptr = timer_events;
|
||||
|
||||
while (ptr->proc && ptr->proc != proc) {
|
||||
ptr++;
|
||||
}
|
||||
if (ptr->proc && ptr->running) {
|
||||
ptr->value = 0;
|
||||
ptr->running = FALSE;
|
||||
remove_param_int(timer_event_proc, (void *)ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void emulator_set_state(int state)
|
||||
{
|
||||
#ifdef TRUE_TIMER2
|
||||
if (state != EMULATOR_STOP) {
|
||||
start_timer_proc(timer2_update);
|
||||
} else {
|
||||
stop_timer_proc(timer2_update);
|
||||
}
|
||||
#endif
|
||||
emulator_state = state;
|
||||
pdebug_state_changed();
|
||||
}
|
||||
|
||||
int emulator_get_state(void)
|
||||
{
|
||||
return emulator_state;
|
||||
}
|
||||
|
||||
void emulator_init(void)
|
||||
{
|
||||
static boolean locked = FALSE;
|
||||
|
||||
bus_init();
|
||||
display_init();
|
||||
|
||||
if (!locked) {
|
||||
LOCK_VARIABLE(timer_events);
|
||||
LOCK_FUNCTION(timer_event_proc);
|
||||
locked = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void emulator_exit(void)
|
||||
{
|
||||
display_exit();
|
||||
bus_exit();
|
||||
}
|
||||
|
||||
void emulator_run(void)
|
||||
{
|
||||
CycleEvent *cep;
|
||||
TimerEvent *tep;
|
||||
dword delta;
|
||||
|
||||
start_timer_proc(gui_update);
|
||||
start_timer_proc(true_speed_proc);
|
||||
|
||||
while (!please_exit) {
|
||||
if (emulator_state != EMULATOR_STOP) {
|
||||
if (!cpu.shutdown) {
|
||||
execute_instruction();
|
||||
if (emulator_state == EMULATOR_STEP) {
|
||||
emulator_set_state(EMULATOR_STOP);
|
||||
}
|
||||
} else {
|
||||
delta = MAX_DELTA;
|
||||
for (cep = cycle_events; cep->proc; cep++) {
|
||||
delta = MIN(delta, cep->next - cpu.cycles + 1);
|
||||
}
|
||||
cpu.cycles += delta;
|
||||
}
|
||||
for (cep = cycle_events; cep->proc; cep++) {
|
||||
if ((cep->next - cpu.cycles) & 0x80000000) {
|
||||
cep->next += emulator_speed / cep->freq;
|
||||
cep->proc();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (tep = timer_events; tep->proc; tep++) {
|
||||
if (tep->running && tep->value) {
|
||||
tep->value--;
|
||||
tep->proc();
|
||||
}
|
||||
}
|
||||
if (emulator_state == EMULATOR_STOP) {
|
||||
rest(10);
|
||||
} else {
|
||||
yield_timeslice ();
|
||||
}
|
||||
}
|
||||
#ifdef TRUE_TIMER2
|
||||
if (emulator_state != EMULATOR_STOP) {
|
||||
stop_timer_proc(timer2_update);
|
||||
}
|
||||
#endif
|
||||
stop_timer_proc(true_speed_proc);
|
||||
stop_timer_proc(gui_update);
|
||||
}
|
49
src/emulator.h
Normal file
49
src/emulator.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __EMULATOR_H
|
||||
#define __EMULATOR_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
enum EmulatorStates {
|
||||
EMULATOR_STOP,
|
||||
EMULATOR_STEP,
|
||||
EMULATOR_RUN
|
||||
};
|
||||
|
||||
extern volatile boolean please_exit;
|
||||
extern dword emulator_speed;
|
||||
|
||||
void emulator_init(void);
|
||||
void emulator_exit(void);
|
||||
void emulator_run(void);
|
||||
|
||||
void emulator_set_state(int state);
|
||||
int emulator_get_state(void);
|
||||
|
||||
#endif
|
233
src/gui.c
Normal file
233
src/gui.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "color.h"
|
||||
#include "pmenu.h"
|
||||
#include "pcalc.h"
|
||||
#include "pdebug.h"
|
||||
#include "pfiles.h"
|
||||
#include "pabout.h"
|
||||
#include "gui.h"
|
||||
|
||||
#define PANEL_FLAG_VISIBLE 0x01
|
||||
|
||||
typedef struct GuiPanel {
|
||||
int x, y;
|
||||
int w, h;
|
||||
int flags;
|
||||
BITMAP *bmp;
|
||||
void (*show)(BITMAP *bmp);
|
||||
void (*hide)(void);
|
||||
void (*mouse_down)(int mx, int my, int mb);
|
||||
void (*mouse_up)(int mx, int my, int mb);
|
||||
} GuiPanel;
|
||||
|
||||
static GuiPanel panels[PANEL_COUNT] = {
|
||||
{ 10, 10, 620, 20, 0, NULL, pmenu_show, pmenu_hide, pmenu_down, pmenu_up },
|
||||
{ 360, 40, 270, 430, 0, NULL, pcalc_show, pcalc_hide, pcalc_down, pcalc_up },
|
||||
{ 10, 40, 340, 430, 0, NULL, pdebug_show, pdebug_hide, pdebug_down, pdebug_up },
|
||||
{ 10, 40, 340, 430, 0, NULL, pfiles_show, pfiles_hide, pfiles_down, pfiles_up },
|
||||
{ 10, 40, 340, 430, 0, NULL, pabout_show, pabout_hide, pabout_down, pabout_up },
|
||||
};
|
||||
|
||||
void gui_init(void)
|
||||
{
|
||||
clear_to_color(screen, color[C_BACKGROUND]);
|
||||
gui_show_panel(PANEL_MENU);
|
||||
gui_show_panel(PANEL_CALC);
|
||||
gui_show_panel(PANEL_ABOUT);
|
||||
}
|
||||
|
||||
void gui_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PANEL_COUNT; i++) {
|
||||
gui_hide_panel(i);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline int panel_at(int x, int y)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = PANEL_COUNT; i >= 0; i--) {
|
||||
if (panels[i].flags & PANEL_FLAG_VISIBLE &&
|
||||
x >= panels[i].x && x < panels[i].x+panels[i].w &&
|
||||
y >= panels[i].y && y < panels[i].y+panels[i].h) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void gui_update(void)
|
||||
{
|
||||
static int down_panel = -1;
|
||||
static int down_mb = 0;
|
||||
int mx, my, mb;
|
||||
|
||||
mx = mouse_x;
|
||||
my = mouse_y;
|
||||
mb = mouse_b;
|
||||
|
||||
if (!down_mb && (mb & 1)) {
|
||||
down_panel = panel_at(mx, my);
|
||||
if (down_panel >= 0) {
|
||||
down_mb = 1;
|
||||
panels[down_panel].mouse_down(mx - panels[down_panel].x, my - panels[down_panel].y, down_mb);
|
||||
}
|
||||
} else if (!down_mb && (mb & 2)) {
|
||||
down_panel = panel_at(mx, my);
|
||||
if (down_panel >= 0) {
|
||||
down_mb = 2;
|
||||
panels[down_panel].mouse_down(mx - panels[down_panel].x, my - panels[down_panel].y, down_mb);
|
||||
}
|
||||
} else if (down_mb && !(mb & 3)) {
|
||||
panels[down_panel].mouse_up(mx - panels[down_panel].x, my - panels[down_panel].y, down_mb);
|
||||
down_mb = 0;
|
||||
down_panel = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void gui_show_panel(int i)
|
||||
{
|
||||
if (!(panels[i].flags & PANEL_FLAG_VISIBLE)) {
|
||||
panels[i].flags |= PANEL_FLAG_VISIBLE;
|
||||
panels[i].bmp = create_sub_bitmap(screen, panels[i].x, panels[i].y, panels[i].w, panels[i].h);
|
||||
acquire_screen();
|
||||
scare_mouse();
|
||||
rect(screen, panels[i].x-1, panels[i].y-1, panels[i].x+panels[i].w, panels[i].y+panels[i].h, color[C_PANEL_BORDER]);
|
||||
panels[i].show(panels[i].bmp);
|
||||
unscare_mouse();
|
||||
release_screen();
|
||||
}
|
||||
}
|
||||
|
||||
void gui_hide_panel(int i)
|
||||
{
|
||||
if (panels[i].flags & PANEL_FLAG_VISIBLE) {
|
||||
panels[i].flags &= ~PANEL_FLAG_VISIBLE;
|
||||
panels[i].hide();
|
||||
destroy_bitmap(panels[i].bmp);
|
||||
panels[i].bmp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void button_draw(BITMAP *bmp, Button *b)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = color[(b->flags&BUTTON_PUSHED) ? C_BUTTON_PUSHED : C_BUTTON_BACK];
|
||||
text_mode(c);
|
||||
acquire_bitmap(bmp);
|
||||
scare_mouse();
|
||||
rect(bmp, b->x-1, b->y-1, b->x+b->w, b->y+b->h, color[C_BUTTON_BORDER]);
|
||||
rectfill(bmp, b->x, b->y, b->x+b->w-1, b->y+b->h-1, c);
|
||||
c = color[(b->flags&BUTTON_DISABLED) ? C_BUTTON_DISABLED : C_BUTTON_TEXT];
|
||||
textout_centre(bmp, font, b->text, b->x+b->w/2, b->y+(b->h-text_height (font))/2, c);
|
||||
unscare_mouse();
|
||||
release_bitmap(bmp);
|
||||
}
|
||||
|
||||
void button_draw_all(BITMAP *bmp, Button *buttons)
|
||||
{
|
||||
acquire_bitmap(bmp);
|
||||
scare_mouse();
|
||||
while (buttons->text) {
|
||||
button_draw(bmp, buttons);
|
||||
buttons++;
|
||||
}
|
||||
unscare_mouse();
|
||||
release_bitmap(bmp);
|
||||
}
|
||||
|
||||
static __inline Button *find_button(Button *b, int x, int y)
|
||||
{
|
||||
while (b->text) {
|
||||
if (x >= b->x && x < b->x+b->w && y >= b->y && y < b->y+b->h) {
|
||||
return b;
|
||||
}
|
||||
b++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int button_mouse_down(BITMAP *bmp, Button *buttons, int mx, int my, int mb)
|
||||
{
|
||||
Button *b = find_button(buttons, mx, my);
|
||||
|
||||
if (!b) {
|
||||
return 0;
|
||||
}
|
||||
if (!(b->flags & BUTTON_DISABLED)) {
|
||||
if ((mb == 2 && (b->flags & BUTTON_B2TOGGLE)) ||
|
||||
(mb == 1 && (b->flags & BUTTON_B1TOGGLE))) {
|
||||
if (b->flags & BUTTON_PUSHED) {
|
||||
b->flags &= ~BUTTON_PUSHED;
|
||||
button_draw(bmp, b);
|
||||
if (b->up) b->up(TRUE);
|
||||
} else {
|
||||
b->flags |= BUTTON_PUSHED;
|
||||
button_draw(bmp, b);
|
||||
if (b->down) b->down();
|
||||
}
|
||||
} else if (mb == 1 && !(b->flags & BUTTON_PUSHED)) {
|
||||
b->flags |= BUTTON_PUSHED;
|
||||
button_draw(bmp, b);
|
||||
if (b->down) b->down();
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int button_mouse_up(BITMAP *bmp, Button *buttons, int mx, int my, int mb)
|
||||
{
|
||||
Button *b = find_button(buttons, mx, my);
|
||||
int ret = (b != NULL);
|
||||
|
||||
if (b && !(b->flags & BUTTON_DISABLED)) {
|
||||
if (mb == 1 && (b->flags & BUTTON_PUSHED) && !(b->flags & BUTTON_B1TOGGLE)) {
|
||||
b->flags &= ~BUTTON_PUSHED;
|
||||
button_draw(bmp, b);
|
||||
if (b->up) b->up(TRUE);
|
||||
}
|
||||
}
|
||||
if (mb == 1) {
|
||||
for (b = buttons; b->text; b++) {
|
||||
if ((b->flags & (BUTTON_B1RELEASE|BUTTON_PUSHED)) == (BUTTON_B1RELEASE|BUTTON_PUSHED)) {
|
||||
b->flags &= ~BUTTON_PUSHED;
|
||||
button_draw(bmp, b);
|
||||
if (b->up) b->up(FALSE);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
73
src/gui.h
Normal file
73
src/gui.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __GUI_H
|
||||
#define __GUI_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
enum Panels {
|
||||
PANEL_MENU,
|
||||
PANEL_CALC,
|
||||
PANEL_DEBUG,
|
||||
PANEL_FILES,
|
||||
PANEL_ABOUT,
|
||||
PANEL_COUNT
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int x, y;
|
||||
int w, h;
|
||||
int flags;
|
||||
char *text;
|
||||
void (*down)(void);
|
||||
void (*up)(boolean action);
|
||||
} Button;
|
||||
|
||||
/* Button flags:
|
||||
* Use BUTTON_B1RELEASE for normal buttons.
|
||||
* Use BUTTON_B1RELEASE | BUTTON_B2TOGGLE for calculator buttons.
|
||||
* Use BUTTON_B1TOGGLE for toggle buttons
|
||||
*/
|
||||
#define BUTTON_PUSHED 0x01 // Set if button is pushed
|
||||
#define BUTTON_DISABLED 0x02 // If set the button will be grayed out
|
||||
#define BUTTON_B1TOGGLE 0x04 // Mouse button 1 toggles this button
|
||||
#define BUTTON_B2TOGGLE 0x08 // Mouse button 2 toggles this button
|
||||
#define BUTTON_B1RELEASE 0x10 // Releaseing mouse button 1 anywhere unpushes the button
|
||||
|
||||
void gui_init(void);
|
||||
void gui_exit(void);
|
||||
void gui_update(void);
|
||||
void gui_show_panel(int i);
|
||||
void gui_hide_panel(int i);
|
||||
|
||||
void button_draw(BITMAP *bmp, Button *buttons);
|
||||
void button_draw_all(BITMAP *bmp, Button *buttons);
|
||||
int button_mouse_down(BITMAP *bmp, Button *butons, int mx, int my, int mb);
|
||||
int button_mouse_up(BITMAP *bmp, Button *buttons, int mx, int my, int mb);
|
||||
|
||||
#endif
|
193
src/hdw.c
Normal file
193
src/hdw.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "bus.h"
|
||||
#include "ports.h"
|
||||
#include "timers.h"
|
||||
#include "display.h"
|
||||
#include "hdw.h"
|
||||
|
||||
static byte hdw_ram[64];
|
||||
|
||||
void hdw_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void hdw_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
byte hdw_read_nibble(address adr)
|
||||
{
|
||||
switch (adr) {
|
||||
|
||||
case 0x00: return display_offset | (display_enable ? 0x8 : 0x0);
|
||||
|
||||
case 0x04: return (byte) crc & 0xF;
|
||||
case 0x05: return (byte) (crc >> 4) & 0xF;
|
||||
case 0x06: return (byte) (crc >> 8) & 0xF;
|
||||
case 0x07: return (byte) (crc >> 12) & 0xF;
|
||||
|
||||
case 0x0F: return (hdw_ram[0x0E] & 0x8) ? ports_card_detect() : 0;
|
||||
|
||||
case 0x28: return display_line_count & 0xF;
|
||||
case 0x29: return (display_line_count>>4) | (hdw_ram[0x29] & 0x4) | (bus_info.da19 ? 0x8 : 0x0);
|
||||
|
||||
case 0x2E: return timer1_control;
|
||||
case 0x2F: return timer2_control;
|
||||
|
||||
case 0x37: return timer1_value;
|
||||
case 0x38: return (byte) timer2_value & 0xF;
|
||||
case 0x39: return (byte) (timer2_value >> 4) & 0xF;
|
||||
case 0x3A: return (byte) (timer2_value >> 8) & 0xF;
|
||||
case 0x3B: return (byte) (timer2_value >> 12) & 0xF;
|
||||
case 0x3C: return (byte) (timer2_value >> 16) & 0xF;
|
||||
case 0x3D: return (byte) (timer2_value >> 20) & 0xF;
|
||||
case 0x3E: return (byte) (timer2_value >> 24) & 0xF;
|
||||
case 0x3F: return (byte) (timer2_value >> 28) & 0xF;
|
||||
|
||||
default: return hdw_ram[adr];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void hdw_write_nibble(byte data, address adr)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
switch (adr) {
|
||||
|
||||
case 0x00: display_offset = data & 7;
|
||||
display_enable = (data & 8) ? TRUE : FALSE;
|
||||
break;
|
||||
|
||||
case 0x04: crc &= 0xFFF0;
|
||||
crc |= (word) data;
|
||||
break;
|
||||
case 0x05: crc &= 0xFF0F;
|
||||
crc |= (word) data << 4;
|
||||
break;
|
||||
case 0x06: crc &= 0xF0FF;
|
||||
crc |= (word) data << 8;
|
||||
break;
|
||||
case 0x07: crc &= 0x0FFF;
|
||||
crc |= (word) data << 12;
|
||||
break;
|
||||
|
||||
case 0x0F: break;
|
||||
|
||||
case 0x20: display_base &= 0xFFFF0;
|
||||
display_base |= (address) data & 0xE;
|
||||
break;
|
||||
case 0x21: display_base &= 0xFFF0F;
|
||||
display_base |= (address) data << 4;
|
||||
break;
|
||||
case 0x22: display_base &= 0xFF0FF;
|
||||
display_base |= (address) data << 8;
|
||||
break;
|
||||
case 0x23: display_base &= 0xF0FFF;
|
||||
display_base |= (address) data << 12;
|
||||
break;
|
||||
case 0x24: display_base &= 0x0FFFF;
|
||||
display_base |= (address) data << 16;
|
||||
break;
|
||||
case 0x25: display_line_offset &= 0xFF0;
|
||||
display_line_offset |= (address) data & 0xE;
|
||||
break;
|
||||
case 0x26: display_line_offset &= 0xF0F;
|
||||
display_line_offset |= (address) data << 4;
|
||||
break;
|
||||
case 0x27: display_line_offset &= 0x0FF;
|
||||
display_line_offset |= (address) data << 8;
|
||||
if (display_line_offset & 0x800)
|
||||
display_line_offset |= ~0xFFF;
|
||||
else
|
||||
display_line_offset &= 0xFFF;
|
||||
break;
|
||||
case 0x28: display_height &= 0xF0;
|
||||
display_height |= data;
|
||||
break;
|
||||
case 0x29: display_height &= 0x0F;
|
||||
display_height |= (data&3) << 4;
|
||||
hdw_ram[0x29] = data & 0x4;
|
||||
tmp = bus_info.da19;
|
||||
bus_info.da19 = (data & 0x8) ? TRUE : FALSE;
|
||||
if (tmp != bus_info.da19) {
|
||||
bus_remap();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2E: timer1_control = data; break;
|
||||
case 0x2F: timer2_control = data; break;
|
||||
|
||||
case 0x30: menu_base &= 0xFFFF0;
|
||||
menu_base |= (address) data & 0xE;
|
||||
break;
|
||||
case 0x31: menu_base &= 0xFFF0F;
|
||||
menu_base |= (address) data << 4;
|
||||
break;
|
||||
case 0x32: menu_base &= 0xFF0FF;
|
||||
menu_base |= (address) data << 8;
|
||||
break;
|
||||
case 0x33: menu_base &= 0xF0FFF;
|
||||
menu_base |= (address) data << 12;
|
||||
break;
|
||||
case 0x34: menu_base &= 0x0FFFF;
|
||||
menu_base |= (address) data << 16;
|
||||
break;
|
||||
|
||||
case 0x37: timer1_value = data; break;
|
||||
case 0x38: timer2_value &= 0xFFFFFFF0;
|
||||
timer2_value |= (dword) data;
|
||||
break;
|
||||
case 0x39: timer2_value &= 0xFFFFFF0F;
|
||||
timer2_value |= (dword) data << 4;
|
||||
break;
|
||||
case 0x3A: timer2_value &= 0xFFFFF0FF;
|
||||
timer2_value |= (dword) data << 8;
|
||||
break;
|
||||
case 0x3B: timer2_value &= 0xFFFF0FFF;
|
||||
timer2_value |= (dword) data << 12;
|
||||
break;
|
||||
case 0x3C: timer2_value &= 0xFFF0FFFF;
|
||||
timer2_value |= (dword) data << 16;
|
||||
break;
|
||||
case 0x3D: timer2_value &= 0xFF0FFFFF;
|
||||
timer2_value |= (dword) data << 20;
|
||||
break;
|
||||
case 0x3E: timer2_value &= 0xF0FFFFFF;
|
||||
timer2_value |= (dword) data << 24;
|
||||
break;
|
||||
case 0x3F: timer2_value &= 0x0FFFFFFF;
|
||||
timer2_value |= (dword) data << 28;
|
||||
break;
|
||||
|
||||
default: hdw_ram[adr] = data;
|
||||
break;
|
||||
}
|
||||
}
|
39
src/hdw.h
Normal file
39
src/hdw.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __HDW_H
|
||||
#define __HDW_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void hdw_init(void);
|
||||
void hdw_exit(void);
|
||||
|
||||
byte hdw_read_nibble(address adr);
|
||||
void hdw_write_nibble(byte data, address adr);
|
||||
|
||||
#endif
|
109
src/keyboard.c
Normal file
109
src/keyboard.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "cpu.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
boolean kbd_on;
|
||||
|
||||
static byte kbd_row[9];
|
||||
|
||||
static void update_in(void)
|
||||
{
|
||||
byte in = 0;
|
||||
|
||||
// TODO: Emulate real HP48 keyboard circuit
|
||||
|
||||
if (cpu.out[0]&1) in |= kbd_row[0];
|
||||
if (cpu.out[0]&2) in |= kbd_row[1];
|
||||
if (cpu.out[0]&4) in |= kbd_row[2];
|
||||
if (cpu.out[0]&8) in |= kbd_row[3];
|
||||
if (cpu.out[1]&1) in |= kbd_row[4];
|
||||
if (cpu.out[1]&2) in |= kbd_row[5];
|
||||
if (cpu.out[1]&4) in |= kbd_row[6];
|
||||
if (cpu.out[1]&8) in |= kbd_row[7];
|
||||
if (cpu.out[2]&1) in |= kbd_row[8];
|
||||
|
||||
cpu.in[0] = in & 0xF;
|
||||
cpu.in[1] = (in >> 4) & 0xF;
|
||||
cpu.in[2] = 0;
|
||||
cpu.in[3] = kbd_on ? 8 : 0;
|
||||
}
|
||||
|
||||
void kbd_out_changed(void)
|
||||
{
|
||||
update_in();
|
||||
}
|
||||
|
||||
void kbd_key_pressed(int row, int col)
|
||||
{
|
||||
boolean no_key = !cpu.in[0] && !cpu.in[1] && !cpu.in[3];
|
||||
kbd_row[row] |= 1 << col;
|
||||
update_in();
|
||||
if (cpu.shutdown && no_key && (cpu.in[0] || cpu.in[1] || cpu.in[3])) {
|
||||
cpu.shutdown = FALSE;
|
||||
}
|
||||
if (cpu.keyscan && no_key && (cpu.in[0] || cpu.in[1] || cpu.in[3])) {
|
||||
if (cpu.inte) {
|
||||
cpu.keyintp = FALSE;
|
||||
cpu_interrupt();
|
||||
} else {
|
||||
cpu.keyintp = TRUE;
|
||||
}
|
||||
} else if (!cpu.in[0] && !cpu.in[1] && !cpu.in[3]) {
|
||||
cpu.keyintp = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void kbd_key_released(int row, int col)
|
||||
{
|
||||
kbd_row[row] &= ~(1 << col);
|
||||
update_in();
|
||||
if (!cpu.in[0] && !cpu.in[1] && !cpu.in[3]) {
|
||||
cpu.keyintp = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void kbd_on_pressed(void)
|
||||
{
|
||||
boolean no_key = !cpu.in[3];
|
||||
kbd_on = TRUE;
|
||||
cpu.in[3] |= 8;
|
||||
if (cpu.shutdown && no_key) {
|
||||
cpu.shutdown = FALSE;
|
||||
}
|
||||
if (cpu.inte && no_key) {
|
||||
cpu_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void kbd_on_released(void)
|
||||
{
|
||||
kbd_on = FALSE;
|
||||
cpu.in[3] &= ~8;
|
||||
}
|
39
src/keyboard.h
Normal file
39
src/keyboard.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __KEYBOARD_H
|
||||
#define __KEYBOARD_H
|
||||
|
||||
extern boolean kbd_on;
|
||||
|
||||
void kbd_out_changed(void);
|
||||
void kbd_key_pressed(int row, int col);
|
||||
void kbd_key_released(int row, int col);
|
||||
void kbd_on_pressed(void);
|
||||
void kbd_on_released(void);
|
||||
|
||||
#endif
|
124
src/main.c
Normal file
124
src/main.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "types.h"
|
||||
#include "emulator.h"
|
||||
#include "gui.h"
|
||||
#include "color.h"
|
||||
|
||||
static int fullscreen = FALSE;
|
||||
|
||||
static void parse_args(int argc, char *argv[])
|
||||
{
|
||||
while (--argc) {
|
||||
argv++;
|
||||
if (argv[0][0] == '-') {
|
||||
switch (argv[0][1]) {
|
||||
case 'f':
|
||||
fullscreen = TRUE;
|
||||
break;
|
||||
case 'w':
|
||||
fullscreen = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void close_hook(void)
|
||||
{
|
||||
please_exit = TRUE;
|
||||
}
|
||||
|
||||
static void program_init(void)
|
||||
{
|
||||
int depth;
|
||||
|
||||
if (install_allegro(SYSTEM_AUTODETECT, &errno, atexit) < 0) {
|
||||
allegro_message("Can't install allegro");
|
||||
exit(1);
|
||||
}
|
||||
if (install_timer() < 0) {
|
||||
allegro_message("Can't install timer driver");
|
||||
exit(1);
|
||||
}
|
||||
if (install_keyboard() < 0) {
|
||||
allegro_message("Can't install keyboard driver");
|
||||
exit(1);
|
||||
}
|
||||
if (install_mouse() < 0) {
|
||||
allegro_message("Can't install mouse driver");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fullscreen) {
|
||||
depth = 8;
|
||||
} else {
|
||||
depth = desktop_color_depth();
|
||||
if (depth == 0) {
|
||||
depth = 8;
|
||||
}
|
||||
}
|
||||
set_color_depth(depth);
|
||||
|
||||
if (set_gfx_mode(fullscreen
|
||||
? GFX_AUTODETECT_FULLSCREEN
|
||||
: GFX_AUTODETECT_WINDOWED,
|
||||
640, 480, 0, 0) < 0) {
|
||||
allegro_message("Can't set graphics mode (%s)", allegro_error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
set_window_title("hpemu 0.9.0");
|
||||
set_window_close_hook(close_hook);
|
||||
|
||||
color_init();
|
||||
|
||||
show_mouse(screen);
|
||||
}
|
||||
|
||||
static void program_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
parse_args (argc, argv);
|
||||
program_init();
|
||||
emulator_init();
|
||||
gui_init();
|
||||
|
||||
emulator_run();
|
||||
|
||||
gui_exit();
|
||||
emulator_exit();
|
||||
program_exit();
|
||||
|
||||
return 0;
|
||||
} END_OF_MAIN();
|
||||
|
1164
src/opcodes.c
Normal file
1164
src/opcodes.c
Normal file
File diff suppressed because it is too large
Load diff
41
src/opcodes.h
Normal file
41
src/opcodes.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __OPCODES_H
|
||||
#define __OPCODES_H
|
||||
|
||||
typedef struct Opcode Opcode;
|
||||
|
||||
struct Opcode {
|
||||
void (*exec)(byte *);
|
||||
Opcode *next;
|
||||
char *dissasm;
|
||||
};
|
||||
|
||||
extern Opcode opcodes[16];
|
||||
|
||||
#endif
|
404
src/opinline.h
Normal file
404
src/opinline.h
Normal file
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __OPINLINE_H
|
||||
#define __OPINLINE_H
|
||||
|
||||
#include <string.h>
|
||||
#include "emulator.h"
|
||||
#include "cpu.h"
|
||||
|
||||
static __inline void load(byte *reg, byte *data, int start, int len)
|
||||
{
|
||||
if (start + len <= 16) {
|
||||
memcpy(reg+start, data, len);
|
||||
} else {
|
||||
memcpy(reg+start, data, 16-start);
|
||||
memcpy(reg, data+(16-start), len-(16-start));
|
||||
}
|
||||
}
|
||||
|
||||
static __inline unsigned int nib_to_unsigned(byte *nib, int len)
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
while (len--) {
|
||||
x <<= 4;
|
||||
x |= nib[len];
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static __inline int nib_to_signed(byte *nib, int len)
|
||||
{
|
||||
int x;
|
||||
|
||||
len--;
|
||||
x = nib[len];
|
||||
if (x & 8) x -= 16;
|
||||
while (len--) {
|
||||
x <<= 4;
|
||||
x |= nib[len];
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static __inline void unsigned_to_nib(byte *nib, int x, int len)
|
||||
{
|
||||
while (len--) {
|
||||
*nib++ = x & 0xF;
|
||||
x >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline address rstk_pop(void)
|
||||
{
|
||||
address adr = cpu.rstk[cpu.rstk_ptr];
|
||||
cpu.rstk[cpu.rstk_ptr] = 0x00000;
|
||||
cpu.rstk_ptr = (cpu.rstk_ptr + 1) & 7;
|
||||
return adr;
|
||||
}
|
||||
|
||||
static __inline void rstk_push(address adr)
|
||||
{
|
||||
cpu.rstk_ptr = (cpu.rstk_ptr - 1) & 7;
|
||||
cpu.rstk[cpu.rstk_ptr] = adr & 0xFFFFF;
|
||||
}
|
||||
|
||||
static __inline void goyes(byte *opc, int offset)
|
||||
{
|
||||
if (cpu.carry) {
|
||||
address rel = nib_to_signed(opc + offset, 2);
|
||||
if (rel) {
|
||||
cpu.pc += rel + offset;
|
||||
} else {
|
||||
cpu.pc = rstk_pop();
|
||||
}
|
||||
cpu.cycles += 7;
|
||||
} else {
|
||||
cpu.pc += offset + 2;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void reg_zero(byte *reg, int len)
|
||||
{
|
||||
memset(reg, 0, len);
|
||||
}
|
||||
|
||||
static __inline void reg_bit(byte *reg, int bit, int value)
|
||||
{
|
||||
if (value) {
|
||||
reg[bit>>2] |= 1 << (bit & 3);
|
||||
} else {
|
||||
reg[bit>>2] &= ~(1 << (bit & 3));
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void reg_cpy(byte *dest, byte *src, int len)
|
||||
{
|
||||
memcpy(dest, src, len);
|
||||
}
|
||||
|
||||
static __inline void reg_ex(byte *reg1, byte *reg2, int len)
|
||||
{
|
||||
static byte tmp[16];
|
||||
|
||||
memcpy(tmp, reg1, len);
|
||||
memcpy(reg1, reg2, len);
|
||||
memcpy(reg2, tmp, len);
|
||||
}
|
||||
|
||||
static __inline void comp_bit_zero(byte *reg, int bit)
|
||||
{
|
||||
cpu.carry =(reg[bit>>2] & (1 << (bit & 3))) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
static __inline void comp_zero(byte *reg, int len)
|
||||
{
|
||||
while (len--) {
|
||||
if (*reg++) {
|
||||
cpu.carry = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cpu.carry = TRUE;
|
||||
}
|
||||
|
||||
static __inline void comp_eq(byte *reg1, byte *reg2, int len)
|
||||
{
|
||||
while (len--) {
|
||||
if (*reg1++ != *reg2++) {
|
||||
cpu.carry = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cpu.carry = TRUE;
|
||||
}
|
||||
|
||||
static __inline void comp_gt(byte *reg1, byte *reg2, int len)
|
||||
{
|
||||
while (--len && reg1[len] == reg2[len])
|
||||
;
|
||||
cpu.carry = (reg1[len] > reg2[len]) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static __inline void alu_add(byte *dest, byte *src, int len)
|
||||
{
|
||||
byte c = 0;
|
||||
byte base = cpu.dec ? 10 : 16;
|
||||
|
||||
while (len--) {
|
||||
if (*dest >= base) *dest &= 7;
|
||||
*dest += *src + c;
|
||||
if (*dest >= base) {
|
||||
*dest -= base;
|
||||
c = 1;
|
||||
} else {
|
||||
c = 0;
|
||||
}
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
cpu.carry = c ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static __inline void alu_sub(byte *dest, byte *src, int len)
|
||||
{
|
||||
byte c = 0;
|
||||
byte base = cpu.dec ? 10 : 16;
|
||||
|
||||
while (len--) {
|
||||
*dest -= *src + c;
|
||||
if (*dest & 0xF0) {
|
||||
*dest += base;
|
||||
c = 1;
|
||||
} else {
|
||||
c = 0;
|
||||
}
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
cpu.carry = c ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static __inline void alu_sub2(byte *dest, byte *src, int len)
|
||||
{
|
||||
byte c = 0;
|
||||
byte base = cpu.dec ? 10 : 16;
|
||||
|
||||
while (len--) {
|
||||
*dest = *src - (*dest + c);
|
||||
if (*dest & 0xF0) {
|
||||
*dest += base;
|
||||
c = 1;
|
||||
} else {
|
||||
c = 0;
|
||||
}
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
cpu.carry = c ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static __inline void alu_add_con(byte *reg, byte con, int i, int len)
|
||||
{
|
||||
reg[i] += con;
|
||||
while (len--) {
|
||||
reg[i]++;
|
||||
if (!(reg[i] & 0xF0)) {
|
||||
cpu.carry = FALSE;
|
||||
return;
|
||||
}
|
||||
reg[i] -= 16;
|
||||
i = (i + 1) & 0xF;
|
||||
}
|
||||
cpu.carry = TRUE;
|
||||
}
|
||||
|
||||
static __inline void alu_sub_con(byte *reg, byte con, int i, int len)
|
||||
{
|
||||
reg[i] -= con;
|
||||
while (len--) {
|
||||
reg[i]--;
|
||||
if (!(reg[i] & 0xF0)) {
|
||||
cpu.carry = FALSE;
|
||||
return;
|
||||
}
|
||||
reg[i] += 16;
|
||||
i = (i + 1) & 0xF;
|
||||
}
|
||||
cpu.carry = TRUE;
|
||||
}
|
||||
|
||||
static __inline void alu_inc(byte *reg, int len)
|
||||
{
|
||||
if (cpu.dec) {
|
||||
byte c = 1;
|
||||
while (len--) {
|
||||
if (*reg >= 10) *reg &= 7;
|
||||
*reg += c;
|
||||
if (*reg >= 10) {
|
||||
*reg -= 10;
|
||||
c = 1;
|
||||
} else {
|
||||
c = 0;
|
||||
}
|
||||
reg++;
|
||||
}
|
||||
cpu.carry = c ? TRUE : FALSE;
|
||||
} else {
|
||||
while (len--) {
|
||||
(*reg)++;
|
||||
if (!(*reg & 0xF0)) {
|
||||
cpu.carry = FALSE;
|
||||
return;
|
||||
}
|
||||
*reg -= 16;
|
||||
reg++;
|
||||
}
|
||||
cpu.carry = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void alu_dec(byte *reg, int len)
|
||||
{
|
||||
byte base = cpu.dec ? 10 : 16;
|
||||
|
||||
while (len--) {
|
||||
(*reg)--;
|
||||
if (!(*reg & 0xF0)) {
|
||||
cpu.carry = FALSE;
|
||||
return;
|
||||
}
|
||||
*reg += base;
|
||||
reg++;
|
||||
}
|
||||
cpu.carry = TRUE;
|
||||
}
|
||||
|
||||
static __inline void alu_neg(byte *reg, int len)
|
||||
{
|
||||
byte base = cpu.dec ? 10 : 16;
|
||||
|
||||
while (len && *reg == 0) {
|
||||
reg++;
|
||||
len--;
|
||||
}
|
||||
cpu.carry = len ? TRUE : FALSE;
|
||||
if (cpu.carry) {
|
||||
*reg = base - *reg;
|
||||
if (*reg & 0xF0) *reg &= 7;
|
||||
reg++;
|
||||
len--;
|
||||
base--;
|
||||
while (len--) {
|
||||
*reg = base - *reg;
|
||||
if (*reg & 0xF0) *reg &= 7;
|
||||
reg++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void alu_not(byte *reg, int len)
|
||||
{
|
||||
byte base = cpu.dec ? 9 : 15;
|
||||
|
||||
while (len--) {
|
||||
*reg = base - *reg;
|
||||
if (*reg & 0xF0) *reg &= 7;
|
||||
reg++;
|
||||
}
|
||||
cpu.carry = FALSE;
|
||||
}
|
||||
|
||||
static __inline void alu_and(byte *dest, byte *src, int len)
|
||||
{
|
||||
while (len--) {
|
||||
*dest++ &= *src++;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void alu_or(byte *dest, byte *src, int len)
|
||||
{
|
||||
while (len--) {
|
||||
*dest++ |= *src++;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void alu_sl(byte *reg, int len)
|
||||
{
|
||||
while (--len) {
|
||||
reg[len] = reg[len-1];
|
||||
}
|
||||
reg[0] = 0;
|
||||
}
|
||||
|
||||
static __inline void alu_slc(byte *reg, int len)
|
||||
{
|
||||
byte tmp = reg[len-1];
|
||||
|
||||
while (--len) {
|
||||
reg[len] = reg[len-1];
|
||||
}
|
||||
reg[0] = tmp;
|
||||
}
|
||||
|
||||
static __inline void alu_sr(byte *reg, int len)
|
||||
{
|
||||
if (reg[0]) cpu.hst |= HST_SB;
|
||||
|
||||
while (--len) {
|
||||
reg[0] = reg[1];
|
||||
reg++;
|
||||
}
|
||||
reg[0] = 0;
|
||||
}
|
||||
|
||||
static __inline void alu_src(byte *reg, int len)
|
||||
{
|
||||
byte tmp = reg[0];
|
||||
|
||||
while (--len) {
|
||||
reg[0] = reg[1];
|
||||
reg++;
|
||||
}
|
||||
reg[0] = tmp;
|
||||
}
|
||||
|
||||
static __inline void alu_srb(byte *reg, int len)
|
||||
{
|
||||
if (*reg & 1) cpu.hst |= HST_SB;
|
||||
|
||||
while (--len) {
|
||||
*reg >>= 1;
|
||||
if (reg[1] & 1) *reg |= 8;
|
||||
reg++;
|
||||
}
|
||||
*reg >>= 1;
|
||||
}
|
||||
|
||||
#endif
|
119
src/pabout.c
Normal file
119
src/pabout.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "color.h"
|
||||
#include "gui.h"
|
||||
#include "pabout.h"
|
||||
|
||||
static BITMAP *about_bmp;
|
||||
|
||||
static char *about_line[] = {
|
||||
"C / ",
|
||||
"C /__ ___ ___ ____ ",
|
||||
"C / / / / /__/ / / / / /",
|
||||
"C/ / /__/ /__ / / /__/ ",
|
||||
"C / ",
|
||||
"C / version 0.9.0 ",
|
||||
"P",
|
||||
" Copyright 2002 Daniel Nilsson",
|
||||
"P",
|
||||
"JHpemu is free software; you can",
|
||||
"Jredistribute it and/or modify it under",
|
||||
"Jthe terms of the GNU General Public",
|
||||
"JLicense as published by the Free Software",
|
||||
"JFoundation; either version 2 of the",
|
||||
"JLicense, or (at your option) any later",
|
||||
"Jversion.",
|
||||
"P",
|
||||
"JHpemu is distributed in the hope that it",
|
||||
"Jwill be useful, but WITHOUT ANY WARRANTY;",
|
||||
"Jwithout even the implied warranty of",
|
||||
"JMERCHANTABILITY or FITNESS FOR A",
|
||||
"JPARTICULAR PURPOSE. See the GNU General",
|
||||
"JPublic License for more details.",
|
||||
"P",
|
||||
"JYou should have received a copy of the",
|
||||
"JGNU General Public License along with",
|
||||
"Jhpemu; if not, write to the Free Software",
|
||||
"JFoundation, Inc., 59 Temple Place,",
|
||||
"JSuite 330, Boston, MA 02111-1307 USA",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void draw_about(void)
|
||||
{
|
||||
int i, y;
|
||||
|
||||
text_mode(color[C_PANEL_BACK]);
|
||||
|
||||
acquire_bitmap(about_bmp);
|
||||
scare_mouse();
|
||||
|
||||
y = 10;
|
||||
for (i = 0; about_line[i]; i++) {
|
||||
switch (about_line[i][0]) {
|
||||
case 'C':
|
||||
textout_centre(about_bmp, font, about_line[i]+1, 170, y, color[C_PANEL_TEXT]);
|
||||
break;
|
||||
case 'J':
|
||||
textout_justify(about_bmp, font, about_line[i]+1, 10, 330, y, 150, color[C_PANEL_TEXT]);
|
||||
break;
|
||||
case 'P':
|
||||
y += 5;
|
||||
break;
|
||||
default:
|
||||
textout(about_bmp, font, about_line[i]+1, 10, y, color[C_PANEL_TEXT]);
|
||||
break;
|
||||
}
|
||||
y += 10;
|
||||
}
|
||||
|
||||
unscare_mouse();
|
||||
release_bitmap(about_bmp);
|
||||
}
|
||||
|
||||
void pabout_show(BITMAP *bmp)
|
||||
{
|
||||
about_bmp = bmp;
|
||||
|
||||
clear_to_color(about_bmp, color[C_PANEL_BACK]);
|
||||
draw_about();
|
||||
}
|
||||
|
||||
void pabout_hide(void)
|
||||
{
|
||||
about_bmp = NULL;
|
||||
}
|
||||
|
||||
void pabout_down(int mx, int my, int mb)
|
||||
{
|
||||
}
|
||||
|
||||
void pabout_up(int mx, int my, int mb)
|
||||
{
|
||||
}
|
38
src/pabout.h
Normal file
38
src/pabout.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __PABOUT_H
|
||||
#define __PABOUT_H
|
||||
|
||||
#include <allegro.h>
|
||||
|
||||
void pabout_show(BITMAP *bmp);
|
||||
void pabout_hide(void);
|
||||
void pabout_down(int mx, int my, int mb);
|
||||
void pabout_up(int mx, int my, int mb);
|
||||
|
||||
#endif
|
210
src/pcalc.c
Normal file
210
src/pcalc.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "color.h"
|
||||
#include "display.h"
|
||||
#include "keyboard.h"
|
||||
#include "gui.h"
|
||||
#include "pcalc.h"
|
||||
|
||||
static BITMAP *calc_bmp;
|
||||
|
||||
static void dn00(void) { kbd_key_pressed (0, 0); }
|
||||
static void up00(boolean action) { kbd_key_released (0, 0); }
|
||||
static void dn01(void) { kbd_key_pressed (0, 1); }
|
||||
static void up01(boolean action) { kbd_key_released (0, 1); }
|
||||
static void dn02(void) { kbd_key_pressed (0, 2); }
|
||||
static void up02(boolean action) { kbd_key_released (0, 2); }
|
||||
static void dn03(void) { kbd_key_pressed (0, 3); }
|
||||
static void up03(boolean action) { kbd_key_released (0, 3); }
|
||||
static void dn04(void) { kbd_key_pressed (0, 4); }
|
||||
static void up04(boolean action) { kbd_key_released (0, 4); }
|
||||
static void dn10(void) { kbd_key_pressed (1, 0); }
|
||||
static void up10(boolean action) { kbd_key_released (1, 0); }
|
||||
static void dn11(void) { kbd_key_pressed (1, 1); }
|
||||
static void up11(boolean action) { kbd_key_released (1, 1); }
|
||||
static void dn12(void) { kbd_key_pressed (1, 2); }
|
||||
static void up12(boolean action) { kbd_key_released (1, 2); }
|
||||
static void dn13(void) { kbd_key_pressed (1, 3); }
|
||||
static void up13(boolean action) { kbd_key_released (1, 3); }
|
||||
static void dn14(void) { kbd_key_pressed (1, 4); }
|
||||
static void up14(boolean action) { kbd_key_released (1, 4); }
|
||||
static void dn15(void) { kbd_key_pressed (1, 5); }
|
||||
static void up15(boolean action) { kbd_key_released (1, 5); }
|
||||
static void dn20(void) { kbd_key_pressed (2, 0); }
|
||||
static void up20(boolean action) { kbd_key_released (2, 0); }
|
||||
static void dn21(void) { kbd_key_pressed (2, 1); }
|
||||
static void up21(boolean action) { kbd_key_released (2, 1); }
|
||||
static void dn22(void) { kbd_key_pressed (2, 2); }
|
||||
static void up22(boolean action) { kbd_key_released (2, 2); }
|
||||
static void dn23(void) { kbd_key_pressed (2, 3); }
|
||||
static void up23(boolean action) { kbd_key_released (2, 3); }
|
||||
static void dn24(void) { kbd_key_pressed (2, 4); }
|
||||
static void up24(boolean action) { kbd_key_released (2, 4); }
|
||||
static void dn25(void) { kbd_key_pressed (2, 5); }
|
||||
static void up25(boolean action) { kbd_key_released (2, 5); }
|
||||
static void dn30(void) { kbd_key_pressed (3, 0); }
|
||||
static void up30(boolean action) { kbd_key_released (3, 0); }
|
||||
static void dn31(void) { kbd_key_pressed (3, 1); }
|
||||
static void up31(boolean action) { kbd_key_released (3, 1); }
|
||||
static void dn32(void) { kbd_key_pressed (3, 2); }
|
||||
static void up32(boolean action) { kbd_key_released (3, 2); }
|
||||
static void dn33(void) { kbd_key_pressed (3, 3); }
|
||||
static void up33(boolean action) { kbd_key_released (3, 3); }
|
||||
static void dn34(void) { kbd_key_pressed (3, 4); }
|
||||
static void up34(boolean action) { kbd_key_released (3, 4); }
|
||||
static void dn35(void) { kbd_key_pressed (3, 5); }
|
||||
static void up35(boolean action) { kbd_key_released (3, 5); }
|
||||
static void dn40(void) { kbd_key_pressed (4, 0); }
|
||||
static void up40(boolean action) { kbd_key_released (4, 0); }
|
||||
static void dn41(void) { kbd_key_pressed (4, 1); }
|
||||
static void up41(boolean action) { kbd_key_released (4, 1); }
|
||||
static void dn42(void) { kbd_key_pressed (4, 2); }
|
||||
static void up42(boolean action) { kbd_key_released (4, 2); }
|
||||
static void dn43(void) { kbd_key_pressed (4, 3); }
|
||||
static void up43(boolean action) { kbd_key_released (4, 3); }
|
||||
static void dn44(void) { kbd_key_pressed (4, 4); }
|
||||
static void up44(boolean action) { kbd_key_released (4, 4); }
|
||||
static void dn50(void) { kbd_key_pressed (5, 0); }
|
||||
static void up50(boolean action) { kbd_key_released (5, 0); }
|
||||
static void dn51(void) { kbd_key_pressed (5, 1); }
|
||||
static void up51(boolean action) { kbd_key_released (5, 1); }
|
||||
static void dn52(void) { kbd_key_pressed (5, 2); }
|
||||
static void up52(boolean action) { kbd_key_released (5, 2); }
|
||||
static void dn53(void) { kbd_key_pressed (5, 3); }
|
||||
static void up53(boolean action) { kbd_key_released (5, 3); }
|
||||
static void dn54(void) { kbd_key_pressed (5, 4); }
|
||||
static void up54(boolean action) { kbd_key_released (5, 4); }
|
||||
static void dn60(void) { kbd_key_pressed (6, 0); }
|
||||
static void up60(boolean action) { kbd_key_released (6, 0); }
|
||||
static void dn61(void) { kbd_key_pressed (6, 1); }
|
||||
static void up61(boolean action) { kbd_key_released (6, 1); }
|
||||
static void dn62(void) { kbd_key_pressed (6, 2); }
|
||||
static void up62(boolean action) { kbd_key_released (6, 2); }
|
||||
static void dn63(void) { kbd_key_pressed (6, 3); }
|
||||
static void up63(boolean action) { kbd_key_released (6, 3); }
|
||||
static void dn64(void) { kbd_key_pressed (6, 4); }
|
||||
static void up64(boolean action) { kbd_key_released (6, 4); }
|
||||
static void dn70(void) { kbd_key_pressed (7, 0); }
|
||||
static void up70(boolean action) { kbd_key_released (7, 0); }
|
||||
static void dn71(void) { kbd_key_pressed (7, 1); }
|
||||
static void up71(boolean action) { kbd_key_released (7, 1); }
|
||||
static void dn72(void) { kbd_key_pressed (7, 2); }
|
||||
static void up72(boolean action) { kbd_key_released (7, 2); }
|
||||
static void dn73(void) { kbd_key_pressed (7, 3); }
|
||||
static void up73(boolean action) { kbd_key_released (7, 3); }
|
||||
static void dn74(void) { kbd_key_pressed (7, 4); }
|
||||
static void up74(boolean action) { kbd_key_released (7, 4); }
|
||||
static void dn80(void) { kbd_key_pressed (8, 0); }
|
||||
static void up80(boolean action) { kbd_key_released (8, 0); }
|
||||
static void dn81(void) { kbd_key_pressed (8, 1); }
|
||||
static void up81(boolean action) { kbd_key_released (8, 1); }
|
||||
static void dn82(void) { kbd_key_pressed (8, 2); }
|
||||
static void up82(boolean action) { kbd_key_released (8, 2); }
|
||||
static void dn83(void) { kbd_key_pressed (8, 3); }
|
||||
static void up83(boolean action) { kbd_key_released (8, 3); }
|
||||
static void dn84(void) { kbd_key_pressed (8, 4); }
|
||||
static void up84(boolean action) { kbd_key_released (8, 4); }
|
||||
static void dnON(void) { kbd_on_pressed (); }
|
||||
static void upON(boolean action) { kbd_on_released (); }
|
||||
|
||||
static Button calc_buttons[] = {
|
||||
{ 5, 160, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "", dn14, up14 },
|
||||
{ 49, 160, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "", dn84, up84 },
|
||||
{ 93, 160, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "", dn83, up83 },
|
||||
{ 137, 160, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "", dn82, up82 },
|
||||
{ 181, 160, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "", dn81, up81 },
|
||||
{ 225, 160, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "", dn80, up80 },
|
||||
{ 5, 184, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "MTH", dn24, up24 },
|
||||
{ 49, 184, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "PRG", dn74, up74 },
|
||||
{ 93, 184, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "CST", dn73, up73 },
|
||||
{ 137, 184, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "VAR", dn72, up72 },
|
||||
{ 181, 184, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "^", dn71, up71 },
|
||||
{ 225, 184, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "NXT", dn70, up70 },
|
||||
{ 5, 208, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "'", dn04, up04 },
|
||||
{ 49, 208, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "STO", dn64, up64 },
|
||||
{ 93, 208, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "EVAL", dn63, up63 },
|
||||
{ 137, 208, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "<", dn62, up62 },
|
||||
{ 181, 208, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "v", dn61, up61 },
|
||||
{ 225, 208, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, ">", dn60, up60 },
|
||||
{ 5, 232, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "SIN", dn34, up34 },
|
||||
{ 49, 232, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "COS", dn54, up54 },
|
||||
{ 93, 232, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "TAN", dn53, up53 },
|
||||
{ 137, 232, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "/x", dn52, up52 },
|
||||
{ 181, 232, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "yx", dn51, up51 },
|
||||
{ 225, 232, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "1/x", dn50, up50 },
|
||||
{ 5, 256, 84, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "ENTER",dn44, up44 },
|
||||
{ 93, 256, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "+/-", dn43, up43 },
|
||||
{ 137, 256, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "EEX", dn42, up42 },
|
||||
{ 181, 256, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "DEL", dn41, up41 },
|
||||
{ 225, 256, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "<-", dn40, up40 },
|
||||
{ 5, 280, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "a", dn35, up35 },
|
||||
{ 49, 280, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "7", dn33, up33 },
|
||||
{ 104, 280, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "8", dn32, up32 },
|
||||
{ 159, 280, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "9", dn31, up31 },
|
||||
{ 214, 280, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "/", dn30, up30 },
|
||||
{ 5, 304, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "<-", dn25, up25 },
|
||||
{ 49, 304, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "4", dn23, up23 },
|
||||
{ 104, 304, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "5", dn22, up22 },
|
||||
{ 159, 304, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "6", dn21, up21 },
|
||||
{ 214, 304, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "X", dn20, up20 },
|
||||
{ 5, 328, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "->", dn15, up15 },
|
||||
{ 49, 328, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "1", dn13, up13 },
|
||||
{ 104, 328, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "2", dn12, up12 },
|
||||
{ 159, 328, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "3", dn11, up11 },
|
||||
{ 214, 328, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "-", dn10, up10 },
|
||||
{ 5, 352, 40, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "ON", dnON, upON },
|
||||
{ 49, 352, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "0", dn03, up03 },
|
||||
{ 104, 352, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, ".", dn02, up02 },
|
||||
{ 159, 352, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "SPC", dn01, up01 },
|
||||
{ 214, 352, 51, 20, BUTTON_B1RELEASE | BUTTON_B2TOGGLE, "+", dn00, up00 },
|
||||
{ 0, 0, 0, 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
void pcalc_show(BITMAP *bmp)
|
||||
{
|
||||
calc_bmp = bmp;
|
||||
|
||||
clear_to_color(calc_bmp, color[C_PANEL_BACK]);
|
||||
button_draw_all(calc_bmp, calc_buttons);
|
||||
}
|
||||
|
||||
void pcalc_hide(void)
|
||||
{
|
||||
calc_bmp = NULL;
|
||||
}
|
||||
|
||||
void pcalc_down(int mx, int my, int mb)
|
||||
{
|
||||
button_mouse_down(calc_bmp, calc_buttons, mx, my, mb);
|
||||
}
|
||||
|
||||
void pcalc_up(int mx, int my, int mb)
|
||||
{
|
||||
button_mouse_up(calc_bmp, calc_buttons, mx, my, mb);
|
||||
}
|
38
src/pcalc.h
Normal file
38
src/pcalc.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __PCALC_H
|
||||
#define __PCALC_H
|
||||
|
||||
#include <allegro.h>
|
||||
|
||||
void pcalc_show(BITMAP *bmp);
|
||||
void pcalc_hide(void);
|
||||
void pcalc_down(int mx, int my, int mb);
|
||||
void pcalc_up(int mx, int my, int mb);
|
||||
|
||||
#endif
|
267
src/pdebug.c
Normal file
267
src/pdebug.c
Normal file
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "types.h"
|
||||
#include "emulator.h"
|
||||
#include "cpu.h"
|
||||
#include "bus.h"
|
||||
#include "disasm.h"
|
||||
#include "color.h"
|
||||
#include "gui.h"
|
||||
#include "pdebug.h"
|
||||
|
||||
static void run_up(boolean action);
|
||||
static void break_up(boolean action);
|
||||
static void step_up(boolean action);
|
||||
|
||||
static Button debug_buttons[] = {
|
||||
{ 0, 0, 79, 20, BUTTON_B1RELEASE, "Break", NULL, break_up },
|
||||
{ 80, 0, 79, 20, BUTTON_B1RELEASE, "Run", NULL, run_up },
|
||||
{ 160, 0, 79, 20, BUTTON_B1RELEASE, "Step", NULL, step_up },
|
||||
{ 0, 0, 0, 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
#define BREAK_BUTTON 0
|
||||
#define RUN_BUTTON 1
|
||||
#define STEP_BUTTON 2
|
||||
|
||||
static BITMAP *debug_bmp;
|
||||
|
||||
static void update_buttons(void)
|
||||
{
|
||||
if (emulator_get_state() == EMULATOR_STOP) {
|
||||
if (debug_buttons[RUN_BUTTON].flags & BUTTON_DISABLED) {
|
||||
debug_buttons[RUN_BUTTON].flags &= ~BUTTON_DISABLED;
|
||||
if (debug_bmp) button_draw(debug_bmp, debug_buttons + RUN_BUTTON);
|
||||
}
|
||||
if (!(debug_buttons[BREAK_BUTTON].flags & BUTTON_DISABLED)) {
|
||||
debug_buttons[BREAK_BUTTON].flags |= BUTTON_DISABLED;
|
||||
if (debug_bmp) button_draw(debug_bmp, debug_buttons + BREAK_BUTTON);
|
||||
}
|
||||
if (debug_buttons[STEP_BUTTON].flags & BUTTON_DISABLED) {
|
||||
debug_buttons[STEP_BUTTON].flags &= ~BUTTON_DISABLED;
|
||||
if (debug_bmp) button_draw(debug_bmp, debug_buttons + STEP_BUTTON);
|
||||
}
|
||||
} else {
|
||||
if (!(debug_buttons[RUN_BUTTON].flags & BUTTON_DISABLED)) {
|
||||
debug_buttons[RUN_BUTTON].flags |= BUTTON_DISABLED;
|
||||
if (debug_bmp) button_draw(debug_bmp, debug_buttons + RUN_BUTTON);
|
||||
}
|
||||
if (debug_buttons[BREAK_BUTTON].flags & BUTTON_DISABLED) {
|
||||
debug_buttons[BREAK_BUTTON].flags &= ~BUTTON_DISABLED;
|
||||
if (debug_bmp) button_draw(debug_bmp, debug_buttons + BREAK_BUTTON);
|
||||
}
|
||||
if (!(debug_buttons[STEP_BUTTON].flags & BUTTON_DISABLED)) {
|
||||
debug_buttons[STEP_BUTTON].flags |= BUTTON_DISABLED;
|
||||
if (debug_bmp) button_draw(debug_bmp, debug_buttons + STEP_BUTTON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void run_up(boolean action)
|
||||
{
|
||||
if (action) {
|
||||
emulator_set_state(EMULATOR_RUN);
|
||||
}
|
||||
}
|
||||
|
||||
static void break_up(boolean action)
|
||||
{
|
||||
if (action) {
|
||||
emulator_set_state(EMULATOR_STOP);
|
||||
}
|
||||
}
|
||||
|
||||
static void step_up(boolean action)
|
||||
{
|
||||
if (action) {
|
||||
emulator_set_state(EMULATOR_STEP);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_cpu(void)
|
||||
{
|
||||
int c1 = color[C_PANEL_TEXT];
|
||||
int c2 = color[C_PANEL_DISABLED];
|
||||
int i;
|
||||
char *tmp;
|
||||
|
||||
if (!debug_bmp) {
|
||||
return;
|
||||
}
|
||||
|
||||
text_mode(color[C_PANEL_BACK]);
|
||||
|
||||
acquire_bitmap(debug_bmp);
|
||||
scare_mouse();
|
||||
|
||||
tmp = disassemble(bus_fast_peek(NULL, cpu.pc, NULL));
|
||||
textprintf(debug_bmp, font, 10, 30, c1, "PC = #%05X %-24s", (int) cpu.pc, tmp);
|
||||
|
||||
textprintf(debug_bmp, font, 10, 50, c1, "A = #%s", nib_to_hex_rev(cpu.reg[A], 16));
|
||||
textprintf(debug_bmp, font, 10, 60, c1, "B = #%s", nib_to_hex_rev(cpu.reg[B], 16));
|
||||
textprintf(debug_bmp, font, 10, 70, c1, "C = #%s", nib_to_hex_rev(cpu.reg[C], 16));
|
||||
textprintf(debug_bmp, font, 10, 80, c1, "D = #%s", nib_to_hex_rev(cpu.reg[D], 16));
|
||||
textprintf(debug_bmp, font, 58, 90, c2, "%*c%*c", (int) 16-cpu.p, 'P', (int) cpu.p+1, '\0');
|
||||
textprintf(debug_bmp, font, 10, 100, c1, "R0 = #%s", nib_to_hex_rev(cpu.reg_r[0], 16));
|
||||
textprintf(debug_bmp, font, 10, 110, c1, "R1 = #%s", nib_to_hex_rev(cpu.reg_r[1], 16));
|
||||
textprintf(debug_bmp, font, 10, 120, c1, "R2 = #%s", nib_to_hex_rev(cpu.reg_r[2], 16));
|
||||
textprintf(debug_bmp, font, 10, 130, c1, "R3 = #%s", nib_to_hex_rev(cpu.reg_r[3], 16));
|
||||
textprintf(debug_bmp, font, 10, 140, c1, "R4 = #%s", nib_to_hex_rev(cpu.reg_r[4], 16));
|
||||
|
||||
tmp = nib_to_hex(bus_fast_peek(NULL, cpu.d[0], NULL), 16);
|
||||
textprintf(debug_bmp, font, 10, 160, c1, "D0 = #%05X (%s)", (int) cpu.d[0], tmp);
|
||||
tmp = nib_to_hex(bus_fast_peek(NULL, cpu.d[1], NULL), 16);
|
||||
textprintf(debug_bmp, font, 10, 170, c1, "D1 = #%05X (%s)", (int) cpu.d[1], tmp);
|
||||
|
||||
textout(debug_bmp, font, "RSTK", 10, 190, c1);
|
||||
for (i = 0; i < 8; i++) {
|
||||
textprintf(debug_bmp, font, 50, 190+i*10, c1, "#%05X", (int) cpu.rstk[(cpu.rstk_ptr+i)&7]);
|
||||
}
|
||||
|
||||
textprintf(debug_bmp, font, 200, 50, c1, "P = #%X", (int) cpu.p);
|
||||
|
||||
textprintf(debug_bmp, font, 200, 70, c1, "OUT = #%s", nib_to_hex_rev(cpu.out, 3));
|
||||
textprintf(debug_bmp, font, 200, 80, c1, "IN = #%s", nib_to_hex_rev(cpu.in, 4));
|
||||
|
||||
textprintf(debug_bmp, font, 200, 100, c1, "ST = #%s", nib_to_hex_rev(cpu.st, 4));
|
||||
|
||||
textout(debug_bmp, font, "MP", 200, 120, (cpu.hst & 0x8) ? c1 : c2);
|
||||
textout(debug_bmp, font, "SR", 224, 120, (cpu.hst & 0x4) ? c1 : c2);
|
||||
textout(debug_bmp, font, "SB", 248, 120, (cpu.hst & 0x2) ? c1 : c2);
|
||||
textout(debug_bmp, font, "XM", 272, 120, (cpu.hst & 0x1) ? c1 : c2);
|
||||
|
||||
textout(debug_bmp, font, "CARRY", 200, 130, cpu.carry ? c1 : c2);
|
||||
textout(debug_bmp, font, cpu.dec ? "DEC" : "HEX", 200, 140, c1);
|
||||
|
||||
textout(debug_bmp, font, "SHUTDOWN", 10, 280, cpu.shutdown ? c1 : c2);
|
||||
textout(debug_bmp, font, "KEYSCAN", 90, 280, cpu.keyscan ? c1 : c2);
|
||||
textout(debug_bmp, font, "INTE", 170, 280, cpu.inte ? c1 : c2);
|
||||
textout(debug_bmp, font, "KEYINTP", 250, 280, cpu.keyintp ? c1 : c2);
|
||||
|
||||
textout(debug_bmp, font, "HDWREG RAM CE1 CE2 NCE3", 58, 310, c1);
|
||||
textout(debug_bmp, font, "Mask", 10, 320, c1);
|
||||
textout(debug_bmp, font, "-----", 58, 320, c1);
|
||||
if (bus_info.ram_sz_cfg) {
|
||||
textprintf(debug_bmp, font, 114, 320, c1, "%05X", bus_info.ram_size);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 114, 320, c1);
|
||||
}
|
||||
if (bus_info.ce1_sz_cfg) {
|
||||
textprintf(debug_bmp, font, 170, 320, c1, "%05X", bus_info.ce1_size);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 170, 320, c1);
|
||||
}
|
||||
if (bus_info.ce2_sz_cfg) {
|
||||
textprintf(debug_bmp, font, 226, 320, c1, "%05X", bus_info.ce2_size);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 226, 320, c1);
|
||||
}
|
||||
if (bus_info.nce3_sz_cfg) {
|
||||
textprintf(debug_bmp, font, 282, 320, c1, "%05X", bus_info.nce3_size);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 282, 320, c1);
|
||||
}
|
||||
textout(debug_bmp, font, "Base", 10, 330, c1);
|
||||
if (bus_info.hdw_cfg) {
|
||||
textprintf(debug_bmp, font, 58, 330, c1, "%05X", bus_info.hdw_base);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 58, 330, c1);
|
||||
}
|
||||
if (bus_info.ram_cfg) {
|
||||
textprintf(debug_bmp, font, 114, 330, c1, "%05X", bus_info.ram_base);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 114, 330, c1);
|
||||
}
|
||||
if (bus_info.ce1_cfg) {
|
||||
textprintf(debug_bmp, font, 170, 330, c1, "%05X", bus_info.ce1_base);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 170, 330, c1);
|
||||
}
|
||||
if (bus_info.ce2_cfg) {
|
||||
textprintf(debug_bmp, font, 226, 330, c1, "%05X", bus_info.ce2_base);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 226, 330, c1);
|
||||
}
|
||||
if (bus_info.nce3_cfg) {
|
||||
textprintf(debug_bmp, font, 282, 330, c1, "%05X", bus_info.nce3_base);
|
||||
} else {
|
||||
textout(debug_bmp, font, "-----", 282, 330, c1);
|
||||
}
|
||||
|
||||
textprintf(debug_bmp, font, 10, 380, c1, "Instruction count = %u", cpu.inst_cnt);
|
||||
textprintf(debug_bmp, font, 10, 390, c1, "Cycle count = %u", cpu.cycles);
|
||||
|
||||
unscare_mouse();
|
||||
release_bitmap(debug_bmp);
|
||||
}
|
||||
|
||||
void pdebug_draw_true_speed(dword speed)
|
||||
{
|
||||
if (!debug_bmp) {
|
||||
return;
|
||||
}
|
||||
text_mode(color[C_PANEL_BACK]);
|
||||
acquire_bitmap(debug_bmp);
|
||||
scare_mouse();
|
||||
textprintf(debug_bmp, font, 10, 410, color[C_PANEL_TEXT], "True speed: %10u Hz", speed);
|
||||
unscare_mouse();
|
||||
release_bitmap(debug_bmp);
|
||||
}
|
||||
|
||||
void pdebug_state_changed(void)
|
||||
{
|
||||
update_buttons();
|
||||
draw_cpu();
|
||||
}
|
||||
|
||||
void pdebug_show(BITMAP *bmp)
|
||||
{
|
||||
update_buttons();
|
||||
|
||||
debug_bmp = bmp;
|
||||
|
||||
clear_to_color(debug_bmp, color[C_PANEL_BACK]);
|
||||
button_draw_all(debug_bmp, debug_buttons);
|
||||
draw_cpu();
|
||||
}
|
||||
|
||||
void pdebug_hide(void)
|
||||
{
|
||||
debug_bmp = NULL;
|
||||
}
|
||||
|
||||
void pdebug_down(int mx, int my, int mb)
|
||||
{
|
||||
button_mouse_down(debug_bmp, debug_buttons, mx, my, mb);
|
||||
}
|
||||
|
||||
void pdebug_up(int mx, int my, int mb)
|
||||
{
|
||||
button_mouse_up(debug_bmp, debug_buttons, mx, my, mb);
|
||||
}
|
42
src/pdebug.h
Normal file
42
src/pdebug.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __PDEBUG_H
|
||||
#define __PDEBUG_H
|
||||
|
||||
#include <allegro.h>
|
||||
#include "types.h"
|
||||
|
||||
void pdebug_state_changed(void);
|
||||
void pdebug_draw_true_speed(dword speed);
|
||||
|
||||
void pdebug_show(BITMAP *bmp);
|
||||
void pdebug_hide(void);
|
||||
void pdebug_down(int mx, int my, int mb);
|
||||
void pdebug_up(int mx, int my, int mb);
|
||||
|
||||
#endif
|
134
src/pfiles.c
Normal file
134
src/pfiles.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include <string.h>
|
||||
#include "color.h"
|
||||
#include "gui.h"
|
||||
#include "rpl.h"
|
||||
#include "pfiles.h"
|
||||
|
||||
static void load_up(boolean action);
|
||||
|
||||
static Button files_buttons[] = {
|
||||
{ 0, 0, 79, 20, BUTTON_B1RELEASE, "Load", NULL, load_up },
|
||||
{ 0, 0, 0, 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static BITMAP *files_bmp;
|
||||
|
||||
static void load_file(char *name)
|
||||
{
|
||||
PACKFILE *f;
|
||||
byte *buf;
|
||||
byte *obj;
|
||||
int i, j;
|
||||
int fsize;
|
||||
address size;
|
||||
|
||||
fsize = file_size(name);
|
||||
if (fsize < 11) // "PHPH48-X" + prologue (8 + 2.5)
|
||||
return;
|
||||
|
||||
buf = malloc(fsize);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
f = pack_fopen(name, "r");
|
||||
if (!f) {
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pack_fread(buf, fsize, f) != fsize) {
|
||||
free(buf);
|
||||
pack_fclose(f);
|
||||
return;
|
||||
}
|
||||
pack_fclose(f);
|
||||
|
||||
if (memcmp(buf, "HPHP48-", 7)) {
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
obj = malloc((fsize - 8) * 2);
|
||||
if (!obj) {
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 8, j = 0; i < fsize; i++) {
|
||||
obj[j++] = buf[i] & 0x0F;
|
||||
obj[j++] = (buf[i] >> 4) & 0x0F;
|
||||
}
|
||||
free(buf);
|
||||
|
||||
size = rpl_object_size(obj);
|
||||
if (size > (fsize - 8) * 2) {
|
||||
free(obj);
|
||||
return;
|
||||
}
|
||||
rpl_push_object(obj, size);
|
||||
free(obj);
|
||||
}
|
||||
|
||||
#define PATH_SIZE 1024
|
||||
|
||||
static void load_up(boolean action)
|
||||
{
|
||||
static char path[PATH_SIZE] = "";
|
||||
|
||||
if (action) {
|
||||
if (file_select_ex("Load Object", path, NULL, PATH_SIZE, 0, 0)) {
|
||||
load_file(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pfiles_show(BITMAP *bmp)
|
||||
{
|
||||
files_bmp = bmp;
|
||||
|
||||
clear_to_color(files_bmp, color[C_PANEL_BACK]);
|
||||
button_draw_all(files_bmp, files_buttons);
|
||||
}
|
||||
|
||||
void pfiles_hide(void)
|
||||
{
|
||||
files_bmp = NULL;
|
||||
}
|
||||
|
||||
void pfiles_down(int mx, int my, int mb)
|
||||
{
|
||||
button_mouse_down(files_bmp, files_buttons, mx, my, mb);
|
||||
}
|
||||
|
||||
void pfiles_up(int mx, int my, int mb)
|
||||
{
|
||||
button_mouse_up(files_bmp, files_buttons, mx, my, mb);
|
||||
}
|
38
src/pfiles.h
Normal file
38
src/pfiles.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __PFILES_H
|
||||
#define __PFILES_H
|
||||
|
||||
#include <allegro.h>
|
||||
|
||||
void pfiles_show(BITMAP *bmp);
|
||||
void pfiles_hide(void);
|
||||
void pfiles_down(int mx, int my, int mb);
|
||||
void pfiles_up(int mx, int my, int mb);
|
||||
|
||||
#endif
|
124
src/pmenu.c
Normal file
124
src/pmenu.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "emulator.h"
|
||||
#include "color.h"
|
||||
#include "gui.h"
|
||||
#include "pmenu.h"
|
||||
|
||||
static void exit_up(boolean action);
|
||||
static void debug_up(boolean action);
|
||||
static void files_up(boolean action);
|
||||
static void about_up(boolean action);
|
||||
|
||||
static Button menu_buttons[] = {
|
||||
{ 0, 0, 79, 20, BUTTON_B1RELEASE, "Exit", NULL, exit_up },
|
||||
{ 80, 0, 79, 20, BUTTON_B1RELEASE, "Debug", NULL, debug_up },
|
||||
{ 160, 0, 79, 20, BUTTON_B1RELEASE, "Files", NULL, files_up },
|
||||
{ 240, 0, 79, 20, BUTTON_DISABLED | BUTTON_B1RELEASE, "About", NULL, about_up },
|
||||
{ 0, 0, 0, 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
enum MenuButtons {
|
||||
MENU_EXIT,
|
||||
MENU_DEBUG,
|
||||
MENU_FILES,
|
||||
MENU_ABOUT,
|
||||
MENU_COUNT
|
||||
};
|
||||
|
||||
static BITMAP *menu_bmp;
|
||||
|
||||
static void exit_up(boolean action)
|
||||
{
|
||||
if (action) {
|
||||
please_exit = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_up(boolean action)
|
||||
{
|
||||
if (action) {
|
||||
menu_buttons[MENU_DEBUG].flags |= BUTTON_DISABLED;
|
||||
menu_buttons[MENU_FILES].flags &= ~BUTTON_DISABLED;
|
||||
menu_buttons[MENU_ABOUT].flags &= ~BUTTON_DISABLED;
|
||||
button_draw_all(menu_bmp, menu_buttons);
|
||||
gui_hide_panel(PANEL_FILES);
|
||||
gui_hide_panel(PANEL_ABOUT);
|
||||
gui_show_panel(PANEL_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
static void files_up(boolean action)
|
||||
{
|
||||
if (action) {
|
||||
menu_buttons[MENU_DEBUG].flags &= ~BUTTON_DISABLED;
|
||||
menu_buttons[MENU_FILES].flags |= BUTTON_DISABLED;
|
||||
menu_buttons[MENU_ABOUT].flags &= ~BUTTON_DISABLED;
|
||||
button_draw_all(menu_bmp, menu_buttons);
|
||||
gui_hide_panel(PANEL_DEBUG);
|
||||
gui_hide_panel(PANEL_ABOUT);
|
||||
gui_show_panel(PANEL_FILES);
|
||||
}
|
||||
}
|
||||
|
||||
static void about_up(boolean action)
|
||||
{
|
||||
if (action) {
|
||||
menu_buttons[MENU_DEBUG].flags &= ~BUTTON_DISABLED;
|
||||
menu_buttons[MENU_FILES].flags &= ~BUTTON_DISABLED;
|
||||
menu_buttons[MENU_ABOUT].flags |= BUTTON_DISABLED;
|
||||
button_draw_all(menu_bmp, menu_buttons);
|
||||
gui_hide_panel(PANEL_DEBUG);
|
||||
gui_hide_panel(PANEL_FILES);
|
||||
gui_show_panel(PANEL_ABOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void pmenu_show(BITMAP *bmp)
|
||||
{
|
||||
menu_bmp = bmp;
|
||||
|
||||
clear_to_color(menu_bmp, color[C_PANEL_BACK]);
|
||||
button_draw_all(menu_bmp, menu_buttons);
|
||||
}
|
||||
|
||||
void pmenu_hide(void)
|
||||
{
|
||||
menu_bmp = NULL;
|
||||
}
|
||||
|
||||
void pmenu_down(int mx, int my, int mb)
|
||||
{
|
||||
button_mouse_down(menu_bmp, menu_buttons, mx, my, mb);
|
||||
}
|
||||
|
||||
void pmenu_up(int mx, int my, int mb)
|
||||
{
|
||||
button_mouse_up(menu_bmp, menu_buttons, mx, my, mb);
|
||||
}
|
38
src/pmenu.h
Normal file
38
src/pmenu.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __PMENU_H
|
||||
#define __PMENU_H
|
||||
|
||||
#include <allegro.h>
|
||||
|
||||
void pmenu_show(BITMAP *bmp);
|
||||
void pmenu_hide(void);
|
||||
void pmenu_down(int mx, int my, int mb);
|
||||
void pmenu_up(int mx, int my, int mb);
|
||||
|
||||
#endif
|
115
src/ports.c
Normal file
115
src/ports.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "types.h"
|
||||
#include "bus.h"
|
||||
#include "ports.h"
|
||||
|
||||
static byte current_bank;
|
||||
static byte *port2;
|
||||
static address port2mask;
|
||||
|
||||
void ports_init(void)
|
||||
{
|
||||
// ce1 = bank switcher
|
||||
bus_info.ce1_data = NULL;
|
||||
bus_info.ce1_mask = 0x0007F;
|
||||
bus_info.ce1_r_o = TRUE;
|
||||
bus_info.ce1_bs = TRUE;
|
||||
|
||||
#if 1
|
||||
// ce2 = port1 (unplugged)
|
||||
bus_info.ce2_data = NULL;
|
||||
bus_info.ce2_mask = 0x00000;
|
||||
bus_info.ce2_r_o = TRUE;
|
||||
#else
|
||||
#define PORT1_SIZE (64*1024) // Nibbles
|
||||
// ce2 = port1 (plugged)
|
||||
bus_info.ce2_data = malloc(PORT1_SIZE);
|
||||
bus_info.ce2_mask = PORT1_SIZE-1;
|
||||
bus_info.ce2_r_o = FALSE;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// nce3 = port2 (unplugged)
|
||||
port2 = NULL;
|
||||
port2mask = 0x00000;
|
||||
bus_info.nce3_data = port2;
|
||||
bus_info.nce3_mask = port2mask & 0x3FFFF;
|
||||
bus_info.nce3_r_o = TRUE;
|
||||
#else
|
||||
#define PORT2_SIZE (512*1024) // Nibbles
|
||||
// nce3 = port2 (plugged)
|
||||
port2 = malloc(PORT2_SIZE);
|
||||
port2mask = PORT2_SIZE-1;
|
||||
bus_info.nce3_data = port2;
|
||||
bus_info.nce3_mask = port2mask & 0x3FFFF;
|
||||
bus_info.nce3_r_o = FALSE;
|
||||
#endif
|
||||
|
||||
bus_info.ben = FALSE;
|
||||
current_bank = 0;
|
||||
}
|
||||
|
||||
void ports_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ports_switch_bank(address adr)
|
||||
{
|
||||
boolean need_remap = FALSE;
|
||||
|
||||
if (current_bank != (((byte) adr >> 1) & 0x1F)) {
|
||||
current_bank = ((byte) adr >> 1) & 0x1F;
|
||||
if (port2) {
|
||||
bus_info.nce3_data = port2 + ((current_bank << 18) & port2mask);
|
||||
if (bus_info.nce3_cfg) {
|
||||
need_remap = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bus_info.ben != !(adr & 0x40)) {
|
||||
bus_info.ben = (adr & 0x40) ? TRUE : FALSE;
|
||||
if (bus_info.nce3_cfg) {
|
||||
need_remap = TRUE;
|
||||
}
|
||||
}
|
||||
if (need_remap) {
|
||||
bus_remap();
|
||||
}
|
||||
}
|
||||
|
||||
byte ports_card_detect(void)
|
||||
{
|
||||
byte x = 0;
|
||||
if (bus_info.nce3_data) x |= 0x1;
|
||||
if (bus_info.ce2_data) x |= 0x2;
|
||||
if (!bus_info.nce3_r_o) x |= 0x4;
|
||||
if (!bus_info.ce2_r_o) x |= 0x8;
|
||||
return x;
|
||||
}
|
38
src/ports.h
Normal file
38
src/ports.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __PORTS_H
|
||||
#define __PORTS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void ports_init(void);
|
||||
void ports_exit(void);
|
||||
void ports_switch_bank(address adr);
|
||||
byte ports_card_detect(void);
|
||||
|
||||
#endif
|
54
src/ram.c
Normal file
54
src/ram.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "bus.h"
|
||||
#include "ram.h"
|
||||
|
||||
static address ram_size = 256*1024; // in nibbles, not bytes!
|
||||
|
||||
void ram_init(void)
|
||||
{
|
||||
byte *buf;
|
||||
|
||||
buf = malloc(ram_size);
|
||||
if (!buf) {
|
||||
exit(0x20);
|
||||
}
|
||||
memset(buf, 0, ram_size);
|
||||
bus_info.ram_data = buf;
|
||||
bus_info.ram_mask = ram_size-1;
|
||||
}
|
||||
|
||||
void ram_exit(void)
|
||||
{
|
||||
free(bus_info.ram_data);
|
||||
bus_info.ram_data = NULL;
|
||||
bus_info.ram_mask = 0x00000;
|
||||
}
|
34
src/ram.h
Normal file
34
src/ram.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __RAM_H
|
||||
#define __RAM_H
|
||||
|
||||
void ram_init(void);
|
||||
void ram_exit(void);
|
||||
|
||||
#endif
|
84
src/rom.c
Normal file
84
src/rom.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <allegro.h>
|
||||
#include "types.h"
|
||||
#include "bus.h"
|
||||
#include "rom.h"
|
||||
|
||||
void rom_init(void)
|
||||
{
|
||||
int size;
|
||||
char *name = "hpemu.rom";
|
||||
byte *buf, *ptr1, *ptr2;
|
||||
PACKFILE *f;
|
||||
|
||||
size = file_size(name);
|
||||
if (!size) {
|
||||
exit(0x10);
|
||||
}
|
||||
if (size != 256*1024 && size != 512*1024 && size != 1024*1024) {
|
||||
exit (0x11);
|
||||
}
|
||||
buf = malloc(size);
|
||||
if (!buf) {
|
||||
exit(0x12);
|
||||
}
|
||||
f = pack_fopen(name, "r");
|
||||
if (!f) {
|
||||
exit(0x13);
|
||||
}
|
||||
if (pack_fread(buf, size, f) != size) {
|
||||
exit(0x14);
|
||||
}
|
||||
pack_fclose(f);
|
||||
if (buf[0] & 0xF0 || buf[1] & 0xF0) {
|
||||
if (size == 1024*1024) {
|
||||
exit(0x15);
|
||||
}
|
||||
buf = realloc(buf, size*2);
|
||||
if (!buf) {
|
||||
exit(0x16);
|
||||
}
|
||||
ptr1 = buf+size-1;
|
||||
size *= 2;
|
||||
ptr2 = buf+size-1;
|
||||
do {
|
||||
*(ptr2--) = (*ptr1 >> 4) & 0x0F;
|
||||
*(ptr2--) = *(ptr1--) & 0x0F;
|
||||
} while (ptr1 != ptr2);
|
||||
}
|
||||
bus_info.rom_data = buf;
|
||||
bus_info.rom_mask = size - 1;
|
||||
}
|
||||
|
||||
void rom_exit(void)
|
||||
{
|
||||
free(bus_info.rom_data);
|
||||
bus_info.rom_data = NULL;
|
||||
bus_info.rom_mask = 0x00000;
|
||||
}
|
34
src/rom.h
Normal file
34
src/rom.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ROM_H
|
||||
#define __ROM_H
|
||||
|
||||
void rom_init(void);
|
||||
void rom_exit(void);
|
||||
|
||||
#endif
|
199
src/rpl.c
Normal file
199
src/rpl.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "types.h"
|
||||
#include "bus.h"
|
||||
#include "opinline.h"
|
||||
#include "rpl.h"
|
||||
|
||||
#define TEMPOB 0x806E9
|
||||
#define TEMPTOP 0x806EE
|
||||
#define RSKTOP 0x806F3
|
||||
#define DSKTOP 0x806F8
|
||||
#define AVMEM 0x807ED
|
||||
#define INTRPPTR 0x8072F
|
||||
|
||||
int rpl_object_size(byte *obj)
|
||||
{
|
||||
int size;
|
||||
int prologue;
|
||||
int n;
|
||||
|
||||
prologue = nib_to_unsigned(obj, 5);
|
||||
|
||||
switch (prologue) {
|
||||
|
||||
case 0x0312B: size = 0; break; // SEMI
|
||||
case 0x029BF: size = 7; break; // Character
|
||||
case 0x02911: size = 10; break; // System binary integer
|
||||
case 0x02E92: size = 11; break; // XLIB name
|
||||
case 0x02BAA: size = 15; break; // Extended pointer
|
||||
case 0x02933: size = 21; break; // Real number
|
||||
case 0x02955: size = 26; break; // Long real
|
||||
case 0x02977: size = 37; break; // Complex number
|
||||
case 0x0299D: size = 47; break; // Long complex
|
||||
|
||||
case 0x02A2C: // String
|
||||
case 0x02A4E: // User binary integer
|
||||
case 0x02B1E: // Graphic object
|
||||
case 0x02DCC: // Code object
|
||||
case 0x02B88: // Library data
|
||||
case 0x029E8: // Array
|
||||
case 0x02B40: // Library
|
||||
case 0x02B62: // Backup
|
||||
case 0x02A0A: // Linked array
|
||||
size = 5 + nib_to_unsigned(obj+5, 5);
|
||||
break;
|
||||
|
||||
case 0x02E48: // Global name
|
||||
case 0x02E6D: // Local name
|
||||
case 0x02AFC: // Tagged object
|
||||
case 0x02ADA: // Unit object
|
||||
size = 7 + 2 * nib_to_unsigned(obj+5, 2);
|
||||
if (prologue == 0x02AFC) { // Tagged object
|
||||
size += rpl_object_size(obj + size);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02A74: // List
|
||||
case 0x02D9D: // RPL program
|
||||
case 0x02AB8: // Algebraic expression
|
||||
size = 5;
|
||||
n = 5;
|
||||
do {
|
||||
size += n;
|
||||
obj += n;
|
||||
n = rpl_object_size(obj);
|
||||
} while (n > 0);
|
||||
break;
|
||||
|
||||
case 0x02A96: // Directory
|
||||
n = nib_to_unsigned(obj+8, 5);
|
||||
if (n == 0) {
|
||||
size = 13;
|
||||
} else {
|
||||
size = 8 + n;
|
||||
size += 4 + 2 * nib_to_unsigned(obj + size, 2);
|
||||
size += rpl_object_size(obj + size);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
size = 5;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static address read_address(address adr)
|
||||
{
|
||||
byte buf[5];
|
||||
word ocrc;
|
||||
|
||||
ocrc = crc;
|
||||
bus_read(buf, adr, 5);
|
||||
crc = ocrc;
|
||||
|
||||
return nib_to_unsigned(buf, 5);
|
||||
}
|
||||
|
||||
static void write_address(address adr, address val)
|
||||
{
|
||||
byte buf[5];
|
||||
|
||||
unsigned_to_nib(buf, val, 5);
|
||||
bus_write(buf, adr, 5);
|
||||
}
|
||||
|
||||
static int moveup(address src, address dst, address cnt)
|
||||
{
|
||||
byte *buf = malloc(cnt * sizeof(byte));
|
||||
word ocrc;
|
||||
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
ocrc = crc;
|
||||
bus_read(buf, src, cnt);
|
||||
bus_write(buf, dst, cnt);
|
||||
crc = ocrc;
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
address rpl_make_temp(address size)
|
||||
{
|
||||
address temptop, rsktop, dsktop;
|
||||
|
||||
size += 6;
|
||||
|
||||
temptop = read_address(TEMPTOP);
|
||||
rsktop = read_address(RSKTOP);
|
||||
dsktop = read_address(DSKTOP);
|
||||
|
||||
if (rsktop + size > dsktop)
|
||||
return 0;
|
||||
|
||||
if (moveup(temptop, temptop + size, rsktop - temptop))
|
||||
return 0;
|
||||
|
||||
write_address(TEMPTOP, temptop + size);
|
||||
write_address(RSKTOP, rsktop + size);
|
||||
write_address(AVMEM, (dsktop - rsktop - size) / 5);
|
||||
write_address(temptop + size - 5, size);
|
||||
|
||||
return temptop + 1;
|
||||
}
|
||||
|
||||
void rpl_push(address adr)
|
||||
{
|
||||
address dsktop, avmem;
|
||||
|
||||
avmem = read_address(AVMEM);
|
||||
if (!avmem)
|
||||
return;
|
||||
write_address(AVMEM, avmem-1);
|
||||
|
||||
dsktop = read_address(DSKTOP);
|
||||
dsktop -= 5;
|
||||
write_address(dsktop, adr);
|
||||
write_address(DSKTOP, dsktop);
|
||||
}
|
||||
|
||||
int rpl_push_object(byte *obj, address size)
|
||||
{
|
||||
address adr;
|
||||
|
||||
adr = rpl_make_temp(size);
|
||||
if (!adr)
|
||||
return -1;
|
||||
|
||||
bus_write(obj, adr, size);
|
||||
rpl_push(adr);
|
||||
return 0;
|
||||
}
|
38
src/rpl.h
Normal file
38
src/rpl.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __RPL_H
|
||||
#define __RPL_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
int rpl_object_size(byte *obj);
|
||||
address rpl_make_temp(address size);
|
||||
void rpl_push(address adr);
|
||||
int rpl_push_object(byte *obj, address size);
|
||||
|
||||
#endif
|
95
src/timers.c
Normal file
95
src/timers.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "cpu.h"
|
||||
#include "timers.h"
|
||||
|
||||
#define TIMER1_EXTRA 0x1
|
||||
#define TIMER1_INT 0x2
|
||||
#define TIMER1_WAKE 0x4
|
||||
#define TIMER1_SRQ 0x8
|
||||
|
||||
#define TIMER_RUN 0x1
|
||||
#define TIMER2_INT 0x2
|
||||
#define TIMER2_WAKE 0x4
|
||||
#define TIMER2_SRQ 0x8
|
||||
|
||||
byte timer1_control;
|
||||
byte timer2_control;
|
||||
byte timer1_value;
|
||||
dword timer2_value;
|
||||
|
||||
void timer1_update(void)
|
||||
{
|
||||
if (timer2_control & TIMER_RUN) {
|
||||
timer1_value--;
|
||||
timer1_value &= 0xF;
|
||||
|
||||
if (timer1_value & 0x8) {
|
||||
if (timer1_control & TIMER1_WAKE) {
|
||||
timer1_control |= TIMER1_SRQ;
|
||||
if (cpu.shutdown) {
|
||||
cpu.shutdown = FALSE;
|
||||
timer1_control &= ~TIMER1_WAKE;
|
||||
}
|
||||
}
|
||||
if (timer1_control & TIMER1_INT) {
|
||||
timer1_control |= TIMER1_SRQ;
|
||||
if (!cpu.shutdown) {
|
||||
cpu_interrupt();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
timer1_control &= ~TIMER1_SRQ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void timer2_update(void)
|
||||
{
|
||||
if (timer2_control & TIMER_RUN) {
|
||||
timer2_value--;
|
||||
if (timer2_value & 0x80000000) {
|
||||
if (timer2_control & TIMER2_WAKE) {
|
||||
timer2_control |= TIMER2_SRQ;
|
||||
if (cpu.shutdown) {
|
||||
cpu.shutdown = 0;
|
||||
timer2_control &= ~TIMER2_WAKE;
|
||||
}
|
||||
}
|
||||
if (timer2_control & TIMER2_INT) {
|
||||
timer2_control |= TIMER2_SRQ;
|
||||
if (!cpu.shutdown) {
|
||||
cpu_interrupt();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
timer2_control &= ~TIMER2_SRQ;
|
||||
}
|
||||
}
|
||||
}
|
41
src/timers.h
Normal file
41
src/timers.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __TIMERS_H
|
||||
#define __TIMERS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern byte timer1_control;
|
||||
extern byte timer2_control;
|
||||
extern byte timer1_value;
|
||||
extern dword timer2_value;
|
||||
|
||||
void timer1_update(void);
|
||||
void timer2_update(void);
|
||||
|
||||
#endif
|
42
src/types.h
Normal file
42
src/types.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* /
|
||||
* /__ ___ ___ ____
|
||||
* / / / / /__/ / / / / /
|
||||
* / / /__/ /__ / / /__/
|
||||
* /
|
||||
* / version 0.9.0
|
||||
*
|
||||
* Copyright 2002 Daniel Nilsson
|
||||
*
|
||||
* This file is part of hpemu.
|
||||
*
|
||||
* Hpemu is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Hpemu 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 hpemu; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __TYPES_H
|
||||
#define __TYPES_H
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int dword;
|
||||
typedef signed int address;
|
||||
typedef char boolean;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE -1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue