mirror of
https://github.com/aufflick/kegs.git
synced 2025-01-28 03:36:54 +00:00
v0.91 sources and binaries from website
This commit is contained in:
parent
cf770f0a3d
commit
f913d80b03
@ -1,4 +1,61 @@
|
||||
|
||||
Changes in KEGS v0.91 since v0.90 (12/06/04)
|
||||
- Fixed serious bug in engine_c.c that could cause Finder file copies to
|
||||
silently corrupt data.
|
||||
- Virtual Modem support--modem appears on serial port, allows outgoing
|
||||
and incoming connections.
|
||||
- Sockets (and Virtual Modem) supported on Windows.
|
||||
- Fixed various reset bugs (where pressing Ctrl-Reset would cause infinite
|
||||
beeps, etc).
|
||||
- Allow user to select ROM file from config panel if not found.
|
||||
- Improved Mac OS X interface: Full Screen support and error dialogs.
|
||||
- Better floppy support by always having 5.25" read nearest track regardless
|
||||
of head position (supports Last Gladiator game bad crack by
|
||||
emulating other emulators).
|
||||
|
||||
Changes in KEGS v0.90 since v0.89 (10/19/04)
|
||||
- Make Keypad Joystick the default joystick emulation
|
||||
- Fix timezone calculation on Mac OS X for central time zone.
|
||||
- Fix handling of long paths in config panel, reported by David Scruffham.
|
||||
- Always call joystick_init at startup.
|
||||
- Fix F2 keymappings for X Windows, to fix some issue reported by
|
||||
David Wilson.
|
||||
- Fixed some documentation issues reported by David Wilson.
|
||||
- Fixed a bug in joystick_driver.c reported by Doug Mitton.
|
||||
- Add README.a2.compatibility to discuss known issues with programs.
|
||||
|
||||
Changes in KEGS v0.89 since v0.88 (10/17/04)
|
||||
- Make old mouse button presses disappear after .5 seconds.
|
||||
- Add Keypad Joystick, along with configuration menu choices to enable it.
|
||||
The keypad numbers move the joystick to the indicated direction,
|
||||
with chording allowing in-between values.
|
||||
The keypad '0' is button 0 and keypad '1' is button 1.
|
||||
- Also add jostick scaling factor and trim adjustment.
|
||||
- Allow user to increase keyboard and mouse scan rate to 240Hz from 60Hz
|
||||
for some better game response.
|
||||
|
||||
Changes in KEGS v0.88 since v0.87 (10/13/04)
|
||||
- Add configuration setting to debug halt on code red halts. Also add
|
||||
configuration mode (on by default) to shadow text page 2 on ROM 01,
|
||||
which is an enhancement over a real IIgs.
|
||||
- Handle mac binary header on images. Handle compressed .po images.
|
||||
- Fix refresh rate to 59.923Hz from 60Hz so that exactly 17030 1MHz cycles
|
||||
pass in one screen refresh period.
|
||||
- Enhance trace-to-file function to also write out data values stored using
|
||||
the Data_log info.
|
||||
- Debugger adds memory move and memory compare functions.
|
||||
- Support "floating bus" where reading certain $C0xx locations returns the
|
||||
current video data. This allows Bob Bishop's split-screen demos to
|
||||
run and enables Drol's between-level animations to work fully.
|
||||
|
||||
Changes in KEGS v0.87 since v0.86 (10/05/04)
|
||||
- Remove all of Jonathan Kalbfeld's and Gilles Tschopp's contributions.
|
||||
All of Solaris audio is removed.
|
||||
- Fix config screen not drawing correctly if emulator was currently displaying
|
||||
video page 2.
|
||||
- Fix STP instruction.
|
||||
- Fix mouse-joystick which was halving the Y dimension.
|
||||
|
||||
Changes in KEGS v0.86 since v0.85 (03/23/04)
|
||||
- Add patch for Solaris sound by Jonathan Kalbfeld.
|
||||
- Fix so that F4 enters config panel even while running Prosel-16
|
280
COPYING.txt
Normal file
280
COPYING.txt
Normal file
@ -0,0 +1,280 @@
|
||||
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
|
@ -4,8 +4,46 @@
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>2mg</string>
|
||||
<string>2MG</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>2mg.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Apple II 2MG Disk Image</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>a2mg</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>kegs</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>525.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>KEGS Configuration File</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>kegs</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>KEGSMAC</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>KEGSMAC</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>kegsicon.icns</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
@ -13,10 +51,14 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<string>KEGS</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<string>0.91</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>KEGSMAC version 0.91</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>KEGSMAC v0.91, Copyright 2004 Kent Dickey, http://kegs.sourceforge.net</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright 2004 Kent Dickey</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
BIN
KEGSMAC.app/Contents/Resources/2mg.icns
Normal file
BIN
KEGSMAC.app/Contents/Resources/2mg.icns
Normal file
Binary file not shown.
BIN
KEGSMAC.app/Contents/Resources/525.icns
Normal file
BIN
KEGSMAC.app/Contents/Resources/525.icns
Normal file
Binary file not shown.
Binary file not shown.
123
README.a2.compatibility.txt
Normal file
123
README.a2.compatibility.txt
Normal file
@ -0,0 +1,123 @@
|
||||
# $Id: README.a2.compatibility,v 1.2 2004/10/18 18:17:21 kentd Exp $
|
||||
|
||||
Flobynoid: Must disable Fast Disk Emul (hit F7 to toggle it off) since
|
||||
game's loader relies on the sector order on the disk (reads 8
|
||||
sectors from the start without checking headers, assumes every other
|
||||
physical sector is skipped due to decode delays).
|
||||
|
||||
Bard's Tale II GS: Doesn't recognize any save disk as a ProDOS disk.
|
||||
It's detecting a "ProDOS" disk by checking for a string on block
|
||||
0 at offset 0x15e. GSOS on system 6 has moved the string to 0x162,
|
||||
so disks inited under GSOS will be detected as "Not a PRODOS disk".
|
||||
Just make a copy of the Bard's Tale disk image to another file and
|
||||
then mount that new image and remove all the files using the Finder.
|
||||
Then rename the volume and you have a working save disk.
|
||||
|
||||
Robotron 2084:
|
||||
Robot Battle:
|
||||
These cracks use a "Fastloader" which is buggy.
|
||||
It tries to JMP $F3D4 and expects to hit an RTS soon.
|
||||
But on a IIgs it will access some illegal memory causing a code
|
||||
yellow. You can just ignore the code yellow.
|
||||
|
||||
Beyond Castle Wolfenstein: Make sure your disk is writeable (not compressed!)
|
||||
|
||||
Breakout: Has trouble loading from the cracked copy.
|
||||
From the BASIC prompt, do: "CALL -151" then "C083 N C083" then
|
||||
"BLOAD INTBASIC" then run breakout. Then it runs fine.
|
||||
|
||||
Burgertime: This is a bad crack. Loader starts the game by writing
|
||||
the game entry point into $0036/$0037, and then executing a BRK
|
||||
instruction. The BRK handler on an old Apple II will try to write
|
||||
out a message by calling through $0036/$0037, and this will start
|
||||
the game. But on a IIgs, the ROM sets the $0036/$0037 vectors
|
||||
back to the default, and so we crash into the monitor instead.
|
||||
Here's a memory fix and a disk-image fix: From the crack screen,
|
||||
press Shift-F6 (or middle mouse button) and in the KEGS debugger
|
||||
window enter: "1d0a:ea 6c 36 0" and then "g". You can make
|
||||
this fix to the disk image using a sector editor and change
|
||||
Track $1E sector $09 offset $0A from "60 78 A9 03" to "EA 6C 36 00"
|
||||
and write it back.
|
||||
|
||||
Caverns of Callisto: Requires old C600 ROM in slot 6 (Slot 6==Your Card).
|
||||
|
||||
Championship Loderunner: Requires disk to be writeable or else it starts
|
||||
the level and then jumps immediately back to the title page.
|
||||
|
||||
Jeopardy: Disk must be writeable or else it displays "DISK ERROR" and
|
||||
then crashes into the monitor.
|
||||
|
||||
|
||||
Drol: Needs slot 6 set to "Your Card" from the IIgs control panel
|
||||
(Ctrl-Cmd-ESC, then choose "Slots").
|
||||
I found Drol hard, so here are some cheats. First, the standard cheat
|
||||
for Drol is to have infinite lives, this cheat is to edit the disk
|
||||
image:
|
||||
Track $0B, Sector $0A, byte $22 to EA EA
|
||||
Track $11, Sector $0A, byte $10 to EA EA
|
||||
Track $17, Sector $09, byte $B2 to EA EA
|
||||
I didn't create those cheats, I got it from textfiles.com.
|
||||
My cheats are for the monsters to never kill you--just run right
|
||||
through them.
|
||||
While playing Drol, press Shift-F6 (or middle mouse button) to
|
||||
enter the KEGS debugger, and then:
|
||||
0/f28:18 18 # Monsters' missiles won't kill you
|
||||
0/e05:90 0c # Monsters won't kill you
|
||||
Continue emulation by type "g" and then enter.
|
||||
Other things, like the bird, axes, swords still kill you.
|
||||
To easily solve the third screen, move your man to the far right
|
||||
side on the top level, so that you are directly above the woman
|
||||
on the bottom row. Fly into the air "A" and then get to the KEGS
|
||||
debugger, and type:
|
||||
0/c:4
|
||||
and then continue with "g". Now press "Z" and you will go all
|
||||
the way down and land on the woman and end the level. It's
|
||||
useful to have made the two above patches so that touching monsters
|
||||
won't kill you.
|
||||
Two more patches that only apply to level 3, and so most be made
|
||||
in memory each time you enter level 3:
|
||||
6cf3:18 18 18 # Axes won't kill you
|
||||
6f70:38 38 # Swords/arrows won't kill you
|
||||
The bird and the guy you can't kill will still kill you. These
|
||||
cheats were enough to make the game easily playable.
|
||||
In the game, your death is indicated by setting location $001E to
|
||||
$FF. Setting breakpoints there can let you find other cheats.
|
||||
|
||||
Moon Patrol: Crashes into the monitor after completing checkpoint E.
|
||||
To fix the Moon Patrol/Dung beetles version, from within KEGS:
|
||||
BLOAD MOON PATROL
|
||||
CALL -151
|
||||
1E15:EA
|
||||
919G
|
||||
and it will work fine.
|
||||
If you have the booting version that just has Moon Patrol on it,
|
||||
then from any point after the crack screen is shown, enter the
|
||||
KEGS debugger (Shift-F6 or middle moust button) and then enter:
|
||||
0/1e15:ea
|
||||
g
|
||||
and then it will play fine.
|
||||
The bug is that the code executes an instruction with opcode $02,
|
||||
which is a NOP on 6502, but is a COP instruction to 65816. The
|
||||
COP instruction acts like BRK and will crash. The patch just
|
||||
makes it a real NOP.
|
||||
|
||||
Microbe: Crashes upon booting.
|
||||
Code at $599E tries to pull a return address off of a location
|
||||
beneath the stack pointer and jump to it, but it doesn't add 1
|
||||
correctly so it jumps to $5917 when it meant to jump to $5918.
|
||||
On a IIgs, this causes a BRK to be executed and the game to crash.
|
||||
This can be patched in memory in two places:
|
||||
0/599e:ba ca 9a 7d 00 01 48 98 7d 01 01 9d 01 01 60
|
||||
0/6f1d:ba ca 9a 7d 00 01 48 98 7d 01 01 9d 01 01 60
|
||||
The original byte sequence for both locations is:
|
||||
00/599e: ba TSX
|
||||
00/599f: 7d ff 00 ADC $00ff,X
|
||||
00/59a2: 85 94 STA $94
|
||||
00/59a4: 98 TYA
|
||||
00/59a5: 7d 00 01 ADC $0100,X
|
||||
00/59a8: 85 95 STA $95
|
||||
00/59aa: 6c 94 00 JMP ($0094)
|
||||
You can also patch the code onto the disk image. I found
|
||||
the $599E version on Track $05, Sector $06, Byte $9E.
|
||||
I found the $6F1D version on the image at Track $0C, Sector $00,
|
||||
at byte $1D.
|
@ -1,5 +1,4 @@
|
||||
|
||||
NOTE: The build process changed as of KEGS v0.70!
|
||||
# $Id: README.compile,v 1.20 2004/10/18 04:05:14 kentd Exp $
|
||||
|
||||
General build instructions:
|
||||
--------------------------
|
||||
@ -39,8 +38,11 @@ Use the vars_x86linux file with:
|
||||
rm vars; ln -s vars_x86linux vars
|
||||
make
|
||||
|
||||
KEGS assumes perl is in your path. If it is somewhere else, you need to edit
|
||||
the "PERL = perl" line in the vars file and make it point to the correct place.
|
||||
The resulting executable is called "xkegs".
|
||||
|
||||
The build scripts assume perl is in your path. If it is somewhere else,
|
||||
you need to edit the "PERL = perl" line in the vars file and make it point
|
||||
to the correct place.
|
||||
|
||||
For audio, KEGS needs access to /dev/dsp. If the permissions do not allow
|
||||
KEGS to access /dev/dsp, it can fail with a cryptic error message. As root,
|
||||
@ -55,11 +57,12 @@ Use the vars_linuxppc vars file by:
|
||||
rm vars; ln -s vars_linuxppc vars
|
||||
make
|
||||
|
||||
KEGS assumes perl is in your path. If it is somewhere else, you need to edit
|
||||
the "PERL = perl" line in the vars file and make it point to the correct place.
|
||||
The build scripts assume perl is in your path. If it is somewhere else,
|
||||
you need to edit the "PERL = perl" line in the vars file and make it point
|
||||
to the correct place.
|
||||
|
||||
Audio is currently disabled by default, but you can try turning it on
|
||||
by runnning "kegs -audio 1". It sounds horrible to me, but sounds do
|
||||
by runnning "xkegs -audio 1". It sounds horrible to me, but sounds do
|
||||
come out.
|
||||
|
||||
Solaris SPARC build instructions:
|
||||
@ -70,11 +73,12 @@ Use the vars_solaris vars file by:
|
||||
rm vars; ln -s vars_solaris vars
|
||||
make
|
||||
|
||||
KEGS assumes perl is in your path. If it is somewhere else, you need to edit
|
||||
the "PERL = perl" line in the vars file and make it point to the correct place.
|
||||
The build scripts assume perl is in your path. If it is somewhere else,
|
||||
you need to edit the "PERL = perl" line in the vars file and make it point
|
||||
to the correct place.
|
||||
|
||||
Audio is currently disabled by default, but you can try turning it on
|
||||
by runnning "kegs -audio 1".
|
||||
by runnning "xkegs -audio 1".
|
||||
|
||||
Solaris x86 build instructions:
|
||||
--------------------------------
|
||||
@ -84,11 +88,12 @@ Use the vars_x86solaris vars file by:
|
||||
rm vars; ln -s vars_x86solaris vars
|
||||
make
|
||||
|
||||
KEGS assumes perl is in your path. If it is somewhere else, you need to edit
|
||||
the "PERL = perl" line in the vars file and make it point to the correct place.
|
||||
The build scripts assume perl is in your path. If it is somewhere else,
|
||||
you need to edit the "PERL = perl" line in the vars file and make it point
|
||||
to the correct place.
|
||||
|
||||
Audio is currently disabled by default, but you can try turning it on
|
||||
by runnning "kegs -audio 1".
|
||||
by runnning "xkegs -audio 1".
|
||||
|
||||
HP-UX assembly-emulation instructions:
|
||||
-------------------------------------
|
||||
@ -100,14 +105,14 @@ rm vars; ln -s vars_hp vars
|
||||
Edit the Makefile, and remove "engine_c.o" from the "OBJECTS1=" line at
|
||||
the top. Then just type "make".
|
||||
|
||||
This version is quite out of date and most likely does not compile any more.
|
||||
|
||||
Other platform "C" build instructions:
|
||||
-------------------------------------
|
||||
|
||||
I don't know--you tell me. If you are porting to an X-windows and
|
||||
Unix-based machine, it should be easy. Start with vars_x86linux if
|
||||
you are a little-endian machine, or vars_linuxppc if you are big
|
||||
endian. Don't define -DKEGS_LITTLE_ENDIAN unless your processor is
|
||||
little-endian (x86, Alpha). Mac, Sun, MIPS, HP, Motorola, and IBM are
|
||||
big-endian.
|
||||
If you are porting to an X-windows and Unix-based machine, it should be
|
||||
easy. Start with vars_x86linux if you are a little-endian machine, or
|
||||
vars_linuxppc if you are big endian. Don't define -DKEGS_LITTLE_ENDIAN
|
||||
unless your processor is little-endian (x86, Alpha). Mac, Sun, MIPS,
|
||||
HP, Motorola, and IBM are big-endian.
|
||||
|
@ -1,18 +1,19 @@
|
||||
|
||||
KEGS: Kent's Emulated GS version 0.86
|
||||
KEGS: Kent's Emulated GS version 0.91
|
||||
http://kegs.sourceforge.net/
|
||||
|
||||
What is this?
|
||||
-------------
|
||||
|
||||
KEGS is an Apple IIgs emulator for Mac OS X, Linux, and Win32.
|
||||
The Apple IIgs was the last released computer in the Apple II line.
|
||||
It first was sold in 1986.
|
||||
The Apple IIgs was the most powerful computer in the Apple II line.
|
||||
It first was sold in 1986. An Apple IIgs has the capability to run almost all
|
||||
Apple II, Apple IIe, and Apple IIc programs.
|
||||
|
||||
KEGS supports all Apple IIgs graphics modes (which include all Apple //e
|
||||
modes), plus plays all Apple IIgs sounds accurately. It supports
|
||||
limited serial port emulation through sockets, or can use real serial ports
|
||||
on Windows and Mac OS X.
|
||||
serial port emulation through TCP/IP connections, or can use real
|
||||
serial ports on Windows and Mac OS X.
|
||||
|
||||
The ROMs and GS/OS (the Apple IIgs operating system) are not included
|
||||
with KEGS since they are not freely distributable. KEGS is a little
|
||||
@ -20,49 +21,53 @@ user-hostile now, so if something doesn't work, let me know what went
|
||||
wrong, and I'll try to help you out. See my email address at the end of
|
||||
this file.
|
||||
|
||||
I'd like to thank Chea Chee Keong who created KEGS32, the first Windows
|
||||
port of KEGS. That version, which has a better Windows-interface but which
|
||||
is based on older core code, is at http://www.geocities.com/akilgard/kegs2.
|
||||
|
||||
KEGS features:
|
||||
-------------
|
||||
|
||||
Fast 65816 emulation:
|
||||
About 80MHz on a P4 1.7GHz or a G4 1GHz.
|
||||
About 80MHz on a Pentium 4 1.7GHz or a Mac G4 1GHz.
|
||||
Emulates low-level 5.25" and 3.5" drive accesses (even nibble-copiers work!).
|
||||
Emulates classic Apple II sound and 32-voice Ensoniq sound.
|
||||
All sound is played in 16-bit stereo at 48KHz (44100 on a Mac).
|
||||
Emulates all Apple IIgs graphics modes, including border effects.
|
||||
Can handle mixed-displays (superhires at the top, lores at the bottom).
|
||||
Always does 60 full screen video updates per second.
|
||||
Even supports 3200-color pictures.
|
||||
Emulates all Apple IIgs and Apple II graphics modes, including border effects.
|
||||
Can handle display changes at any time (superhires at the top, lores
|
||||
at the bottom). Always does 60 full screen video updates per second.
|
||||
Supports 3200-color pictures.
|
||||
Mouse and joystick support.
|
||||
Emulates all Apple IIgs memory "tricks" for full compatibility.
|
||||
Low-level ADB keyboard and mouse emulation enables Wolfenstein 3D to run.
|
||||
Clock chip emulation makes the host time available to the Apple IIgs.
|
||||
Emulated battery RAM remembers control panel settings.
|
||||
Limited SCC (serial port) emulation to enable PR#1/2 IN#1/2 and other
|
||||
serial programs to work.
|
||||
Limited SCC (serial port) emulation to enable PR#1/2 IN#1/2 and Virtual
|
||||
Modem enables standard Apple terminal programs to telnet to any
|
||||
internet address (or receive connections from another telnet).
|
||||
|
||||
KEGS by default emulates a 8MB Apple IIgs, but you can change this with
|
||||
the "-mem" command line option.
|
||||
KEGS by default emulates a 8MB Apple IIgs, but you can change this from
|
||||
the Configuration Panel.
|
||||
|
||||
KEGS is so accurate, even the built-in ROM selftests pass (you must be in
|
||||
2.8MHz speed mode to pass the self-tests).
|
||||
2.8MHz speed mode to pass the self-tests and you must set the Configuration
|
||||
Panel entry "Enable Text Page 2 shadow" to "Disabled on ROM 01" for ROM 01).
|
||||
|
||||
Release info:
|
||||
------------
|
||||
|
||||
Included files:
|
||||
CHANGES - Description of changes since last release
|
||||
README.kegs - you're here
|
||||
README.compile - Describes how to build KEGS
|
||||
README.linux.rpm - Describes how to install KEGS's RPM for Linux
|
||||
README.win32 - Win32 special directions
|
||||
README.mac - Mac OS X special directions
|
||||
INTERNALS.overview - description of how KEGS code works
|
||||
INTERNALS.xdriver - Describes the xdriver.c routines for porting
|
||||
INTERNALS.iwm - Describes the internal 3.5" and 5.25" disk
|
||||
README.kegs.txt - you're here
|
||||
README.compile.txt - Describes how to build KEGS
|
||||
README.linux.rpm.txt - Describes how to install KEGS's RPM for Linux
|
||||
README.win32.txt - Win32 special directions
|
||||
README.mac.txt - Mac OS X special directions
|
||||
README.a2.compatibility.txt - List of programs which need tweaking
|
||||
src/INTERNALS.overview - description of how KEGS code works
|
||||
src/INTERNALS.xdriver - Describes the xdriver.c routines for porting
|
||||
src/INTERNALS.iwm - Describes the internal 3.5" and 5.25" disk
|
||||
handling routines
|
||||
kegs - the executable, for HP-UX 10.20+
|
||||
kegs.spec - The Linux spec file for making an RPM
|
||||
kegs_conf - disk image configuration info
|
||||
KEGSMAC - the Mac OS X executable
|
||||
kegswin.exe - the Windows executable
|
||||
config.kegs - disk image configuration info
|
||||
to_pro - Hard-to-use ProDOS volume creator
|
||||
partls - Lists partitions on Apple-partitioned hard
|
||||
drives or CD-ROMs
|
||||
@ -71,9 +76,10 @@ Included files:
|
||||
You need to provide:
|
||||
|
||||
1) Patience.
|
||||
2) a ROM file called "ROM", "ROM.01" or "ROM.03" in the KEGS directory.
|
||||
It can be either from a ROM 01 (131072 bytes long) or from a
|
||||
ROM 03 machine (262144 bytes long.)
|
||||
2) a ROM file called "ROM", "ROM.01" or "ROM.03" in the KEGS directory
|
||||
(or in your home directory). It can be either from a ROM 01
|
||||
(131072 bytes long) or from a ROM 03 machine (262144 bytes
|
||||
long.)
|
||||
3) A disk image to boot. This can be either "raw" format or 2IMG.
|
||||
See discussion below. GS/OS would be best.
|
||||
|
||||
@ -87,10 +93,11 @@ or fc/0000 - ff/ffff from a ROM 03 GS, and put that in a file called
|
||||
Running KEGS:
|
||||
------------
|
||||
|
||||
The distribution comes in 3 parts: a source-only distribution (kegs.xxx.tar.gz),
|
||||
along with two binary distributions for Mac and Windows.
|
||||
The distribution comes with the full source code for all platforms in
|
||||
the src/ directory, the Windows executable as kegswin.exe, and the Mac OS X
|
||||
executable as KEGSMAC.
|
||||
|
||||
See the README.compile file for more info about compiling for Linux.
|
||||
See the README.compile.txt file for more info about compiling for Linux.
|
||||
|
||||
On all platforms except the Mac, you must start KEGS from a terminal
|
||||
window. KEGS will open a new window and use the window you started it from
|
||||
@ -98,50 +105,68 @@ as a "debug" window.
|
||||
|
||||
On a MAC, you need to place the "config.kegs" file someplace where KEGS
|
||||
can find it. The simplest place is in your home directory, so copy it there
|
||||
with the Finder (or using the Terminal).
|
||||
with the Finder (or using the Terminal). You can also make the directory
|
||||
Library/KEGS from your home directory, and then place config.kegs there
|
||||
along with the ROM file. You do not need a starting config.kegs file
|
||||
on a Mac--KEGS will offer to make it for you if it cannot find one.
|
||||
|
||||
Start kegs by Double-clicking the KEGSMAC icon on a MAC, or by running
|
||||
the executable (kegswin on Windows, and kegs on Linux). KEGSMAC can
|
||||
be run by the Terminal window as well (which enables access to more debug
|
||||
information) by typing: "./KEGSMAC.app/Contents/MacOS/KEGSMAC".
|
||||
be run by the Terminal window on a Mac as well (which enables access to
|
||||
more debug information) by typing: "./KEGSMAC.app/Contents/MacOS/KEGSMAC".
|
||||
|
||||
Assuming all goes well, KEGS will then boot up but probably not find any
|
||||
disk images. See below for how to tell KEGS what disk images to use.
|
||||
Tip: Hitting "F8" locks the mouse in the window (and hides the host cursor)
|
||||
until you hit "F8" again.
|
||||
|
||||
Disk Images:
|
||||
Configuration Panel:
|
||||
-------------------
|
||||
|
||||
You enter the Configuration panel by pressing F4 at any time. You tell
|
||||
KEGS what disk images to use through the Configuration panel. (If KEGS
|
||||
couldn't find a ROM file, you will be forced into the Configuration
|
||||
Panel mode until you select a valid ROM file).
|
||||
|
||||
To select a ROM file, select "ROM File Selection" and then select your
|
||||
ROM file. If you were not forced into the panel at startup, the KEGS
|
||||
found one and you can skip this step.
|
||||
|
||||
Disk Images
|
||||
-----------
|
||||
|
||||
You tell KEGS what disk images to use through the Configuration panel.
|
||||
The primary use of the Configuration Panel is to select disk images. To
|
||||
change disk images being used, select "Disk Configuration". Each slot
|
||||
and drive that can be loaded with an image is listed. "s5d1" means slot
|
||||
5, drive 1. Slot 5 devices are 3.5" 800K disks, and slot 6 devices are
|
||||
5.25" 140K disks. Slot 7 devices are virtual hard drives, and can be
|
||||
any size at all (although ProDOS-formatted images should be less than
|
||||
32MB).
|
||||
|
||||
You enter the Configuration panel by pressing F4 at any time. Then select,
|
||||
"Disk Configuration". Each slot and drive that can be loaded with an image
|
||||
is listed. "s5d1" means slot 5, drive 1. Slot 5 devices are 3.5" 800K disks,
|
||||
and slot 6 devices are 5.25" 140K disks. Slot 7 devices are virtual hard
|
||||
drives, and can be any size at all (although ProDOS-formatted drives
|
||||
should be less than 32MB).
|
||||
|
||||
Just use the arrow keys to navigate to the device entry to change,
|
||||
and then select it by pressing Return. A scrollable file selection
|
||||
interface is presented, letting you located your image files. To
|
||||
save navigation, you can press Tab to toggle between entering a path
|
||||
manually, and using the selector. Press Return on ".." entries to go up
|
||||
a directory level. When you find the image you want, just press Return.
|
||||
Just use the arrow keys to navigate to the device entry to change, and
|
||||
then select it by pressing Return. A scrollable file selection
|
||||
interface is presented, letting you locate your image files. To quickly
|
||||
jump to a particular path, you can press Tab to toggle between entering
|
||||
a path manually, and using the file selector. Press Return on ".."
|
||||
entries to go up a directory level. When you find the image you want,
|
||||
just press Return.
|
||||
|
||||
If the image has partitions that KEGS supports, another selection
|
||||
dialog will have you select which partition to mount. You will probably
|
||||
only have partitions on direct devices you mount. For instance, on a
|
||||
Mac, /dev/disk1 is usually the CDROM drive.
|
||||
only have partitions on direct devices you mount (or on a Mac, of .dmg
|
||||
images of CDs). For instance, on a Mac, /dev/disk1 can sometimes be the
|
||||
CDROM drive.
|
||||
|
||||
KEGS can handle "raw", .dsk, .po, 2IMG, 5.25" ".nib" images, some Mac
|
||||
KEGS can handle "raw", .dsk, .po, 2IMG, 5.25" ".nib" images, most Mac
|
||||
Diskcopy images and partitioned images. The .dsk and .po formats you often
|
||||
find on the web are really "raw" formats, and so they work fine. KEGS uses
|
||||
the host file permissions to encode the read/write status of the image.
|
||||
KEGS can open any image file compressed with gzip (with the extension ".gz")
|
||||
automatically as a read-only disk image.
|
||||
|
||||
An image is the representation of an Apple IIgs disk, but in a file on
|
||||
your computer. For 3.5" disks, for example, a raw image would be exactly
|
||||
800K bytes long (819200 bytes). KEGS intercepts the emulated GS accesses to
|
||||
800K bytes long (819200 bytes). KEGS directs the emulated GS accesses to
|
||||
the image, and does the correct reads and writes of the Unix file instead.
|
||||
|
||||
To do "useful" things with KEGS, you need to get a bootable disk image.
|
||||
@ -150,21 +175,36 @@ get Apple IIgs System 6. Unfortunately, Apple now only has .sea files which
|
||||
are executable files for Macintosh only. You need a macintosh to execute
|
||||
those programs, which creates Disk Copy image files with no special extensions
|
||||
(and with spaces in the names). Once you get those files back to your
|
||||
host machine, you can use them by listing them in kegs_conf.
|
||||
host machine, you can use them by selecting them from the Configuration Panel.
|
||||
|
||||
You can also get Apple II programs in ".dsk" format from a variety of
|
||||
sites on the internet, and these should all work on KEGS as well.
|
||||
|
||||
KEGS also supports partitioned devices. For instance, if you have a CD-ROM
|
||||
on your computer, just pop an Apple II CD in, and KEGS can mount it, if
|
||||
you have a Unix-base system (Linux, any Unix, and Mac OS X).
|
||||
you have a Unix-based system (Linux, any Unix, and Mac OS X).
|
||||
|
||||
If you're on a Mac, be careful letting KEGS use your HFS partitions--
|
||||
GSOS has many HFS bugs when it is writing.
|
||||
GSOS has many HFS bugs when it is writing. Also avoid having KEGS access
|
||||
an image which have mounted on your Mac at the same time (always unmount
|
||||
it from your Mac before letting KEGS access it)!
|
||||
|
||||
If you do not have any disk mounted in s7d1, KEGS will jump into BASIC.
|
||||
If you do not have any disk mounted in s7d1, KEGS will jump into the monitor.
|
||||
To boot slot 6 (or slot 5), use the Apple IIgs Control Panel by pressing
|
||||
Ctrl-Command-ESC.
|
||||
|
||||
Support for 5.25" nibblized images is read-only for now (since the
|
||||
format is kinda simplistic, it's tricky for KEGS to write to it).
|
||||
Just mount your image, like "disk.nib" in the kegs_conf file like
|
||||
any .dsk or .po image.
|
||||
format is kinda simplistic, it's tricky for KEGS to write to it since KEGS
|
||||
has more information than fits in that format). Just select your image,
|
||||
like "disk.nib" in the kegs_conf file like any .dsk or .po image.
|
||||
|
||||
In addition to changing disks, you can also just "eject" and image by
|
||||
moving the cursor to select that slot/drive and then press "E". The
|
||||
emulated IIgs will immediately detect changes to s5d1 and s5d2.
|
||||
|
||||
Care should be taken when changing images in slot 7--KEGS does not notify
|
||||
GSOS that images have changed (or been ejected), and so it's best to make
|
||||
changes when GSOS is not running.
|
||||
|
||||
|
||||
Key summary:
|
||||
@ -180,8 +220,8 @@ F7: Toggle fast_disk_emul on/off
|
||||
F8: Toggle pointer hiding on/off.
|
||||
F9: Invert the sense of the joystick.
|
||||
Shift-F9: Swap x and y joystick/paddle axes.
|
||||
F10: Attempt to change the a2vid_palette (only useful on 8-bit color display)
|
||||
F11: Full screen mode (does not do anything yet).
|
||||
F10: Attempt to change the a2vid_palette (only useful on 256-color displays)
|
||||
F11: Full screen mode (only on Mac OS X).
|
||||
F12: Alias of Pause/Break which is treated as Reset
|
||||
|
||||
F2, Alt_R, Meta_r, Menu, Print, Mode_switch, Option: Option key
|
||||
@ -202,35 +242,15 @@ KEGS hides the host cursor automatically and enables special tracking
|
||||
which forces the emulated cursor to follow the host cursor. If this doesn't
|
||||
work right under some program, just press F8 for better compatibility.
|
||||
|
||||
The default joystick is the mouse position. Upper left is 0,0. Lower right
|
||||
is 255,255. Press Shift-F9 to swap the X and Y axes. Press F9 to reverse
|
||||
the sense of both paddles (so 0 becomes 255, etc). Swapping and
|
||||
reversing are convenient with paddle-based games like "Little Brick Out"
|
||||
so that the mouse will be moving like the paddle on the screen. "Little
|
||||
Brick Out" is on the DOS 3.3 master disk. The joystick does not work
|
||||
properly if the pointer is constrained in the window.
|
||||
|
||||
If you have a real joystick on Linux, start KEGS with "-joystick" and
|
||||
you should be able to use it. Real joysticks should also work on Windows.
|
||||
|
||||
The left mouse button is the mouse button for KEGS. The right mouse
|
||||
button (if you have it) or F6 toggles between four speed modes. Mode 0
|
||||
(the default) means run as fast as possible. Mode 1 means run at 1MHz.
|
||||
Mode 2 means run at 2.8MHz. Mode 3 means run at 8.0MHz (about the speed
|
||||
of a ZipGS accelerator). Most Apple //e (or earlier) games need to be
|
||||
run at 1MHz. Many Apple IIgs demos must run at 2.8MHz or they crash. Try
|
||||
running ornery programs at 2.8MHz. 3200 pictures generally only display
|
||||
correctly at 2.8MHz or sometimes 8.0MHz.
|
||||
|
||||
The middle mouse button or Shift-F6 causes KEGS to stop emulation, and enter
|
||||
the debugger. You can continue with "g" then return in the debug window.
|
||||
You can also disassemble memory, etc. The section "Debugging KEGS"
|
||||
above describes the debugger interface a little more.
|
||||
|
||||
KEGS has no pop-up menus or other interactive interfaces (other than
|
||||
the debug window). Input to the debug window is only acted upon when
|
||||
the emulation is stopped by hitting a breakpoint or pressing the right-most
|
||||
mouse button.
|
||||
the debug window, and the occasional error dialogs on Mac OS X). Input to
|
||||
the debug window is only acted upon when the emulation is stopped
|
||||
(Shift-F6, middle mouse button, or hitting a breakpoint).
|
||||
|
||||
Quitting KEGS:
|
||||
-------------
|
||||
@ -240,6 +260,86 @@ can select Quit from the menu. Or enter ctrl-c in the debugger window.
|
||||
Or press the middle-mouse button in the emulation window, and then type
|
||||
"q" return in the debug window.
|
||||
|
||||
Command/Option keys:
|
||||
-------------------
|
||||
|
||||
If you have a keyboard with the special Windows keys, you can
|
||||
use them as the command/option keys. For those without those keys,
|
||||
there are several alternatives.
|
||||
|
||||
The following keys are Option (closed-apple) (not all keyboards have all
|
||||
keys): F2, Meta_R, Alt_R, Cancel, Print_screen, Mode_switch, Option,
|
||||
or the Windows key just to the right of the spacebar. The following keys are
|
||||
Command (open-apple): F1, Meta_L, Alt_L, Menu, Scroll_lock, Command,
|
||||
the Windows key left of the spacebar, and the Windows key on the far right
|
||||
that looks like a pull-down menu. You can use F1 and F2 if you cannot make
|
||||
anything else work (especially useful if your OS is intercepting some
|
||||
Alt or Command key sequences).
|
||||
|
||||
If you can't get any of these to work on your machine, let me know.
|
||||
Note that X Windows often has other things mapped to Meta- and Alt-
|
||||
key sequences, so they often don't get passed through to KEGS. So it's
|
||||
best to use another key instead of Alt or Meta.
|
||||
|
||||
The joystick/paddle buttons are just the Command and Option keys.
|
||||
|
||||
|
||||
Reset:
|
||||
-----
|
||||
|
||||
The reset key is Pause/Break or F12. You must hit it with Ctrl to get it to
|
||||
take effect (just like a real Apple IIgs). Ctrl-Command-Reset
|
||||
forces a reboot. Ctrl-Command-Option-Reset enters selftests.
|
||||
Selftests will pass if you force speed to 2.8MHz using the middle
|
||||
button or F6 (and also set Enable Text Page 2 shadow = Disabled for ROM 01).
|
||||
Watch out for ctrl-shift-Break--it will likely kill an X Windows session.
|
||||
Also note that the Unix olvwm X window manager interprets ctrl-F12 and will
|
||||
not pass it on to KEGS--you'll need to use Break for reset in that case.
|
||||
|
||||
Full Screen mode (MAC OS X ONLY):
|
||||
----------------
|
||||
|
||||
KEGS can run in full screen mode--which is especially useful when letting
|
||||
small kids use KEGS (but it is not really a lock, so do not let a 2 year
|
||||
old bang on the keyboard while running KEGS).
|
||||
|
||||
Full Screen mode is toggled with F11 (or Ctrl-F11, since Expose on a Mac
|
||||
is intercepting F11). If KEGS stops in the debugger for any reason,
|
||||
full screen mode is toggled off automatically.
|
||||
|
||||
|
||||
Joystick Emulation (Mouse, Keypad, or real native joystick):
|
||||
------------------
|
||||
|
||||
The default joystick is the mouse position. Upper left is 0,0. Lower right
|
||||
is 255,255. Press Shift-F9 to swap the X and Y axes. Press F9 to reverse
|
||||
the sense of both paddles (so 0 becomes 255, etc). Swapping and
|
||||
reversing are convenient with paddle-based games like "Little Brick Out"
|
||||
so that the mouse will be moving like the paddle on the screen. "Little
|
||||
Brick Out" is on the DOS 3.3 master disk. The joystick does not work
|
||||
properly if the pointer is constrained in the window.
|
||||
|
||||
You can also select from a "Keypad Joystick" or a real joystick from
|
||||
the Configuration panel. Press return on the "Joystick Configuration"
|
||||
entry, and then select between Mouse Joystick, Keypad Joystick, or one
|
||||
of two native joysticks. The Keypad Joystick uses your keypad number
|
||||
keys as a joystick, where keypad 7 means move to the upper left, and
|
||||
keypad 3 means move to the lower right. Pressing multiple keys together
|
||||
averages the results, allowing finer control than just 8 directions.
|
||||
Also, joystick scaling is selectable here for games which require
|
||||
a greater range of motion to work correctly, along with trim adjustment
|
||||
which moves the centering point. Adjusting scaling usually means you
|
||||
will need to adjust the trim as well.
|
||||
|
||||
The left mouse button is the mouse button for KEGS. The right mouse
|
||||
button (if you have it) or F6 toggles between four speed modes. Mode 0
|
||||
(the default) means run as fast as possible. Mode 1 means run at 1MHz.
|
||||
Mode 2 means run at 2.8MHz. Mode 3 means run at 8.0MHz (about the speed
|
||||
of a ZipGS accelerator). Most Apple //e (or earlier) games need to be
|
||||
run at 1MHz. Many Apple IIgs demos must run at 2.8MHz or they will not
|
||||
operate correctly. Try running ornery programs at 2.8MHz. 3200 pictures
|
||||
generally only display correctly at 2.8MHz or sometimes 8.0MHz.
|
||||
|
||||
|
||||
Debugging KEGS:
|
||||
--------------
|
||||
@ -272,6 +372,10 @@ type:
|
||||
|
||||
e1/0010B
|
||||
|
||||
The format is "bank/address" then "B", where the B must be in caps and
|
||||
the address must use lower-case hex. For Apple IIe programs, just use a
|
||||
bank of 0.
|
||||
|
||||
To list all breakpoints, just type 'B' with no number in front of it.
|
||||
To delete a breakpoint, enter its address followed by 'D', so
|
||||
|
||||
@ -296,27 +400,17 @@ watchpoints).
|
||||
Frederic Devernay has written a nice help screen available in the
|
||||
debugger when you type "h".
|
||||
|
||||
Useful locations for setting breakpoints:
|
||||
0/3f0B - Break handler
|
||||
0/c000B - Keyboard latch, programs read keys from this address
|
||||
|
||||
|
||||
|
||||
KEGS command-line option summary:
|
||||
--------------------------------
|
||||
|
||||
-mem {mem_amt}: KEGS will use mem_amt as the amount of expansion RAM in
|
||||
the IIgs. This memory is in addition to the 256KB on a ROM 01
|
||||
motherboard, or 1MB on a ROM 03. The memory is in bytes,
|
||||
and it will be rounded down to the nearest 64KB. "-mem 0x800000"
|
||||
will use 8MB of expansion RAM (the default).
|
||||
-badrd: Causes KEGS to halt on any access to invalid memory addresses.
|
||||
Useful for debugging. By default, KEGS allows reads to invalid
|
||||
memory since the Finder does some (especially when you open the
|
||||
About window, and then close it). But KEGS warns you about these
|
||||
accesses in the debug window. In general, these warnings
|
||||
indicate buggy programs. If the warnings get severe, it's
|
||||
a good sign you should quit KEGS and start over before the
|
||||
emulated program crashes. -badrd would be the default for KEGS
|
||||
if it wasn't for the Finder's About window's problem.
|
||||
-ignbadacc: Causes KEGS to allow reads & writes to invalid memory
|
||||
addresses without printing any warnings. Useful for running
|
||||
extremely buggy programs so you don't have to see all the warning
|
||||
messages scroll by.
|
||||
There are others, but the Configuration panel provides a better way to
|
||||
set them so they are no longer listed here.
|
||||
-skip: KEGS will "skip" that many screen redraws between refreshes.
|
||||
-skip 0 will do 60 frames per second, -skip 1 will do 30 fps,
|
||||
-skip 5 will do 10 fps.
|
||||
@ -340,7 +434,6 @@ X-Windows/Linux options
|
||||
-24: KEGS will only look for a 24-bit X-Window display.
|
||||
-display {machine:0.0}: Same as setting the environment variable DISPLAY.
|
||||
Sends X display to {machine:0.0}.
|
||||
-joystick: Will use /dev/js0 as the joystick.
|
||||
-noshm: KEGS will not try to used shared memory for the X graphics display.
|
||||
This will make KEGS much slower on graphics-intensive tasks,
|
||||
by as much as a factor of 10! By default, -noshm causes an
|
||||
@ -348,40 +441,9 @@ X-Windows/Linux options
|
||||
default by specifying a -skip explicitly.
|
||||
|
||||
|
||||
Command/Option keys:
|
||||
-------------------
|
||||
|
||||
If you have a workstation keyboard with the new Windows keys, you can
|
||||
use them as the command/option keys. This is what I use. Since many people
|
||||
don't have the PC keyboard, there are several alternatives.
|
||||
|
||||
The following keys are Option (closed-apple) (not all keyboards have all
|
||||
keys): F2, Meta_R, Alt_R, Cancel, Print_screen, Mode_switch, Option,
|
||||
or the Windows key just to the right of the spacebar. The following keys are
|
||||
Command (open-apple): F1, Meta_L, Alt_L, Menu, Scroll_lock, Command,
|
||||
the Windows key left of the spacebar, and the Windows key on the far right
|
||||
that looks like a pull-down menu. You can use F1 and F2 if you cannot make
|
||||
anything else work.
|
||||
|
||||
If you can't get any of these to work on your machine, let me know.
|
||||
Note that X Windows often has other things mapped to Meta- and Alt-
|
||||
key sequences, so they often don't get passed through to KEGS. So it's
|
||||
best to use another key instead of Alt or Meta.
|
||||
|
||||
The joystick/paddle buttons are just the Command and Option keys.
|
||||
|
||||
Reset:
|
||||
-----
|
||||
|
||||
The reset key is Pause/Break or F12. You must hit it with Ctrl to get it to
|
||||
take effect (just like a real Apple IIgs). Ctrl-Command-Reset
|
||||
forces a reboot. Ctrl-Command-Option-Reset enters selftests.
|
||||
Selftests will pass if you force speed to 2.8MHz using the middle
|
||||
button. Watch out for ctrl-shift-Break--it will likely kill your
|
||||
X Windows session.
|
||||
|
||||
Control Panel:
|
||||
-------------
|
||||
Apple IIgs Control Panel:
|
||||
------------------------
|
||||
|
||||
You can get to the Apple IIgs control panel (unless some application
|
||||
has locked it out) using Ctrl-Command-ESC.
|
||||
@ -453,18 +515,12 @@ to $E0.
|
||||
Details on config.kegs and disk images
|
||||
--------------------------------------
|
||||
|
||||
The file "config.kegs" describes the images KEGS will use. The sample
|
||||
file has all the lines commented out with '#' to show sample uses.
|
||||
Remember, KEGS will boot s7d1 (unless you've changed that using the
|
||||
Apple IIgs control panel), so you must put an image in that slot.
|
||||
The file "config.kegs" describes the images KEGS will use. Although you
|
||||
can edit the file manually, in general you can use the Configuration Panel
|
||||
to make all the changes you need. This information is for reference.
|
||||
|
||||
Changing disks in slot 7 does not work, but you can move around
|
||||
disks in slots 5 and 6. This allows you to "eject" disks and change them.
|
||||
This is especially useful for multi-disk 5.25" programs.
|
||||
|
||||
KEGS uses the Unix permissions on raw disk images to decide how to load
|
||||
it into the emulator. If the file is unreadable, it cannot load the
|
||||
image (duh).
|
||||
KEGS by default will boot s7d1 (unless you've changed that using the
|
||||
Apple IIgs control panel), so you should put an image in that slot.
|
||||
|
||||
KEGS, by default, runs the IWM (3.5" and 5.25" disks) emulation in an
|
||||
"approximate" mode, called "fast_disk_emul". In this mode, KEGS
|
||||
@ -544,14 +600,14 @@ equivalent speed. Many games will be unplayable at the unlimited
|
||||
setting. Setting the IIgs control panel speed to "slow" will slow down
|
||||
to 1MHz.
|
||||
|
||||
Sound output has an interesting relationship to KEGS timing. KEGS must
|
||||
Sound output has an important relationship to KEGS timing. KEGS must
|
||||
play one second of sound per second of emulated time. Normally, this
|
||||
works out exactly right. But as noted above, if KEGS can't maintain the
|
||||
needed speed, it extends the emulated second. If it extends the second
|
||||
to 1.4 real seconds, that means KEGS only produces 1.0 second of sound
|
||||
data every 1.4 seconds--the sound breaks up!
|
||||
|
||||
In all cases, 1MHz to KEGS is 1.024MHz. And 2.8MHz to KEGS is 2.52MHz
|
||||
In all cases, 1MHz to KEGS is 1.024MHz. And 2.8MHz to KEGS is 2.56MHz
|
||||
(trying to approximate the slowdown causes by memory refresh on a real
|
||||
Apple IIgs). It's just easier to say 1MHz and 2.8MHz.
|
||||
|
||||
@ -673,7 +729,9 @@ useful for some games.
|
||||
KEGS: What works:
|
||||
-----------------
|
||||
|
||||
Basically, just about every Apple II program works.
|
||||
Basically, just about every Apple II program works. See the file
|
||||
README.a2.compatibility for directions on how to make certain games/programs
|
||||
work.
|
||||
|
||||
KEGS is EXTREMELY compatible. But, I haven't tested everything. Let
|
||||
me know if you find a program which is not working correctly.
|
||||
@ -696,9 +754,6 @@ the above lets it work fine. This seems to be a bug in the demo.
|
||||
KEGS bugs:
|
||||
---------
|
||||
|
||||
KEGS's serial port emulation is very limited now, and only for
|
||||
adventurous souls.
|
||||
|
||||
On a ROM03, KEGS makes a patch to the ROM image (inside emulation, not
|
||||
to the Unix file) to fix a bug in the ROM code. Both ROM01 and ROM03
|
||||
are patched to enable use of more than 8MB of memory. I then patch the ROM
|
||||
@ -726,39 +781,70 @@ in the debug window. However, when sound restarts, it sometimes
|
||||
If your display is not using shared memory, audio defaults to off unless
|
||||
you override it with "-audio 1".
|
||||
|
||||
SCC emulation:
|
||||
-------------
|
||||
SCC (Serial Port) emulation:
|
||||
---------------------------
|
||||
|
||||
KEGS emulates the two serial ports on a IIgs as being two Unix sockets.
|
||||
Port 1 (printer port) is at socket address 6501, and port 2 (modem)
|
||||
is at socket address 6502.
|
||||
|
||||
In KEGS, from APPLESOFT, if you PR#1, all output will then be sent to
|
||||
socket port 6501. You can see it by connecting to the port using
|
||||
any method you like, but a simple, easy way is to use telnet. In
|
||||
another Unix window, do: "telnet localhost 6501" and then you
|
||||
will see all the output going to the "printer".
|
||||
By default, slot 1 is emulated using a simple receive socket, and slot 2
|
||||
emulates a Virtual Modem.
|
||||
|
||||
A Virtual Modem means KEGS acts as if a modem is on the serial port
|
||||
allowing Apple II communcation programs to fully work, but connected to
|
||||
internet-enabled sockets. KEGS emulates a "Hayes- Compatible" modem,
|
||||
meaning it accepts "AT" commands. You can use KEGS to connect to free
|
||||
telnet-BBSs, or run a BBS program on KEGS and become a telnet BBS yourself.
|
||||
|
||||
The two main AT commands are: ATDT for dialing out, and ATA for receiving
|
||||
calls. To dial out, enter "ATDThostname", or for example,
|
||||
"ATDTboycot.no-ip.com" (which is down at the moment, unfortunately).
|
||||
You can also enter an IP address, like "ATDT127.0.0.1". On a Mac, to
|
||||
create a telnet server to allow telnet connections (do not use over the
|
||||
internet, but on a private network behind a firewall, this should be
|
||||
fine), in a Terminal window type: "sudo /usr/libexec/telnetd -debug".
|
||||
You must then enable telnet on port 23 through your Mac OS X Firewall in
|
||||
the System Preferences->Sharing->Firewall page (just add port 23 as
|
||||
open--you'll need to use the "New..." button and then select Other for
|
||||
Port Name, and enter Port Number as 23). Then from KEGS in a
|
||||
communications program, do "ATDT127.0.0.1", and then log-in to your Mac.
|
||||
|
||||
KEGS also accepts incoming "calls". Start KEGS, and initialize the
|
||||
Virtual Modem with some AT command (ATZ resets all state, and is a useful
|
||||
start). KEGS now has a socket port open, 6502 for slot 2, which you
|
||||
can connect to using any telnet program. In a Terminal window, then
|
||||
type "telnet 127.0.0.1 6502" and you will connect to KEGS. The Virtual
|
||||
Modem then starts printing "RING" every 2 seconds until you answer with
|
||||
"ATA". You are now connected. I have not tried BBS programs, but have
|
||||
made connections with ProTERM.
|
||||
|
||||
On Windows XP SP2, when KEGS tries to open this incoming socket, you'll
|
||||
need to enable it and click Unblock to the dialog that Windows pops up.
|
||||
If you do not want incoming connections, you can block it instead.
|
||||
|
||||
Once connected, you can go back to talking to the Virtual Modem by
|
||||
pressing + three times quickly (+++), and then not type anything for a second.
|
||||
This goes back to the AT-command mode. You can now "ATH" to hang up, or
|
||||
"ATO" to go back online.
|
||||
|
||||
On Windows, the socket code is very preliminary and there are problems
|
||||
receiving connections.
|
||||
|
||||
KEGS also supports an older, simpler socket interface, which it defaults
|
||||
to using on slot 1. In KEGS, from APPLESOFT, if you PR#1, all output will
|
||||
then be sent to socket port 6501. You can see it by connecting to the
|
||||
port using telnet. In another terminal window, do: "telnet localhost 6501"
|
||||
and then you will see all the output going to the "printer".
|
||||
|
||||
Under APPLESOFT, you can PR#1 and IN#1. This gets input from the
|
||||
socket also. You can type in the telnet window, it will be sent on
|
||||
to the emulated IIgs. Telnet on Unix defaults to "line mode" which
|
||||
buffers keys you type until you hit return. This can be a bit distracting,
|
||||
and can be disabled by hitting Ctrl-] and then "mode char". This
|
||||
causes a few {{ chars to show up in KEGS--just ignore this for now.
|
||||
You may want to go to the F4 Config Panel and set "mask off high bit"
|
||||
for serial port accesses to make PR#2 work a little nicer.
|
||||
to the emulated IIgs. You may want to go to the F4 Config Panel and set
|
||||
"mask off high bit" for serial port accesses to make PR#1 work a little nicer.
|
||||
|
||||
That's about it. Proterm and Appleworks GS can talk to the modem port
|
||||
fine, but it's limited in its usefulness. I have printed from
|
||||
Printshop, but it's a bit pointless since it's sending out Imagewriter
|
||||
printer codes which doesn't look like anything. You can "print" from
|
||||
BASIC by using something like PR#1 in KEGS and
|
||||
You can "print" from BASIC by using something like PR#1 in KEGS and
|
||||
"telnet localhost 6501 | tee file.out" in another window.
|
||||
|
||||
Feel free to let me know what doesn't work, but a lot is known not
|
||||
to work. GNO's tty interface may work, but I'm having problems
|
||||
testing it.
|
||||
|
||||
|
||||
KEGS status area:
|
||||
----------------
|
||||
@ -875,7 +961,7 @@ Fix the Ensoniq bugs to make sound more accurate.
|
||||
If you have any problems/questions/etc., just let me know.
|
||||
|
||||
Special thanks to Jeff Smoot of climbingwashington.com for letting me use
|
||||
the picture of a keg in the Mac icon.
|
||||
the picture of a keg for the Mac icon.
|
||||
|
||||
Kent Dickey
|
||||
kadickey@alumni.princeton.edu
|
||||
@ -956,21 +1042,9 @@ KEGS boots s7d1 by default. You can change this using the emulated IIgs
|
||||
control panel, just like a real Apple IIgs. KEGS emulates a IIgs with
|
||||
two 5.25" drives in slot 6, two 3.5" drives in slot 5, and up to 32
|
||||
"hard drives" in slot 7. However, the current Configuration Panel only
|
||||
lets you set through s7d11.
|
||||
|
||||
Config.kegs file
|
||||
----------------
|
||||
|
||||
KEGS saves your preferences and disk image names in the file config.kegs.
|
||||
KEGS searches for this file in the directory KEGS was started in, in
|
||||
your home directory, or in the Resources directory (on a Mac) of the app.
|
||||
It needs to find one someplace, so putting it in your home directory is
|
||||
usually the easiest.
|
||||
|
||||
The config.kegs file is a simple text file. You need to quit KEGS before
|
||||
editing the file. The BRAM data is also kept in this file, with separate
|
||||
BRAM contents for ROM 01 and ROM 03 (so if you switch ROM versions, you
|
||||
don't lose all your BRAM preferences).
|
||||
lets you set through s7d11. ProDOS 8 can access disks up to s7d8, but GSOS
|
||||
has no limit, so it's best to put HFS images past s7d8 in order to leave
|
||||
more slots for ProDOS images.
|
||||
|
||||
If you're trying to use a real host device (CD-ROM, or hard drive, or
|
||||
floppy), you should make the permissions on the /dev/disk* files something
|
||||
@ -982,8 +1056,6 @@ You can do this on a Mac with:
|
||||
|
||||
sudo chmod 644 /dev/disk2
|
||||
|
||||
Running KEGS as root is NOT recommended.
|
||||
|
||||
The s6d* and s5d* drives support disk swapping and disk ejecting, but
|
||||
the s7d* drives do not.
|
||||
DO NOT RUN KEGS AS ROOT. It is not designed for this and it's almost certain
|
||||
problems will ensue.
|
||||
|
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
||||
KEGS - Kent's Emulated GS
|
||||
=========================
|
||||
|
||||
Kegs is an Apple //gs emulator for Mac OS X, Win32, Linux and Unix/X11
|
||||
|
||||
The latest version on the main KEGS home page is v0.91 which doesn't work on Intel Macs. In fact, only
|
||||
small build changes are required, so I have forked the code to Github with my changes.
|
||||
|
||||
Original homepage with useful info on how to get it running is here: (http://kegs.sourceforge.net/)[http://kegs.sourceforge.net/]
|
@ -2,13 +2,13 @@
|
||||
WIN32 port of KEGS (KEGSWIN)
|
||||
----------------------------
|
||||
|
||||
There is a different port of KEGS by akilgard called KEGS32.
|
||||
You can get it from http://www.geocities.com/akilgard/kegs32.
|
||||
This port is leveraged from KEGS32, but mostly a rewrite (perhaps
|
||||
for the worse). The joystick code was taken without too many
|
||||
modifications.
|
||||
There is a different port of KEGS by Chea Chee Keong (akilgard) called
|
||||
KEGS32. You can get it from http://www.geocities.com/akilgard/kegs32.
|
||||
This port is leveraged from KEGS32, but mostly a rewrite (perhaps for
|
||||
the worse). I am grateful for Chea for doing the windows port since I
|
||||
did not know any Windows programming.
|
||||
|
||||
This port is alpha quality. Seriously. Don't expect much.
|
||||
This port is alpha quality. Don't expect much.
|
||||
|
||||
This is a bare-bones Win32 port. It was compiled with Mingw2.0,
|
||||
which you can download at: http://www.mingw.org/. I also had
|
||||
@ -49,3 +49,4 @@ In order to compile,
|
||||
|
||||
|
||||
You can contact me at kadickey@alumni.princeton.edu
|
||||
|
BIN
kegswin.exe
BIN
kegswin.exe
Binary file not shown.
BIN
src/2mg.icns
Normal file
BIN
src/2mg.icns
Normal file
Binary file not shown.
BIN
src/525.icns
Normal file
BIN
src/525.icns
Normal file
Binary file not shown.
@ -4,8 +4,46 @@
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>2mg</string>
|
||||
<string>2MG</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>2mg.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Apple II 2MG Disk Image</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>a2mg</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>kegs</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>525.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>KEGS Configuration File</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>kegs</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>KEGSMAC</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>KEGSMAC</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>kegsicon.icns</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
@ -13,10 +51,14 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<string>KEGS</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<string>0.91</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>KEGSMAC version 0.91</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>KEGSMAC v0.91, Copyright 2004 Kent Dickey, http://kegs.sourceforge.net</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright 2004 Kent Dickey</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
# $Id: release_makefile_base,v 1.15 2003/11/21 20:00:42 kentd Exp $
|
||||
# $Id: release_makefile_base,v 1.15 2003/11/21 20:00:42 kentd Exp kentd $
|
||||
|
||||
OBJECTS1 = adb.o clock.o config.o dis.o engine_c.o scc.o iwm.o \
|
||||
joystick_driver.o moremem.o paddles.o sim65816.o smartport.o \
|
||||
@ -24,17 +24,18 @@ specials_clean:
|
||||
|
||||
# Mac builds:
|
||||
kegsmac: $(OBJECTS) compile_time.o
|
||||
$(CC) $(CCOPTS) $(LDOPTS) -arch ppc $(OBJECTS) compile_time.o $(LDFLAGS) -o kegsmac $(EXTRA_LIBS) -prebind -framework Carbon
|
||||
$(CC) $(CCOPTS) $(LDOPTS) -arch ppc $(OBJECTS) compile_time.o $(LDFLAGS) -o kegsmac $(EXTRA_LIBS) -prebind -framework Carbon -framework Quicktime
|
||||
mkdir -p ../KEGSMAC.app/Contents/Resources/English.lproj/main.nib
|
||||
mkdir -p ../KEGSMAC.app/Contents/MacOS
|
||||
mv kegsmac ../KEGSMAC.app/Contents/MacOS/KEGSMAC
|
||||
echo "APPL????" > ../KEGSMAC.app/Contents/PkgInfo
|
||||
cp -f Info.plist ../KEGSMAC.app/Contents/
|
||||
cp -f InfoPlist.strings ../KEGSMAC.app/Contents/Resources/English.lproj/
|
||||
cp -f info.nib ../KEGSMAC.app/Contents/Resources/English.lproj/main.nib
|
||||
cp -f classes.nib ../KEGSMAC.app/Contents/Resources/English.lproj/main.nib
|
||||
cp -f objects.xib ../KEGSMAC.app/Contents/Resources/English.lproj/main.nib
|
||||
cp -f kegsicon.icns ../KEGSMAC.app/Contents/Resources/
|
||||
cp -f 525.icns ../KEGSMAC.app/Contents/Resources/
|
||||
cp -f 2mg.icns ../KEGSMAC.app/Contents/Resources/
|
||||
touch '../KEGSMAC.app/Icon?'
|
||||
|
||||
# Linux for X builds:
|
||||
@ -49,7 +50,7 @@ kegs.exe: $(OBJECTS) compile_time.o
|
||||
|
||||
# Mingw32 (native windows) builds:
|
||||
kegswin.exe: $(OBJECTS) compile_time.o
|
||||
$(CC) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32
|
||||
$(CC) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32
|
||||
mv $(NAME)$(SUFFIX) ..
|
||||
|
||||
|
||||
|
259
src/adb.c
259
src/adb.c
@ -8,12 +8,14 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_adb_c[] = "@(#)$KmKId: adb.c,v 1.63 2004-03-23 18:46:25-05 kentd Exp $";
|
||||
const char rcsid_adb_c[] = "@(#)$KmKId: adb.c,v 1.73 2004-11-14 14:05:33-05 kentd Exp $";
|
||||
|
||||
/* adb_mode bit 3 and bit 2 (faster repeats for arrows and space/del) not done*/
|
||||
|
||||
#include "adb.h"
|
||||
|
||||
int g_fullscreen = 0;
|
||||
|
||||
extern int Verbose;
|
||||
extern word32 g_vbl_count;
|
||||
extern int g_num_lines_prev_superhires640;
|
||||
@ -21,11 +23,14 @@ extern int g_num_lines_prev_superhires;
|
||||
extern int g_rom_version;
|
||||
extern int g_fast_disk_emul;
|
||||
extern int g_limit_speed;
|
||||
extern int g_irq_pending;
|
||||
extern int g_swap_paddles;
|
||||
extern int g_invert_paddles;
|
||||
extern int g_joystick_type;
|
||||
extern int g_a2vid_palette;
|
||||
extern int g_config_control_panel;
|
||||
extern word32 g_cfg_vbl_count;
|
||||
extern double g_cur_dcycs;
|
||||
|
||||
extern byte *g_slow_memory_ptr;
|
||||
extern byte *g_memory_ptr;
|
||||
@ -84,17 +89,23 @@ int g_warp_pointer = 0;
|
||||
int g_hide_pointer = 0;
|
||||
int g_unhide_pointer = 0;
|
||||
|
||||
|
||||
int g_mouse_a2_x = 0;
|
||||
int g_mouse_a2_y = 0;
|
||||
int g_mouse_a2_button = 0;
|
||||
int g_mouse_fifo_pos = 0;
|
||||
int g_mouse_raw_x = 0;
|
||||
int g_mouse_raw_y = 0;
|
||||
|
||||
#define ADB_MOUSE_FIFO 8
|
||||
|
||||
int g_mouse_fifo_x[ADB_MOUSE_FIFO] = { 0 };
|
||||
int g_mouse_fifo_y[ADB_MOUSE_FIFO] = { 0 };
|
||||
int g_mouse_fifo_buttons[ADB_MOUSE_FIFO] = { 0 };
|
||||
STRUCT(Mouse_fifo) {
|
||||
double dcycs;
|
||||
int x;
|
||||
int y;
|
||||
int buttons;
|
||||
};
|
||||
|
||||
Mouse_fifo g_mouse_fifo[ADB_MOUSE_FIFO] = { { 0, 0, 0, 0 } };
|
||||
|
||||
int g_mouse_warp_x = 0;
|
||||
int g_mouse_warp_y = 0;
|
||||
@ -102,11 +113,6 @@ int g_mouse_warp_y = 0;
|
||||
int g_adb_mouse_valid_data = 0;
|
||||
int g_adb_mouse_coord = 0;
|
||||
|
||||
int g_adb_data_int_sent = 0;
|
||||
int g_adb_mouse_int_sent = 0;
|
||||
int g_adb_kbd_srq_sent = 0;
|
||||
|
||||
|
||||
#define MAX_KBD_BUF 8
|
||||
|
||||
int g_key_down = 0;
|
||||
@ -129,6 +135,10 @@ int g_mouse_ctl_addr = 3; /* ADB ucontroller's mouse addr*/
|
||||
word32 g_virtual_key_up[4]; /* bitmask of all possible 128 a2codes */
|
||||
/* indicates which keys are up=1 by bit */
|
||||
|
||||
int g_keypad_key_is_down[10] = { 0 };/* List from 0-9 of which keypad */
|
||||
/* keys are currently pressed */
|
||||
|
||||
|
||||
#define SHIFT_DOWN ( (g_c025_val & 0x01) )
|
||||
#define CTRL_DOWN ( (g_c025_val & 0x02) )
|
||||
#define CAPS_LOCK_DOWN ( (g_c025_val & 0x04) )
|
||||
@ -171,6 +181,10 @@ adb_init()
|
||||
g_virtual_key_up[i] = -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < 10; i++) {
|
||||
g_keypad_key_is_down[i] = 0;
|
||||
}
|
||||
|
||||
adb_reset();
|
||||
}
|
||||
|
||||
@ -189,9 +203,9 @@ adb_reset()
|
||||
g_kbd_ctl_addr = 2;
|
||||
g_mouse_ctl_addr = 3;
|
||||
|
||||
g_adb_data_int_sent = 0;
|
||||
g_adb_mouse_int_sent = 0;
|
||||
g_adb_kbd_srq_sent = 0;
|
||||
adb_clear_data_int();
|
||||
adb_clear_mouse_int();
|
||||
adb_clear_kbd_srq();
|
||||
|
||||
g_adb_data_pending = 0;
|
||||
g_adb_interrupt_byte = 0;
|
||||
@ -201,6 +215,7 @@ adb_reset()
|
||||
|
||||
g_kbd_reg0_pos = 0;
|
||||
g_kbd_reg3_16bit = 0x602;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -250,8 +265,6 @@ show_adb_log(void)
|
||||
printf("kbd: dev: %x, ctl: %x; mouse: dev: %x, ctl: %x\n",
|
||||
g_kbd_dev_addr, g_kbd_ctl_addr,
|
||||
g_mouse_dev_addr, g_mouse_ctl_addr);
|
||||
printf("adb_data_int_sent: %d, adb_kbd_srq_sent: %d, mouse_int: %d\n",
|
||||
g_adb_data_int_sent, g_adb_kbd_srq_sent, g_adb_mouse_int_sent);
|
||||
printf("g_adb_state: %d, g_adb_interrupt_byte: %02x\n",
|
||||
g_adb_state, g_adb_interrupt_byte);
|
||||
}
|
||||
@ -271,11 +284,8 @@ adb_add_kbd_srq()
|
||||
{
|
||||
if(g_kbd_reg3_16bit & 0x200) {
|
||||
/* generate SRQ */
|
||||
g_adb_interrupt_byte |= 0x08;;
|
||||
if(!g_adb_kbd_srq_sent) {
|
||||
g_adb_kbd_srq_sent = 1;
|
||||
add_irq();
|
||||
}
|
||||
g_adb_interrupt_byte |= 0x08;
|
||||
add_irq(IRQ_PENDING_ADB_KBD_SRQ);
|
||||
} else {
|
||||
printf("Got keycode but no kbd SRQ!\n");
|
||||
}
|
||||
@ -284,10 +294,7 @@ adb_add_kbd_srq()
|
||||
void
|
||||
adb_clear_kbd_srq()
|
||||
{
|
||||
if(g_adb_kbd_srq_sent) {
|
||||
remove_irq();
|
||||
g_adb_kbd_srq_sent = 0;
|
||||
}
|
||||
remove_irq(IRQ_PENDING_ADB_KBD_SRQ);
|
||||
|
||||
/* kbd SRQ's are the only ones to handle now, so just clean it out */
|
||||
g_adb_interrupt_byte &= (~(0x08));
|
||||
@ -297,10 +304,7 @@ void
|
||||
adb_add_data_int()
|
||||
{
|
||||
if(g_c027_val & ADB_C027_DATA_INT) {
|
||||
if(!g_adb_data_int_sent) {
|
||||
g_adb_data_int_sent = 1;
|
||||
add_irq();
|
||||
}
|
||||
add_irq(IRQ_PENDING_ADB_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,31 +312,20 @@ void
|
||||
adb_add_mouse_int()
|
||||
{
|
||||
if(g_c027_val & ADB_C027_MOUSE_INT) {
|
||||
if(!g_adb_mouse_int_sent) {
|
||||
/* printf("Mouse int sent\n"); */
|
||||
g_adb_mouse_int_sent = 1;
|
||||
add_irq();
|
||||
}
|
||||
add_irq(IRQ_PENDING_ADB_MOUSE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
adb_clear_data_int()
|
||||
{
|
||||
if(g_adb_data_int_sent) {
|
||||
remove_irq();
|
||||
g_adb_data_int_sent = 0;
|
||||
}
|
||||
remove_irq(IRQ_PENDING_ADB_DATA);
|
||||
}
|
||||
|
||||
void
|
||||
adb_clear_mouse_int()
|
||||
{
|
||||
if(g_adb_mouse_int_sent) {
|
||||
remove_irq();
|
||||
g_adb_mouse_int_sent = 0;
|
||||
/* printf("Mouse int clear, button: %d\n", g_mouse_a2_button);*/
|
||||
}
|
||||
remove_irq(IRQ_PENDING_ADB_MOUSE);
|
||||
}
|
||||
|
||||
|
||||
@ -580,7 +573,7 @@ adb_read_c026()
|
||||
case ADB_IDLE:
|
||||
ret = g_adb_interrupt_byte;
|
||||
g_adb_interrupt_byte = 0;
|
||||
if(g_adb_kbd_srq_sent) {
|
||||
if(g_irq_pending & IRQ_PENDING_ADB_KBD_SRQ) {
|
||||
g_adb_interrupt_byte |= 0x08;
|
||||
}
|
||||
if(g_adb_data_pending == 0) {
|
||||
@ -1087,15 +1080,57 @@ write_adb_ram(word32 addr, int val)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
adb_get_keypad_xy(int get_y)
|
||||
{
|
||||
int x, y;
|
||||
int key;
|
||||
int num_keys;
|
||||
int i, j;
|
||||
|
||||
key = 1;
|
||||
num_keys = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
for(i = 0; i < 3; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
if(g_keypad_key_is_down[key]) {
|
||||
num_keys++;
|
||||
x = x + (j - 1)*32768;
|
||||
y = y + (1 - i)*32768;
|
||||
}
|
||||
key++;
|
||||
}
|
||||
}
|
||||
if(num_keys == 0) {
|
||||
num_keys = 1;
|
||||
}
|
||||
|
||||
adb_printf("get_xy=%d, num_keys: %d, x:%d, y:%d\n", get_y,
|
||||
num_keys, x, y);
|
||||
|
||||
if(get_y) {
|
||||
return y / num_keys;
|
||||
} else {
|
||||
return x / num_keys;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
update_mouse(int x, int y, int button_states, int buttons_valid)
|
||||
{
|
||||
double dcycs;
|
||||
int button1_changed;
|
||||
int mouse_moved;
|
||||
int unhide;
|
||||
int pos;
|
||||
int i;
|
||||
|
||||
dcycs = g_cur_dcycs;
|
||||
|
||||
g_mouse_raw_x = x;
|
||||
g_mouse_raw_y = y;
|
||||
|
||||
unhide = 0;
|
||||
if(x < 0) {
|
||||
x = 0;
|
||||
@ -1132,47 +1167,50 @@ update_mouse(int x, int y, int button_states, int buttons_valid)
|
||||
y = y >> 1;
|
||||
}
|
||||
|
||||
mouse_compress_fifo(dcycs);
|
||||
|
||||
#if 0
|
||||
printf("Update Mouse called with buttons:%d x,y:%d,%d, fifo:%d,%d, "
|
||||
" a2: %d,%d\n", buttons_valid, x, y,
|
||||
g_mouse_fifo_x[0], g_mouse_fifo_y[0],
|
||||
g_mouse_fifo[0].x, g_mouse_fifo[0].y,
|
||||
g_mouse_a2_x, g_mouse_a2_y);
|
||||
#endif
|
||||
|
||||
if((buttons_valid < 0) && g_warp_pointer) {
|
||||
/* Warping the pointer causes it to jump here...this is not */
|
||||
/* real motion, just update info and get out */
|
||||
g_mouse_a2_x += (x - g_mouse_fifo_x[0]);
|
||||
g_mouse_a2_y += (y - g_mouse_fifo_y[0]);
|
||||
g_mouse_fifo_x[0] = x;
|
||||
g_mouse_fifo_y[0] = y;
|
||||
g_mouse_a2_x += (x - g_mouse_fifo[0].x);
|
||||
g_mouse_a2_y += (y - g_mouse_fifo[0].y);
|
||||
g_mouse_fifo[0].x = x;
|
||||
g_mouse_fifo[0].y = y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("...real move, warp: %d, %d, new x: %d, %d, a2:%d,%d\n",
|
||||
g_mouse_warp_x, g_mouse_warp_y, g_mouse_fifo_x[0],
|
||||
g_mouse_fifo_y[0], g_mouse_a2_x, g_mouse_a2_y);
|
||||
g_mouse_warp_x, g_mouse_warp_y, g_mouse_fifo[0].x,
|
||||
g_mouse_fifo[0].y, g_mouse_a2_x, g_mouse_a2_y);
|
||||
#endif
|
||||
|
||||
mouse_moved = (g_mouse_fifo_x[0] != x) || (g_mouse_fifo_y[0] != y);
|
||||
mouse_moved = (g_mouse_fifo[0].x != x) || (g_mouse_fifo[0].y != y);
|
||||
|
||||
g_mouse_a2_x += g_mouse_warp_x;
|
||||
g_mouse_a2_y += g_mouse_warp_y;
|
||||
g_mouse_fifo_x[0] = x;
|
||||
g_mouse_fifo_y[0] = y;
|
||||
g_mouse_fifo[0].x = x;
|
||||
g_mouse_fifo[0].y = y;
|
||||
g_mouse_fifo[0].dcycs = dcycs;
|
||||
g_mouse_warp_x = 0;
|
||||
g_mouse_warp_y = 0;
|
||||
|
||||
button1_changed = (buttons_valid & 1) &&
|
||||
((button_states & 1) != (g_mouse_fifo_buttons[0] & 1));
|
||||
((button_states & 1) != (g_mouse_fifo[0].buttons & 1));
|
||||
|
||||
if((button_states & 4) && !(g_mouse_fifo_buttons[0] & 4) &&
|
||||
if((button_states & 4) && !(g_mouse_fifo[0].buttons & 4) &&
|
||||
(buttons_valid & 4)) {
|
||||
/* right button pressed */
|
||||
adb_increment_speed();
|
||||
}
|
||||
if((button_states & 2) && !(g_mouse_fifo_buttons[0] & 2) &&
|
||||
if((button_states & 2) && !(g_mouse_fifo[0].buttons & 2) &&
|
||||
(buttons_valid & 2)) {
|
||||
/* middle button pressed */
|
||||
halt2_printf("Middle button pressed\n");
|
||||
@ -1185,15 +1223,13 @@ update_mouse(int x, int y, int button_states, int buttons_valid)
|
||||
/* button up/down times. Using a mouse event list where */
|
||||
/* deltas accumulate until a button change would work, too */
|
||||
for(i = pos; i >= 0; i--) {
|
||||
g_mouse_fifo_x[i + 1] = g_mouse_fifo_x[i];
|
||||
g_mouse_fifo_y[i + 1] = g_mouse_fifo_y[i];
|
||||
g_mouse_fifo_buttons[i + 1] = g_mouse_fifo_buttons[i]&1;
|
||||
g_mouse_fifo[i + 1] = g_mouse_fifo[i]; /* copy struct*/
|
||||
}
|
||||
g_mouse_fifo_pos = pos + 1;
|
||||
}
|
||||
|
||||
g_mouse_fifo_buttons[0] = (button_states & buttons_valid) |
|
||||
(g_mouse_fifo_buttons[0] & ~buttons_valid);
|
||||
g_mouse_fifo[0].buttons = (button_states & buttons_valid) |
|
||||
(g_mouse_fifo[0].buttons & ~buttons_valid);
|
||||
|
||||
if(mouse_moved || button1_changed) {
|
||||
if( (g_mouse_ctl_addr == g_mouse_dev_addr) &&
|
||||
@ -1226,10 +1262,12 @@ mouse_read_c024(double dcycs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mouse_compress_fifo(dcycs);
|
||||
|
||||
pos = g_mouse_fifo_pos;
|
||||
target_x = g_mouse_fifo_x[pos];
|
||||
target_y = g_mouse_fifo_y[pos];
|
||||
mouse_button = (g_mouse_fifo_buttons[pos] & 1);
|
||||
target_x = g_mouse_fifo[pos].x;
|
||||
target_y = g_mouse_fifo[pos].y;
|
||||
mouse_button = (g_mouse_fifo[pos].buttons & 1);
|
||||
delta_x = target_x - g_mouse_a2_x;
|
||||
delta_y = target_y - g_mouse_a2_y;
|
||||
|
||||
@ -1253,7 +1291,7 @@ mouse_read_c024(double dcycs)
|
||||
/* peek into next entry's button info if we are not clamped */
|
||||
/* and we're returning the y-coord */
|
||||
if(!clamped && g_adb_mouse_coord) {
|
||||
mouse_button = g_mouse_fifo_buttons[pos - 1] & 1;
|
||||
mouse_button = g_mouse_fifo[pos - 1].buttons & 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1351,9 +1389,9 @@ mouse_read_c024(double dcycs)
|
||||
g_slow_memory_ptr[0x10190], g_slow_memory_ptr[0x10192],
|
||||
g_slow_memory_ptr[0x10191], g_slow_memory_ptr[0x10193]);
|
||||
|
||||
if((g_mouse_fifo_pos == 0) && (g_mouse_fifo_x[0] == a2_x) &&
|
||||
(g_mouse_fifo_y[0] == a2_y) &&
|
||||
((g_mouse_fifo_buttons[0] & 1) == g_mouse_a2_button)) {
|
||||
if((g_mouse_fifo_pos == 0) && (g_mouse_fifo[0].x == a2_x) &&
|
||||
(g_mouse_fifo[0].y == a2_y) &&
|
||||
((g_mouse_fifo[0].buttons & 1) == g_mouse_a2_button)) {
|
||||
g_adb_mouse_valid_data = 0;
|
||||
adb_clear_mouse_int();
|
||||
}
|
||||
@ -1362,6 +1400,29 @@ mouse_read_c024(double dcycs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
mouse_compress_fifo(double dcycs)
|
||||
{
|
||||
int pos;
|
||||
|
||||
/* The mouse fifo exists so that fast button changes don't get lost */
|
||||
/* if the emulator lags behind the mouse events */
|
||||
/* But the FIFO means really old mouse events are saved if */
|
||||
/* the emulated code isn't looking at the mouse registers */
|
||||
/* This routine compresses all mouse events > 0.5 seconds old */
|
||||
|
||||
for(pos = g_mouse_fifo_pos; pos >= 1; pos--) {
|
||||
if(g_mouse_fifo[pos].dcycs < (dcycs - 500*1000.0)) {
|
||||
/* Remove this entry */
|
||||
adb_printf("Old mouse FIFO pos %d removed\n", pos);
|
||||
g_mouse_fifo_pos = pos - 1;
|
||||
continue;
|
||||
}
|
||||
/* Else, stop searching the FIFO */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
adb_key_event(int a2code, int is_up)
|
||||
{
|
||||
@ -1489,7 +1550,8 @@ adb_read_c000()
|
||||
/* got one */
|
||||
if((g_kbd_read_no_update++ > 5) && (g_kbd_chars_buffered > 1)) {
|
||||
/* read 5 times, keys pending, let's move it along */
|
||||
printf("Read %02x 3 times, tossing\n", g_kbd_buf[0]);
|
||||
printf("Read %02x %d times, tossing\n", g_kbd_buf[0],
|
||||
g_kbd_read_no_update);
|
||||
adb_access_c010();
|
||||
}
|
||||
} else {
|
||||
@ -1583,7 +1645,8 @@ adb_physical_key_update(int a2code, int is_up)
|
||||
{
|
||||
int autopoll;
|
||||
int special;
|
||||
int tmp;
|
||||
int ascii_and_type;
|
||||
int ascii;
|
||||
|
||||
/* this routine called by xdriver to pass raw codes--handle */
|
||||
/* ucontroller and ADB bus protocol issues here */
|
||||
@ -1599,17 +1662,17 @@ adb_physical_key_update(int a2code, int is_up)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remap 0x7b-0x7e to 0x3b-0x3e (arrow keys on new mac keyboards */
|
||||
/* Remap 0x7b-0x7e to 0x3b-0x3e (arrow keys on new mac keyboards) */
|
||||
if(a2code >= 0x7b && a2code <= 0x7e) {
|
||||
a2code = a2code - 0x40;
|
||||
}
|
||||
|
||||
/* Now check for special keys (function keys, etc) */
|
||||
tmp = a2_key_to_ascii[a2code][1];
|
||||
ascii_and_type = a2_key_to_ascii[a2code][1];
|
||||
special = 0;
|
||||
if((tmp & 0xf000) == 0x8000) {
|
||||
if((ascii_and_type & 0xf000) == 0x8000) {
|
||||
/* special function key */
|
||||
special = tmp & 0xff;
|
||||
special = ascii_and_type & 0xff;
|
||||
switch(special) {
|
||||
case 0x01: /* F1 - remap to cmd */
|
||||
a2code = 0x37;
|
||||
@ -1643,7 +1706,7 @@ adb_physical_key_update(int a2code, int is_up)
|
||||
if(special && !is_up) {
|
||||
switch(special) {
|
||||
case 0x04: /* F4 - Emulator config panel */
|
||||
g_config_control_panel = !g_config_control_panel;
|
||||
cfg_toggle_config_panel();
|
||||
break;
|
||||
case 0x06: /* F6 - emulator speed */
|
||||
if(SHIFT_DOWN) {
|
||||
@ -1679,13 +1742,38 @@ adb_physical_key_update(int a2code, int is_up)
|
||||
change_a2vid_palette((g_a2vid_palette + 1) & 0xf);
|
||||
break;
|
||||
case 0x0b: /* F11 - full screen */
|
||||
/* g_fullscreen = !g_fullscreen; */
|
||||
/* x_full_screen(g_full_screen); */
|
||||
g_fullscreen = !g_fullscreen;
|
||||
x_full_screen(g_fullscreen);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/* Handle Keypad Joystick here partly...if keypad key pressed */
|
||||
/* while in Keypad Joystick mode, do not pass it on as a key press */
|
||||
if((ascii_and_type & 0xff00) == 0x1000) {
|
||||
/* Keep track of keypad number keys being up or down even */
|
||||
/* if joystick mode isn't keypad. This avoid funny cases */
|
||||
/* if joystick mode is changed while a key is pressed */
|
||||
ascii = ascii_and_type & 0xff;
|
||||
if(ascii > 0x30 && ascii <= 0x39) {
|
||||
g_keypad_key_is_down[ascii - 0x30] = !is_up;
|
||||
}
|
||||
if(g_joystick_type == 0) {
|
||||
/* If Joystick type is keypad, then do not let these */
|
||||
/* keypress pass on further, except for cmd/opt */
|
||||
if(ascii == 0x30) {
|
||||
/* remap '0' to cmd */
|
||||
a2code = 0x37;
|
||||
} else if(ascii == 0x2e || ascii == 0x2c) {
|
||||
/* remap '.' and ',' to option */
|
||||
a2code = 0x3a;
|
||||
} else {
|
||||
/* Just ignore it in this mode */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
autopoll = 1;
|
||||
if(g_adb_mode & 1) {
|
||||
@ -1753,6 +1841,23 @@ adb_virtual_key_update(int a2code, int is_up)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
adb_all_keys_up()
|
||||
{
|
||||
word32 mask;
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(j = 0; j < 32; j++) {
|
||||
mask = 1 << j;
|
||||
if((g_virtual_key_up[i] & mask) == 0) {
|
||||
/* create key-up event */
|
||||
adb_physical_key_update(i*32 + j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
adb_kbd_repeat_off()
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_adb_h[] = "@(#)$KmKId: adb.h,v 1.9 2002-11-19 03:10:38-05 kadickey Exp $";
|
||||
const char rcsid_adb_h[] = "@(#)$KmKId: adb.h,v 1.11 2004-10-13 23:30:33-04 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
|
||||
@ -87,7 +87,7 @@ const int a2_key_to_ascii[][4] = {
|
||||
{ 0x3f, -1, -1, -1 },
|
||||
|
||||
{ 0x40, -1, -1, -1 },
|
||||
{ 0x41, 0x102e, 0x102e, -1 }, /* keypad . */
|
||||
{ 0x41, 0x102e, 0x102c, -1 }, /* keypad . */
|
||||
{ 0x42, -1, -1, -1 },
|
||||
{ 0x43, 0x102a, 0x102a, -1 }, /* keypad * */
|
||||
{ 0x44, -1, -1, -1 },
|
||||
@ -115,7 +115,7 @@ const int a2_key_to_ascii[][4] = {
|
||||
|
||||
{ 0x58, 0x1036, 0x1036, -1 }, /* keypad 6 */
|
||||
{ 0x59, 0x1037, 0x1037, -1 }, /* keypad 7 */
|
||||
{ 0x5a, -1, -1, -1 },
|
||||
{ 0x5a, 'a', 'A', 0x01 }, /* probably not necessary */
|
||||
{ 0x5b, 0x1038, 0x1038, -1 }, /* keypad 8 */
|
||||
{ 0x5c, 0x1039, 0x1039, -1 }, /* keypad 9 */
|
||||
{ 0x5d, -1, -1, -1 },
|
||||
@ -137,7 +137,7 @@ const int a2_key_to_ascii[][4] = {
|
||||
{ 0x6b, 0x800e, 0x106b, -1 }, /* F14 */
|
||||
{ 0x6c, -1, -1, -1 },
|
||||
{ 0x6d, 0x800a, 0x106d, -1 }, /* F10 */
|
||||
{ 0x6e, -1, -1, -1 },
|
||||
{ 0x6e, 0x4000, 0x4000, -1 }, /* windows key alias to option */
|
||||
{ 0x6f, 0x800c, 0x106f, -1 }, /* F12 */
|
||||
|
||||
{ 0x70, -1, -1, -1 },
|
||||
|
82
src/clock.c
82
src/clock.c
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_clock_c[] = "@(#)$KmKId: clock.c,v 1.29 2003-10-17 15:07:35-04 kentd Exp $";
|
||||
const char rcsid_clock_c[] = "@(#)$KmKId: clock.c,v 1.31 2004-10-19 17:32:07-04 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
#include <time.h>
|
||||
@ -34,8 +34,8 @@ int g_clk_mode = CLK_IDLE;
|
||||
int g_clk_read = 0;
|
||||
int g_clk_reg1 = 0;
|
||||
|
||||
word32 c033_data = 0;
|
||||
word32 c034_val = 0;
|
||||
extern int g_c033_data;
|
||||
extern int g_c034_val;
|
||||
|
||||
byte g_bram[2][256];
|
||||
byte *g_bram_ptr = &(g_bram[0][0]);
|
||||
@ -173,12 +173,19 @@ update_cur_time()
|
||||
tm_ptr = localtime(&cur_time);
|
||||
secs = mktime(tm_ptr);
|
||||
|
||||
#ifdef MAC
|
||||
/* Mac OS X's mktime function modifies the tm_ptr passed in for */
|
||||
/* the CDT timezone and breaks this algorithm. So on a Mac, we */
|
||||
/* will use the tm_ptr->gmtoff member to correct the time */
|
||||
secs = secs + tm_ptr->tm_gmtoff;
|
||||
#else
|
||||
secs = (unsigned int)cur_time - (secs2 - secs);
|
||||
|
||||
if(tm_ptr->tm_isdst) {
|
||||
/* adjust for daylight savings time */
|
||||
secs += 3600;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* add in secs to make date based on Apple Jan 1, 1904 instead of */
|
||||
/* Unix's Jan 1, 1970 */
|
||||
@ -210,28 +217,10 @@ clock_update_if_needed()
|
||||
}
|
||||
}
|
||||
|
||||
word32
|
||||
clock_read_c033()
|
||||
{
|
||||
return c033_data;
|
||||
}
|
||||
|
||||
word32
|
||||
clock_read_c034()
|
||||
{
|
||||
return c034_val;
|
||||
}
|
||||
|
||||
void
|
||||
clock_write_c033(word32 val)
|
||||
{
|
||||
c033_data = val;
|
||||
}
|
||||
|
||||
void
|
||||
clock_write_c034(word32 val)
|
||||
{
|
||||
c034_val = val & 0x7f;
|
||||
g_c034_val = val & 0x7f;
|
||||
if((val & 0x80) != 0) {
|
||||
if((val & 0x20) == 0) {
|
||||
printf("c034 write not last = 1\n");
|
||||
@ -251,12 +240,12 @@ do_clock_data()
|
||||
|
||||
clk_printf("In do_clock_data, g_clk_mode: %02x\n", g_clk_mode);
|
||||
|
||||
read = c034_val & 0x40;
|
||||
read = g_c034_val & 0x40;
|
||||
switch(g_clk_mode) {
|
||||
case CLK_IDLE:
|
||||
g_clk_read = (c033_data >> 7) & 1;
|
||||
g_clk_reg1 = (c033_data >> 2) & 3;
|
||||
op = (c033_data >> 4) & 7;
|
||||
g_clk_read = (g_c033_data >> 7) & 1;
|
||||
g_clk_reg1 = (g_c033_data >> 2) & 3;
|
||||
op = (g_c033_data >> 4) & 7;
|
||||
if(!read) {
|
||||
/* write */
|
||||
switch(op) {
|
||||
@ -269,7 +258,7 @@ do_clock_data()
|
||||
if(g_clk_reg1 & 0x2) {
|
||||
/* extend BRAM read */
|
||||
g_clk_mode = CLK_BRAM2;
|
||||
g_clk_reg1 = (c033_data & 7) << 5;
|
||||
g_clk_reg1 = (g_c033_data & 7) << 5;
|
||||
}
|
||||
break;
|
||||
case 0x2: /* read/write ram 0x10-0x13 */
|
||||
@ -279,11 +268,11 @@ do_clock_data()
|
||||
case 0x4: /* read/write ram 0x00-0x0f */
|
||||
case 0x5: case 0x6: case 0x7:
|
||||
g_clk_mode = CLK_BRAM1;
|
||||
g_clk_reg1 = (c033_data >> 2) & 0xf;
|
||||
g_clk_reg1 = (g_c033_data >> 2) & 0xf;
|
||||
break;
|
||||
default:
|
||||
halt_printf("Bad c033_data in CLK_IDLE: %02x\n",
|
||||
c033_data);
|
||||
g_c033_data);
|
||||
}
|
||||
} else {
|
||||
printf("clk read from IDLE mode!\n");
|
||||
@ -294,13 +283,13 @@ do_clock_data()
|
||||
case CLK_BRAM2:
|
||||
if(!read) {
|
||||
/* get more bits of bram addr */
|
||||
if((c033_data & 0x83) == 0x00) {
|
||||
if((g_c033_data & 0x83) == 0x00) {
|
||||
/* more address bits */
|
||||
g_clk_reg1 |= ((c033_data >> 2) & 0x1f);
|
||||
g_clk_reg1 |= ((g_c033_data >> 2) & 0x1f);
|
||||
g_clk_mode = CLK_BRAM1;
|
||||
} else {
|
||||
halt_printf("CLK_BRAM2: c033_data: %02x!\n",
|
||||
c033_data);
|
||||
g_c033_data);
|
||||
g_clk_mode = CLK_IDLE;
|
||||
}
|
||||
} else {
|
||||
@ -313,9 +302,9 @@ do_clock_data()
|
||||
if(read) {
|
||||
if(g_clk_read) {
|
||||
/* Yup, read */
|
||||
c033_data = g_bram_ptr[g_clk_reg1];
|
||||
g_c033_data = g_bram_ptr[g_clk_reg1];
|
||||
clk_printf("Reading BRAM loc %02x: %02x\n",
|
||||
g_clk_reg1, c033_data);
|
||||
g_clk_reg1, g_c033_data);
|
||||
} else {
|
||||
halt_printf("CLK_BRAM1: said wr, now read\n");
|
||||
}
|
||||
@ -325,8 +314,8 @@ do_clock_data()
|
||||
} else {
|
||||
/* Yup, write */
|
||||
clk_printf("Writing BRAM loc %02x with %02x\n",
|
||||
g_clk_reg1, c033_data);
|
||||
g_bram_ptr[g_clk_reg1] = c033_data;
|
||||
g_clk_reg1, g_c033_data);
|
||||
g_bram_ptr[g_clk_reg1] = g_c033_data;
|
||||
g_config_kegs_update_needed = 1;
|
||||
}
|
||||
}
|
||||
@ -337,20 +326,21 @@ do_clock_data()
|
||||
if(g_clk_read == 0) {
|
||||
halt_printf("Reading time, but in set mode!\n");
|
||||
}
|
||||
c033_data = (g_clk_cur_time >> (g_clk_reg1 * 8)) & 0xff;
|
||||
g_c033_data = (g_clk_cur_time >> (g_clk_reg1 * 8)) &
|
||||
0xff;
|
||||
clk_printf("Returning time byte %d: %02x\n",
|
||||
g_clk_reg1, c033_data);
|
||||
g_clk_reg1, g_c033_data);
|
||||
} else {
|
||||
/* Write */
|
||||
if(g_clk_read) {
|
||||
halt_printf("Write time, but in read mode!\n");
|
||||
}
|
||||
clk_printf("Writing TIME loc %d with %02x\n",
|
||||
g_clk_reg1, c033_data);
|
||||
g_clk_reg1, g_c033_data);
|
||||
mask = 0xff << (8 * g_clk_reg1);
|
||||
|
||||
g_clk_cur_time = (g_clk_cur_time & (~mask)) |
|
||||
((c033_data & 0xff) << (8 *g_clk_reg1));
|
||||
((g_c033_data & 0xff) << (8 * g_clk_reg1));
|
||||
}
|
||||
g_clk_mode = CLK_IDLE;
|
||||
break;
|
||||
@ -361,24 +351,24 @@ do_clock_data()
|
||||
} else {
|
||||
switch(g_clk_reg1) {
|
||||
case 0x0: /* test register */
|
||||
if(c033_data & 0xc0) {
|
||||
if(g_c033_data & 0xc0) {
|
||||
printf("Writing test reg: %02x!\n",
|
||||
c033_data);
|
||||
g_c033_data);
|
||||
/* set_halt(1); */
|
||||
}
|
||||
break;
|
||||
case 0x1: /* write protect reg */
|
||||
clk_printf("Writing clk wr_protect: %02x\n",
|
||||
c033_data);
|
||||
if(c033_data & 0x80) {
|
||||
g_c033_data);
|
||||
if(g_c033_data & 0x80) {
|
||||
printf("Stop, wr clk wr_prot: %02x\n",
|
||||
c033_data);
|
||||
g_c033_data);
|
||||
/* set_halt(1); */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
halt_printf("Writing int reg: %02x with %02x\n",
|
||||
g_clk_reg1, c033_data);
|
||||
g_clk_reg1, g_c033_data);
|
||||
}
|
||||
}
|
||||
g_clk_mode = CLK_IDLE;
|
||||
|
719
src/config.c
719
src/config.c
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/************************************************************************/
|
||||
/* KEGS: Apple //gs Emulator */
|
||||
/* Copyright 2003 by Kent Dickey */
|
||||
/* Copyright 2003-2004 by Kent Dickey */
|
||||
/* */
|
||||
/* This code is covered by the GNU GPL */
|
||||
/* */
|
||||
@ -9,7 +9,7 @@
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_RCSID_C
|
||||
const char rcsid_config_h[] = "@(#)$KmKId: config.h,v 1.8 2003-10-17 15:09:58-04 kentd Exp $";
|
||||
const char rcsid_config_h[] = "@(#)$KmKId: config.h,v 1.9 2004-11-12 23:10:28-05 kentd Exp $";
|
||||
#endif
|
||||
|
||||
#define CONF_BUF_LEN 1024
|
||||
@ -24,6 +24,7 @@ const char rcsid_config_h[] = "@(#)$KmKId: config.h,v 1.8 2003-10-17 15:09:58-04
|
||||
#define CFGTYPE_INT 2
|
||||
#define CFGTYPE_DISK 3
|
||||
#define CFGTYPE_FUNC 4
|
||||
#define CFGTYPE_FILE 5
|
||||
/* CFGTYPE limited to just 4 bits: 0-15 */
|
||||
|
||||
/* Cfg_menu, Cfg_dirent and Cfg_listhdr are defined in defc.h */
|
||||
@ -31,4 +32,5 @@ const char rcsid_config_h[] = "@(#)$KmKId: config.h,v 1.8 2003-10-17 15:09:58-04
|
||||
STRUCT(Cfg_defval) {
|
||||
Cfg_menu *menuptr;
|
||||
int intval;
|
||||
char *strval;
|
||||
};
|
||||
|
70
src/defc.h
70
src/defc.h
@ -9,7 +9,7 @@
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_RCSID_C
|
||||
const char rcsid_defc_h[] = "@(#)$KmKId: defc.h,v 1.91 2003-11-03 01:29:38-05 kentd Exp $";
|
||||
const char rcsid_defc_h[] = "@(#)$KmKId: defc.h,v 1.100 2004-11-09 02:02:07-05 kentd Exp $";
|
||||
#endif
|
||||
|
||||
#include "defcomm.h"
|
||||
@ -34,7 +34,10 @@ void U_STACK_TRACE();
|
||||
#define DCYCS_1_MHZ ((DCYCS_28_MHZ/28.0)*(65.0*7/(65.0*7+1.0)))
|
||||
#define CYCS_1_MHZ ((int)DCYCS_1_MHZ)
|
||||
|
||||
#define DCYCS_IN_16MS_RAW (DCYCS_1_MHZ / 60.0)
|
||||
/* #define DCYCS_IN_16MS_RAW (DCYCS_1_MHZ / 60.0) */
|
||||
#define DCYCS_IN_16MS_RAW (262.0 * 65.0)
|
||||
/* Use precisely 17030 instead of forcing 60 Hz since this is the number of */
|
||||
/* 1MHz cycles per screen */
|
||||
#define DCYCS_IN_16MS ((double)((int)DCYCS_IN_16MS_RAW))
|
||||
#define DRECIP_DCYCS_IN_16MS (1.0 / (DCYCS_IN_16MS))
|
||||
|
||||
@ -70,6 +73,7 @@ void U_STACK_TRACE();
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HPUX
|
||||
# include <machine/inline.h> /* for GET_ITIMER */
|
||||
#endif
|
||||
@ -93,6 +97,13 @@ STRUCT(Pc_log) {
|
||||
word32 pad;
|
||||
};
|
||||
|
||||
STRUCT(Data_log) {
|
||||
double dcycs;
|
||||
word32 addr;
|
||||
word32 val;
|
||||
word32 size;
|
||||
};
|
||||
|
||||
STRUCT(Event) {
|
||||
double dcycs;
|
||||
int type;
|
||||
@ -167,6 +178,21 @@ STRUCT(Cfg_listhdr) {
|
||||
int num_to_show;
|
||||
};
|
||||
|
||||
STRUCT(Emustate_intlist) {
|
||||
const char *str;
|
||||
int *iptr;
|
||||
};
|
||||
|
||||
STRUCT(Emustate_dbllist) {
|
||||
const char *str;
|
||||
double *dptr;
|
||||
};
|
||||
|
||||
STRUCT(Emustate_word32list) {
|
||||
const char *str;
|
||||
word32 *wptr;
|
||||
};
|
||||
|
||||
#ifdef __LP64__
|
||||
# define PTR2WORD(a) ((unsigned long)(a))
|
||||
#else
|
||||
@ -174,14 +200,38 @@ STRUCT(Cfg_listhdr) {
|
||||
#endif
|
||||
|
||||
|
||||
#define ALTZP (statereg & 0x80)
|
||||
#define PAGE2 (statereg & 0x40)
|
||||
#define RAMRD (statereg & 0x20)
|
||||
#define RAMWRT (statereg & 0x10)
|
||||
#define RDROM (statereg & 0x08)
|
||||
#define LCBANK2 (statereg & 0x04)
|
||||
#define ROMB (statereg & 0x02)
|
||||
#define INTCX (statereg & 0x01)
|
||||
#define ALTZP (g_c068_statereg & 0x80)
|
||||
/* #define PAGE2 (g_c068_statereg & 0x40) */
|
||||
#define RAMRD (g_c068_statereg & 0x20)
|
||||
#define RAMWRT (g_c068_statereg & 0x10)
|
||||
#define RDROM (g_c068_statereg & 0x08)
|
||||
#define LCBANK2 (g_c068_statereg & 0x04)
|
||||
#define ROMB (g_c068_statereg & 0x02)
|
||||
#define INTCX (g_c068_statereg & 0x01)
|
||||
|
||||
#define C041_EN_25SEC_INTS 0x10
|
||||
#define C041_EN_VBL_INTS 0x08
|
||||
#define C041_EN_SWITCH_INTS 0x04
|
||||
#define C041_EN_MOVE_INTS 0x02
|
||||
#define C041_EN_MOUSE 0x01
|
||||
|
||||
/* WARNING: SCC1 and SCC0 interrupts must be in this order for scc.c */
|
||||
/* This order matches the SCC hardware */
|
||||
#define IRQ_PENDING_SCC1_ZEROCNT 0x00001
|
||||
#define IRQ_PENDING_SCC1_TX 0x00002
|
||||
#define IRQ_PENDING_SCC1_RX 0x00004
|
||||
#define IRQ_PENDING_SCC0_ZEROCNT 0x00008
|
||||
#define IRQ_PENDING_SCC0_TX 0x00010
|
||||
#define IRQ_PENDING_SCC0_RX 0x00020
|
||||
#define IRQ_PENDING_C023_SCAN 0x00100
|
||||
#define IRQ_PENDING_C023_1SEC 0x00200
|
||||
#define IRQ_PENDING_C046_25SEC 0x00400
|
||||
#define IRQ_PENDING_C046_VBL 0x00800
|
||||
#define IRQ_PENDING_ADB_KBD_SRQ 0x01000
|
||||
#define IRQ_PENDING_ADB_DATA 0x02000
|
||||
#define IRQ_PENDING_ADB_MOUSE 0x04000
|
||||
#define IRQ_PENDING_DOC 0x08000
|
||||
|
||||
|
||||
#define EXTRU(val, pos, len) \
|
||||
( ( (len) >= (pos) + 1) ? ((val) >> (31-(pos))) : \
|
||||
|
@ -9,11 +9,9 @@
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_RCSID_C
|
||||
const char rcsdif_defcomm_h[] = "@(#)$KmKId: defcomm.h,v 1.93 2002-11-19 03:10:38-05 kadickey Exp $";
|
||||
const char rcsdif_defcomm_h[] = "@(#)$KmKId: defcomm.h,v 1.94 2004-10-13 21:53:44-04 kentd Exp $";
|
||||
#endif
|
||||
|
||||
#define USE_XIMAGE_CHANGED
|
||||
|
||||
#if 0
|
||||
# define CHECK_BREAKPOINTS
|
||||
#endif
|
||||
@ -61,25 +59,6 @@ const char rcsdif_defcomm_h[] = "@(#)$KmKId: defcomm.h,v 1.93 2002-11-19 03:10:3
|
||||
#define BANK_BAD_MEM (&g_dummy_memory1_ptr[0xff])
|
||||
|
||||
|
||||
#define LEN_FIFO_BUF 160
|
||||
#define LEN_KBD_BUF 160
|
||||
|
||||
#define FIFO_OK 0x1
|
||||
#define FIFO_INIT 0x2
|
||||
#define FIFO_END 0x3
|
||||
#define FIFO_40COLS 0x4
|
||||
#define FIFO_80COLS 0x5
|
||||
#define FIFO_SENDCHAR 0x6
|
||||
#define FIFO_SENDKEY 0x7
|
||||
#define FIFO_REFRESH 0x8
|
||||
|
||||
#define B_OP_SIZE 2
|
||||
#define B_OP_D_SIZE 5
|
||||
#define B_OP_DTYPE 12
|
||||
#define SIZE_OP_DTYPE 7
|
||||
|
||||
|
||||
|
||||
#define ENGINE_FCYCLES 0x00
|
||||
#define ENGINE_REG_KPC 0x08
|
||||
#define ENGINE_REG_ACC 0x0c
|
||||
@ -189,12 +168,3 @@ const char rcsdif_defcomm_h[] = "@(#)$KmKId: defcomm.h,v 1.93 2002-11-19 03:10:3
|
||||
|
||||
#define A2_BORDER_COLOR_NUM 0xfe
|
||||
|
||||
#if 0
|
||||
#define A2_TEXT_COLOR_ALT_NUM 0x01
|
||||
#define A2_BG_COLOR_ALT_NUM 0x00
|
||||
#define A2_TEXT_COLOR_PRIM_NUM 0x02
|
||||
#define A2_BG_COLOR_PRIM_NUM 0x00
|
||||
#define A2_TEXT_COLOR_FLASH_NUM 0x0c
|
||||
#define A2_BG_COLOR_FLASH_NUM 0x08
|
||||
#endif
|
||||
|
||||
|
356
src/dis.c
356
src/dis.c
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_dis_c[] = "@(#)$KmKId: dis.c,v 1.90 2003-11-18 17:35:30-05 kentd Exp $";
|
||||
const char rcsid_dis_c[] = "@(#)$KmKId: dis.c,v 1.103 2004-11-24 16:41:41-05 kentd Exp $";
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defc.h"
|
||||
@ -20,19 +20,16 @@ const char rcsid_dis_c[] = "@(#)$KmKId: dis.c,v 1.90 2003-11-18 17:35:30-05 kent
|
||||
|
||||
extern byte *g_memory_ptr;
|
||||
extern byte *g_slow_memory_ptr;
|
||||
extern byte *g_rom_fc_ff_ptr;
|
||||
extern byte *g_rom_cards_ptr;
|
||||
extern word32 g_mem_size_base, g_mem_size_exp;
|
||||
extern int halt_sim;
|
||||
extern int enter_debug;
|
||||
extern int statereg;
|
||||
extern int g_c068_statereg;
|
||||
extern word32 stop_run_at;
|
||||
extern int stop_on_c03x;
|
||||
extern int Verbose;
|
||||
extern int Halt_on;
|
||||
extern int g_rom_version;
|
||||
|
||||
extern int g_testing_enabled;
|
||||
extern int g_fullscreen;
|
||||
extern int g_config_control_panel;
|
||||
|
||||
int g_num_breakpoints = 0;
|
||||
word32 g_breakpts[MAX_BREAK_POINTS];
|
||||
@ -48,8 +45,9 @@ int g_stepping = 0;
|
||||
|
||||
word32 list_kpc;
|
||||
int hex_line_len;
|
||||
word32 a1,a2,a3,a4;
|
||||
int a1bank, a2bank, a3bank, a4bank;
|
||||
word32 a1,a2,a3;
|
||||
word32 g_a4, g_a4bank;
|
||||
int a1bank, a2bank, a3bank;
|
||||
char *line_ptr;
|
||||
int mode,old_mode;
|
||||
int got_num;
|
||||
@ -154,9 +152,11 @@ do_debug_intfc()
|
||||
int done;
|
||||
int ret_val;
|
||||
|
||||
g_config_control_panel = 1;
|
||||
|
||||
hex_line_len = 0x10;
|
||||
a1 = 0; a2 = 0; a3 = 0; a4 = 0;
|
||||
a1bank = 0; a2bank = 0; a3bank = 0; a4bank = 0;
|
||||
a1 = 0; a2 = 0; a3 = 0; g_a4 = 0;
|
||||
a1bank = 0; a2bank = 0; a3bank = 0; g_a4bank = 0;
|
||||
list_kpc = engine.kpc;
|
||||
g_stepping = 0;
|
||||
mode = 0; old_mode = 0;
|
||||
@ -164,6 +164,8 @@ do_debug_intfc()
|
||||
stop_run_at = -1;
|
||||
|
||||
x_auto_repeat_on(0);
|
||||
g_fullscreen = 0;
|
||||
x_full_screen(0);
|
||||
|
||||
if(g_quit_sim_now) {
|
||||
printf("Exiting immediately\n");
|
||||
@ -229,10 +231,14 @@ do_debug_intfc()
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
if(got_num) {
|
||||
dis_do_compare();
|
||||
} else {
|
||||
video_show_debug_info();
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
printf("g_irq_pending: %d\n", g_irq_pending);
|
||||
printf("g_irq_pending: %05x\n", g_irq_pending);
|
||||
printf("Setting Verbose ^= %04x\n", a1);
|
||||
Verbose ^= a1;
|
||||
printf("Verbose is now: %04x\n", Verbose);
|
||||
@ -256,8 +262,13 @@ do_debug_intfc()
|
||||
if(engine.psr & 0x100) {
|
||||
engine.psr |= 0x30;
|
||||
}
|
||||
} else {
|
||||
dis_do_memmove();
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
dis_do_pattern_search();
|
||||
break;
|
||||
case 'x':
|
||||
if(old_mode == '=') {
|
||||
if(!a1) {
|
||||
@ -361,6 +372,10 @@ do_debug_intfc()
|
||||
}
|
||||
do_blank();
|
||||
break;
|
||||
case '<':
|
||||
g_a4 = a2;
|
||||
g_a4bank = a2bank;
|
||||
break;
|
||||
case 0x05: /* ctrl-e */
|
||||
show_regs();
|
||||
break;
|
||||
@ -383,10 +398,6 @@ do_debug_intfc()
|
||||
case 'w':
|
||||
read_line(w_buff, W_BUF_LEN);
|
||||
break;
|
||||
case 'X':
|
||||
stop_on_c03x = !stop_on_c03x;
|
||||
printf("stop_on_c03x set to %d\n",stop_on_c03x);
|
||||
break;
|
||||
default:
|
||||
printf("\nUnrecognized command: %s\n",linebuf);
|
||||
*line_ptr = 0;
|
||||
@ -437,7 +448,7 @@ show_toolset_tables(word32 a2bank, word32 addr)
|
||||
|
||||
addr = (a2bank << 16) + (addr & 0xffff);
|
||||
|
||||
toolfile = fopen("tool_set_info", "wt");
|
||||
toolfile = fopen("tool_set_info", "w");
|
||||
if(toolfile == 0) {
|
||||
fprintf(stderr, "fopen of tool_set_info failed: %d\n", errno);
|
||||
exit(2);
|
||||
@ -573,10 +584,14 @@ do_blank()
|
||||
void
|
||||
do_go()
|
||||
{
|
||||
/* also called by do_step */
|
||||
|
||||
g_config_control_panel = 0;
|
||||
clear_halt();
|
||||
|
||||
run_prog();
|
||||
show_regs();
|
||||
g_config_control_panel = 1;
|
||||
}
|
||||
|
||||
void
|
||||
@ -585,11 +600,8 @@ do_step()
|
||||
int size;
|
||||
int size_mem_imm, size_x_imm;
|
||||
|
||||
clear_halt();
|
||||
do_go();
|
||||
|
||||
run_prog();
|
||||
|
||||
show_regs();
|
||||
size_mem_imm = 2;
|
||||
if(engine.psr & 0x20) {
|
||||
size_mem_imm = 1;
|
||||
@ -653,23 +665,56 @@ read_line(char *buf, int len)
|
||||
{
|
||||
int space_left;
|
||||
int ret;
|
||||
#ifndef _WIN32
|
||||
int flags, flags_save;
|
||||
|
||||
/* Unix */
|
||||
flags = fcntl(0, F_GETFL, 0);
|
||||
flags_save = flags;
|
||||
if(flags == -1) {
|
||||
return 0;
|
||||
}
|
||||
ret = fcntl(0, F_SETFL, flags | O_NONBLOCK);
|
||||
if(ret == -1) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
space_left = len;
|
||||
|
||||
ret = 0;
|
||||
buf[0] = 0;
|
||||
ret = 0;
|
||||
while(space_left > 0) {
|
||||
#ifdef _WIN32
|
||||
ret = win_nonblock_read_stdin(0, buf, 1);
|
||||
#else
|
||||
/* Unix */
|
||||
ret = read(0, buf, 1);
|
||||
#endif
|
||||
if(ret <= 0) {
|
||||
printf("read <= 0\n");
|
||||
return(len-space_left);
|
||||
micro_sleep(15.0/60.0);
|
||||
if(errno == EAGAIN) {
|
||||
/* it would block, so no chars--do update */
|
||||
video_update();
|
||||
ret = 0;
|
||||
continue;
|
||||
}
|
||||
printf("read ret %d, errno: %d\n", ret, errno);
|
||||
if(errno == EAGAIN || errno == EINTR) {
|
||||
ret = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
space_left -= ret;
|
||||
if(buf[ret-1] == 0x0a) {
|
||||
return(len-space_left);
|
||||
break;
|
||||
}
|
||||
buf = &buf[ret];
|
||||
}
|
||||
#ifndef _WIN32
|
||||
(void)fcntl(0, F_SETFL, flags_save);
|
||||
#endif
|
||||
|
||||
return (len-space_left);
|
||||
}
|
||||
|
||||
@ -684,7 +729,7 @@ do_debug_list()
|
||||
list_kpc = (a2bank << 16) + (a2 & 0xffff);
|
||||
}
|
||||
printf("%d=m %d=x %d=LCBANK\n", (engine.psr >> 5)&1,
|
||||
(engine.psr >> 4) & 1, (statereg & 0x4) >> 2);
|
||||
(engine.psr >> 4) & 1, (g_c068_statereg & 0x4) >> 2);
|
||||
|
||||
size_mem_imm = 2;
|
||||
if(engine.psr & 0x20) {
|
||||
@ -701,242 +746,45 @@ do_debug_list()
|
||||
}
|
||||
}
|
||||
|
||||
const char *g_kegs_rom_names[] = { "ROM", "ROM.01", "ROM.03", 0 };
|
||||
void
|
||||
dis_do_memmove()
|
||||
{
|
||||
word32 val;
|
||||
|
||||
const char *g_kegs_c1rom_names[] = { 0 };
|
||||
const char *g_kegs_c2rom_names[] = { 0 };
|
||||
const char *g_kegs_c3rom_names[] = { 0 };
|
||||
const char *g_kegs_c4rom_names[] = { 0 };
|
||||
const char *g_kegs_c5rom_names[] = { 0 };
|
||||
const char *g_kegs_c6rom_names[] = { "c600.rom", "controller.rom", "disk.rom",
|
||||
"DISK.ROM", "diskII.prom", 0 };
|
||||
const char *g_kegs_c7rom_names[] = { 0 };
|
||||
|
||||
const char **g_kegs_rom_card_list[8] = {
|
||||
0, g_kegs_c1rom_names,
|
||||
g_kegs_c2rom_names, g_kegs_c3rom_names,
|
||||
g_kegs_c4rom_names, g_kegs_c5rom_names,
|
||||
g_kegs_c6rom_names, g_kegs_c7rom_names };
|
||||
|
||||
byte g_rom_c600_rom01_diffs[256] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xe2, 0x00,
|
||||
0xd0, 0x50, 0x0f, 0x77, 0x5b, 0xb9, 0xc3, 0xb1,
|
||||
0xb1, 0xf8, 0xcb, 0x4e, 0xb8, 0x60, 0xc7, 0x2e,
|
||||
0xfc, 0xe0, 0xbf, 0x1f, 0x66, 0x37, 0x4a, 0x70,
|
||||
0x55, 0x2c, 0x3c, 0xfc, 0xc2, 0xa5, 0x08, 0x29,
|
||||
0xac, 0x21, 0xcc, 0x09, 0x55, 0x03, 0x17, 0x35,
|
||||
0x4e, 0xe2, 0x0c, 0xe9, 0x3f, 0x9d, 0xc2, 0x06,
|
||||
0x18, 0x88, 0x0d, 0x58, 0x57, 0x6d, 0x83, 0x8c,
|
||||
0x22, 0xd3, 0x4f, 0x0a, 0xe5, 0xb7, 0x9f, 0x7d,
|
||||
0x2c, 0x3e, 0xae, 0x7f, 0x24, 0x78, 0xfd, 0xd0,
|
||||
0xb5, 0xd6, 0xe5, 0x26, 0x85, 0x3d, 0x8d, 0xc9,
|
||||
0x79, 0x0c, 0x75, 0xec, 0x98, 0xcc, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x39, 0x00, 0x35, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
|
||||
0x6c, 0x44, 0xce, 0x4c, 0x01, 0x08, 0x00, 0x00
|
||||
};
|
||||
printf("Memory move from %02x/%04x.%04x to %02x/%04x\n", a1bank, a1, a2, g_a4bank, g_a4);
|
||||
while(a1 <= (a2 & 0xffff)) {
|
||||
val = get_memory_c((a1bank << 16) + a1, 0);
|
||||
set_memory_c((g_a4bank << 16) + g_a4, val, 0);
|
||||
a1++;
|
||||
g_a4++;
|
||||
}
|
||||
a1 = a1 & 0xffff;
|
||||
g_a4 = g_a4 & 0xffff;
|
||||
}
|
||||
|
||||
void
|
||||
load_roms()
|
||||
dis_do_pattern_search()
|
||||
{
|
||||
char name_buf[256];
|
||||
struct stat stat_buf;
|
||||
const char **names_ptr;
|
||||
int more_than_8mb;
|
||||
int changed_rom;
|
||||
int len;
|
||||
int fd;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
g_rom_version = 0;
|
||||
setup_kegs_file(&name_buf[0], (int)sizeof(name_buf), 0,
|
||||
&g_kegs_rom_names[0]);
|
||||
fd = open(name_buf, O_RDONLY | O_BINARY);
|
||||
if(fd < 0) {
|
||||
printf("Open ROM file %s failed:%d, errno:%d\n", name_buf, fd,
|
||||
errno);
|
||||
my_exit(-3);
|
||||
printf("Memory pattern search for %04x in %02x/%04x.%04x\n", g_a4, a1bank, a1, a2);
|
||||
}
|
||||
|
||||
ret = fstat(fd, &stat_buf);
|
||||
if(ret != 0) {
|
||||
fprintf(stderr, "fstat returned %d on fd %d, errno: %d\n",
|
||||
ret, fd, errno);
|
||||
my_exit(2);
|
||||
void
|
||||
dis_do_compare()
|
||||
{
|
||||
word32 val1, val2;
|
||||
|
||||
printf("Memory Compare from %02x/%04x.%04x with %02x/%04x\n", a1bank, a1, a2, g_a4bank, g_a4);
|
||||
while(a1 <= (a2 & 0xffff)) {
|
||||
val1 = get_memory_c((a1bank << 16) + a1, 0);
|
||||
val2 = get_memory_c((g_a4bank << 16) + g_a4, 0);
|
||||
if(val1 != val2) {
|
||||
printf("%02x/%04x: %02x vs %02x\n", a1bank, a1, val1, val2);
|
||||
}
|
||||
|
||||
len = stat_buf.st_size;
|
||||
if(len == 128*1024) {
|
||||
g_rom_version = 1;
|
||||
g_mem_size_base = 256*1024;
|
||||
ret = read(fd, &g_rom_fc_ff_ptr[2*65536], len);
|
||||
} else if(len == 256*1024) {
|
||||
g_rom_version = 3;
|
||||
g_mem_size_base = 1024*1024;
|
||||
ret = read(fd, &g_rom_fc_ff_ptr[0], len);
|
||||
} else {
|
||||
fprintf(stderr, "ROM size %d not 128K or 256K\n", len);
|
||||
my_exit(4);
|
||||
}
|
||||
|
||||
printf("Read: %d bytes of ROM\n", ret);
|
||||
if(ret != len) {
|
||||
printf("errno: %d\n", errno);
|
||||
my_exit(-3);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
memset(&g_rom_cards_ptr[0], 0, 256*16);
|
||||
|
||||
/* initialize c600 rom to be diffs from the real ROM, to build-in */
|
||||
/* Apple II compatibility without distributing ROMs */
|
||||
for(i = 0; i < 256; i++) {
|
||||
g_rom_cards_ptr[0x600 + i] = g_rom_fc_ff_ptr[0x3c600 + i] ^
|
||||
g_rom_c600_rom01_diffs[i];
|
||||
}
|
||||
if(g_rom_version >= 3) {
|
||||
/* some patches */
|
||||
g_rom_cards_ptr[0x61b] ^= 0x40;
|
||||
g_rom_cards_ptr[0x61c] ^= 0x33;
|
||||
g_rom_cards_ptr[0x632] ^= 0xc0;
|
||||
g_rom_cards_ptr[0x633] ^= 0x33;
|
||||
}
|
||||
|
||||
for(i = 1; i < 8; i++) {
|
||||
names_ptr = g_kegs_rom_card_list[i];
|
||||
if(names_ptr == 0) {
|
||||
continue;
|
||||
}
|
||||
if(*names_ptr == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
setup_kegs_file(&name_buf[0], (int)sizeof(name_buf), 1,
|
||||
names_ptr);
|
||||
|
||||
if(name_buf[0] != 0) {
|
||||
fd = open(name_buf, O_RDONLY | O_BINARY);
|
||||
if(fd < 0) {
|
||||
printf("Open card ROM file %s failed: %d "
|
||||
"err:%d\n", name_buf, fd, errno);
|
||||
my_exit(-3);
|
||||
}
|
||||
|
||||
len = 256;
|
||||
ret = read(fd, &g_rom_cards_ptr[i*0x100], len);
|
||||
|
||||
if(ret != len) {
|
||||
printf("errno: %d, expected %d, got %d\n",
|
||||
errno, len, ret);
|
||||
my_exit(-3);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
more_than_8mb = (g_mem_size_exp > 0x800000);
|
||||
/* Only do the patch if users wants more than 8MB of expansion mem */
|
||||
|
||||
changed_rom = 0;
|
||||
if(g_rom_version == 1) {
|
||||
/* make some patches to ROM 01 */
|
||||
#if 0
|
||||
/* 1: Patch ROM selftest to not do speed test */
|
||||
printf("Patching out speed test failures from ROM 01\n");
|
||||
g_rom_fc_ff_ptr[0x3785a] = 0x18;
|
||||
changed_rom = 1;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* 2: Patch ROM selftests not to do tests 2,4 */
|
||||
/* 0 = skip, 1 = do it, test 1 is bit 0 of LSByte */
|
||||
g_rom_fc_ff_ptr[0x371e9] = 0xf5;
|
||||
g_rom_fc_ff_ptr[0x371ea] = 0xff;
|
||||
changed_rom = 1;
|
||||
#endif
|
||||
|
||||
if(more_than_8mb) {
|
||||
/* Geoff Weiss patch to use up to 14MB of RAM */
|
||||
g_rom_fc_ff_ptr[0x30302] = 0xdf;
|
||||
g_rom_fc_ff_ptr[0x30314] = 0xdf;
|
||||
g_rom_fc_ff_ptr[0x3031c] = 0x00;
|
||||
changed_rom = 1;
|
||||
}
|
||||
|
||||
/* Patch ROM selftest to not do ROM cksum if any changes*/
|
||||
if(changed_rom) {
|
||||
g_rom_fc_ff_ptr[0x37a06] = 0x18;
|
||||
g_rom_fc_ff_ptr[0x37a07] = 0x18;
|
||||
}
|
||||
} else if(g_rom_version == 3) {
|
||||
/* patch ROM 03 */
|
||||
printf("Patching ROM 03 smartport bug\n");
|
||||
/* 1: Patch Smartport code to fix a stupid bug */
|
||||
/* that causes it to write the IWM status reg into c036, */
|
||||
/* which is the system speed reg...it's "safe" since */
|
||||
/* IWM status reg bit 4 must be 0 (7MHz)..., otherwise */
|
||||
/* it might have turned on shadowing in all banks! */
|
||||
g_rom_fc_ff_ptr[0x357c9] = 0x00;
|
||||
changed_rom = 1;
|
||||
|
||||
#if 0
|
||||
/* patch ROM 03 to not to speed test */
|
||||
/* skip fast speed test */
|
||||
g_rom_fc_ff_ptr[0x36ad7] = 0x18;
|
||||
g_rom_fc_ff_ptr[0x36ad8] = 0x18;
|
||||
changed_rom = 1;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* skip slow speed test */
|
||||
g_rom_fc_ff_ptr[0x36ae7] = 0x18;
|
||||
g_rom_fc_ff_ptr[0x36ae8] = 0x6b;
|
||||
changed_rom = 1;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* 4: Patch ROM 03 selftests not to do tests 1-4 */
|
||||
g_rom_fc_ff_ptr[0x364a9] = 0xf0;
|
||||
g_rom_fc_ff_ptr[0x364aa] = 0xff;
|
||||
changed_rom = 1;
|
||||
#endif
|
||||
|
||||
/* ROM tests are in ff/6403-642x, where 6403 = addr of */
|
||||
/* test 1, etc. */
|
||||
|
||||
if(more_than_8mb) {
|
||||
/* Geoff Weiss patch to use up to 14MB of RAM */
|
||||
g_rom_fc_ff_ptr[0x30b] = 0xdf;
|
||||
g_rom_fc_ff_ptr[0x31d] = 0xdf;
|
||||
g_rom_fc_ff_ptr[0x325] = 0x00;
|
||||
changed_rom = 1;
|
||||
}
|
||||
|
||||
if(changed_rom) {
|
||||
/* patch ROM 03 selftest to not do ROM cksum */
|
||||
g_rom_fc_ff_ptr[0x36cb0] = 0x18;
|
||||
g_rom_fc_ff_ptr[0x36cb1] = 0x18;
|
||||
}
|
||||
|
||||
a1++;
|
||||
g_a4++;
|
||||
}
|
||||
a1 = a1 & 0xffff;
|
||||
g_a4 = g_a4 & 0xffff;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_engine_c_c[] = "@(#)$KmKId: engine_c.c,v 1.51 2004-01-10 15:50:15-05 kentd Exp $";
|
||||
const char rcsid_engine_c_c[] = "@(#)$KmKId: engine_c.c,v 1.57 2004-12-03 23:51:01-05 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
#include "protos_engine_c.h"
|
||||
@ -28,8 +28,10 @@ const char rcsid_engine_c_c[] = "@(#)$KmKId: engine_c.c,v 1.51 2004-01-10 15:50:
|
||||
extern int halt_sim;
|
||||
extern int g_code_red;
|
||||
extern int g_ignore_halts;
|
||||
extern int g_user_halt_bad;
|
||||
extern double g_fcycles_stop;
|
||||
extern double g_last_vbl_dcycs;
|
||||
extern double g_cur_dcycs;
|
||||
extern int g_wait_pending;
|
||||
extern int g_irq_pending;
|
||||
extern int g_testing;
|
||||
@ -44,9 +46,13 @@ extern byte *g_dummy_memory1_ptr;
|
||||
extern int g_num_breakpoints;
|
||||
extern word32 g_breakpts[];
|
||||
|
||||
extern Pc_log *log_pc_ptr;
|
||||
extern Pc_log *log_pc_start_ptr;
|
||||
extern Pc_log *log_pc_end_ptr;
|
||||
extern Pc_log *g_log_pc_ptr;
|
||||
extern Pc_log *g_log_pc_start_ptr;
|
||||
extern Pc_log *g_log_pc_end_ptr;
|
||||
|
||||
extern Data_log *g_log_data_ptr;
|
||||
extern Data_log *g_log_data_start_ptr;
|
||||
extern Data_log *g_log_data_end_ptr;
|
||||
|
||||
int size_tab[] = {
|
||||
#include "size_c.h"
|
||||
@ -75,8 +81,9 @@ int bogus[] = {
|
||||
|
||||
#define FCYCLES_ROUND fcycles = (int)(fcycles + fplus_x_m1);
|
||||
|
||||
#ifdef LOG_PC
|
||||
# define LOG_PC_MACRO() \
|
||||
tmp_pc_ptr = log_pc_ptr++; \
|
||||
tmp_pc_ptr = g_log_pc_ptr++; \
|
||||
tmp_pc_ptr->dbank_kpc = (dbank << 24) + kpc; \
|
||||
tmp_pc_ptr->instr = (opcode << 24) + arg_ptr[1] + \
|
||||
(arg_ptr[2] << 8) + (arg_ptr[3] << 16); \
|
||||
@ -85,11 +92,28 @@ int bogus[] = {
|
||||
tmp_pc_ptr->xreg_yreg = (xreg << 16) + yreg; \
|
||||
tmp_pc_ptr->stack_direct = (stack << 16) + direct; \
|
||||
tmp_pc_ptr->dcycs = fcycles + g_last_vbl_dcycs - fplus_2; \
|
||||
if(log_pc_ptr >= log_pc_end_ptr) { \
|
||||
if(g_log_pc_ptr >= g_log_pc_end_ptr) { \
|
||||
/*halt2_printf("log_pc oflow %f\n", tmp_pc_ptr->dcycs);*/ \
|
||||
log_pc_ptr = log_pc_start_ptr; \
|
||||
g_log_pc_ptr = g_log_pc_start_ptr; \
|
||||
}
|
||||
|
||||
# define LOG_DATA_MACRO(in_addr, in_val, in_size) \
|
||||
g_log_data_ptr->dcycs = fcycles + g_last_vbl_dcycs; \
|
||||
g_log_data_ptr->addr = in_addr; \
|
||||
g_log_data_ptr->val = in_val; \
|
||||
g_log_data_ptr->size = in_size; \
|
||||
g_log_data_ptr++; \
|
||||
if(g_log_data_ptr >= g_log_data_end_ptr) { \
|
||||
g_log_data_ptr = g_log_data_start_ptr; \
|
||||
}
|
||||
|
||||
#else
|
||||
# define LOG_PC_MACRO()
|
||||
# define LOG_DATA_MACRO(addr, val, size)
|
||||
/* Just do nothing */
|
||||
#endif
|
||||
|
||||
|
||||
#define GET_1BYTE_ARG arg = arg_ptr[1];
|
||||
#define GET_2BYTE_ARG arg = arg_ptr[1] + (arg_ptr[2] << 8);
|
||||
#define GET_3BYTE_ARG arg = arg_ptr[1] + (arg_ptr[2] << 8) + (arg_ptr[3]<<16);
|
||||
@ -270,6 +294,7 @@ extern word32 slow_mem_changed[];
|
||||
}
|
||||
|
||||
#define SET_MEMORY8(addr, val) \
|
||||
LOG_DATA_MACRO(addr, val, 8); \
|
||||
CYCLES_PLUS_1; \
|
||||
stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \
|
||||
wstat = PTR2WORD(stat) & 0xff; \
|
||||
@ -284,17 +309,15 @@ extern word32 slow_mem_changed[];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define SET_MEMORY16(addr, val, in_bank) \
|
||||
LOG_DATA_MACRO(addr, val, 16); \
|
||||
stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \
|
||||
wstat = PTR2WORD(stat) & 0xff; \
|
||||
ptr = stat - wstat + ((addr) & 0xff); \
|
||||
if((wstat) || (((addr) & 0xff) == 0xff)) { \
|
||||
fcycles_tmp1 = fcycles; \
|
||||
set_memory16_pieces_stub((addr), (val), \
|
||||
&fcycles_tmp1, fplus_ptr, in_bank); \
|
||||
&fcycles_tmp1, fplus_1, fplus_x_m1, in_bank); \
|
||||
fcycles = fcycles_tmp1; \
|
||||
} else { \
|
||||
CYCLES_PLUS_2; \
|
||||
@ -303,6 +326,7 @@ extern word32 slow_mem_changed[];
|
||||
}
|
||||
|
||||
#define SET_MEMORY24(addr, val, in_bank) \
|
||||
LOG_DATA_MACRO(addr, val, 24); \
|
||||
stat = GET_PAGE_INFO_WR(((addr) >> 8) & 0xffff); \
|
||||
wstat = PTR2WORD(stat) & 0xff; \
|
||||
ptr = stat - wstat + ((addr) & 0xff); \
|
||||
@ -326,7 +350,7 @@ check_breakpoints(word32 addr)
|
||||
|
||||
count = g_num_breakpoints;
|
||||
for(i = 0; i < count; i++) {
|
||||
if(g_breakpts[i] == addr) {
|
||||
if((g_breakpts[i] & 0xffffff) == addr) {
|
||||
halt2_printf("Hit breakpoint at %06x\n", addr);
|
||||
}
|
||||
}
|
||||
@ -464,19 +488,15 @@ set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr,
|
||||
|
||||
void
|
||||
set_memory16_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
|
||||
Fplus *fplus_ptr, int in_bank)
|
||||
double fplus_1, double fplus_x_m1, int in_bank)
|
||||
{
|
||||
byte *ptr;
|
||||
byte *stat;
|
||||
double fcycles, fcycles_tmp1;
|
||||
double fplus_1;
|
||||
double fplus_x_m1;
|
||||
word32 addrp1;
|
||||
word32 wstat;
|
||||
|
||||
fcycles = *fcycs_ptr;
|
||||
fplus_1 = fplus_ptr->plus_1;
|
||||
fplus_x_m1 = fplus_ptr->plus_x_minus_1;
|
||||
SET_MEMORY8(addr, val);
|
||||
addrp1 = addr + 1;
|
||||
if(in_bank) {
|
||||
@ -536,14 +556,6 @@ get_memory_c(word32 addr, int cycs)
|
||||
GET_MEMORY8(addr, ret);
|
||||
return ret;
|
||||
}
|
||||
#if 0
|
||||
stat = page_info[(addr>>8) & 0xffff].rd;
|
||||
ptr = (byte *)((stat & 0xffffff00) | (addr & 0xff));
|
||||
if(stat & (1 << (31 -BANK_IO_BIT))) {
|
||||
return get_memory_io(addr, &in_fcycles);
|
||||
}
|
||||
return *ptr;
|
||||
#endif
|
||||
|
||||
word32
|
||||
get_memory16_c(word32 addr, int cycs)
|
||||
@ -576,16 +588,27 @@ set_memory_c(word32 addr, word32 val, int cycs)
|
||||
double fplus_x_m1;
|
||||
word32 wstat;
|
||||
|
||||
fcycles = 0;
|
||||
fcycles = g_cur_dcycs - g_last_vbl_dcycs;
|
||||
fplus_1 = 0;
|
||||
fplus_x_m1 = 0;
|
||||
SET_MEMORY8(addr, val);
|
||||
}
|
||||
|
||||
void
|
||||
set_memory16_c(word32 addr, word32 val, int cycs)
|
||||
{
|
||||
set_memory_c(addr, val, 0);
|
||||
set_memory_c(addr + 1, val >> 8, 0);
|
||||
byte *stat;
|
||||
byte *ptr;
|
||||
double fcycles, fcycles_tmp1;
|
||||
double fplus_1, fplus_2;
|
||||
double fplus_x_m1;
|
||||
word32 wstat;
|
||||
|
||||
fcycles = g_cur_dcycs - g_last_vbl_dcycs;
|
||||
fplus_1 = 0;
|
||||
fplus_2 = 0;
|
||||
fplus_x_m1 = 0;
|
||||
SET_MEMORY16(addr, val, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -706,10 +729,10 @@ fixed_memory_ptrs_init()
|
||||
/* set g_slow_memory_ptr, g_rom_fc_ff_ptr, g_dummy_memory1_ptr, */
|
||||
/* and rom_cards_ptr */
|
||||
|
||||
g_slow_memory_ptr = memalloc_align(128*1024, 0);
|
||||
g_dummy_memory1_ptr = memalloc_align(256, 1024);
|
||||
g_rom_fc_ff_ptr = memalloc_align(256*1024, 1024);
|
||||
g_rom_cards_ptr = memalloc_align(16*256, 1024);
|
||||
g_slow_memory_ptr = memalloc_align(128*1024, 0, 0);
|
||||
g_dummy_memory1_ptr = memalloc_align(256, 1024, 0);
|
||||
g_rom_fc_ff_ptr = memalloc_align(256*1024, 512, 0);
|
||||
g_rom_cards_ptr = memalloc_align(16*256, 256, 0);
|
||||
|
||||
#if 0
|
||||
printf("g_memory_ptr: %08x, dummy_mem: %08x, slow_mem_ptr: %08x\n",
|
||||
@ -757,7 +780,7 @@ get_itimer()
|
||||
void
|
||||
set_halt_act(int val)
|
||||
{
|
||||
if(val == 1 && g_ignore_halts) {
|
||||
if(val == 1 && g_ignore_halts && !g_user_halt_bad) {
|
||||
g_code_red++;
|
||||
} else {
|
||||
halt_sim |= val;
|
||||
@ -938,9 +961,7 @@ recalc_accsize:
|
||||
|
||||
FETCH_OPCODE;
|
||||
|
||||
#ifdef LOG_PC
|
||||
LOG_PC_MACRO();
|
||||
#endif
|
||||
|
||||
switch(opcode) {
|
||||
default:
|
||||
@ -957,9 +978,7 @@ recalc_accsize:
|
||||
} else {
|
||||
while(fcycles <= g_fcycles_stop) {
|
||||
FETCH_OPCODE;
|
||||
#ifdef LOG_PC
|
||||
LOG_PC_MACRO();
|
||||
#endif
|
||||
|
||||
switch(opcode) {
|
||||
default:
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#ifdef ASM
|
||||
# ifdef INCLUDE_RCSID_S
|
||||
.stringz "@(#)$KmKId: instable.h,v 1.103 2004-01-10 15:50:50-05 kentd Exp $"
|
||||
.stringz "@(#)$KmKId: instable.h,v 1.104 2004-10-05 20:12:08-04 kentd Exp $"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -2353,9 +2353,8 @@ instdb_SYM /* STP */
|
||||
b dispatch_done
|
||||
depi RET_STP,3,4,ret0
|
||||
#else
|
||||
GET_1BYTE_ARG;
|
||||
CYCLES_PLUS_1
|
||||
FINISH(RET_STP, arg);
|
||||
CYCLES_FINISH
|
||||
FINISH(RET_STP, 0);
|
||||
#endif
|
||||
|
||||
instdc_SYM /* JML (Abs) */
|
||||
|
165
src/iwm.c
165
src/iwm.c
@ -8,14 +8,13 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_iwm_c[] = "@(#)$KmKId: iwm.c,v 1.111 2003-11-03 22:14:10-05 kentd Exp $";
|
||||
const char rcsid_iwm_c[] = "@(#)$KmKId: iwm.c,v 1.119 2004-11-21 17:44:14-05 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
|
||||
extern int Verbose;
|
||||
extern int g_vbl_count;
|
||||
extern int speed_fast;
|
||||
extern word32 g_slot_motor_detect;
|
||||
extern int g_c036_val_speed;
|
||||
|
||||
const byte phys_to_dos_sec[] = {
|
||||
0x00, 0x07, 0x0e, 0x06, 0x0d, 0x05, 0x0c, 0x04,
|
||||
@ -72,8 +71,8 @@ int from_disk_byte_valid = 0;
|
||||
|
||||
Iwm iwm;
|
||||
|
||||
int g_apple35_sel = 0;
|
||||
int head_35 = 0;
|
||||
extern int g_c031_disk35;
|
||||
|
||||
int g_iwm_motor_on = 0;
|
||||
|
||||
int g_check_nibblization = 0;
|
||||
@ -87,11 +86,6 @@ void iwm_write_data_525(Disk *dsk, word32 val, int fast_disk_emul,double dcycs);
|
||||
void
|
||||
iwm_init_drive(Disk *dsk, int smartport, int drive, int disk_525)
|
||||
{
|
||||
int num_tracks;
|
||||
int i;
|
||||
|
||||
num_tracks = MAX_TRACKS;
|
||||
|
||||
dsk->dcycs_last_read = 0.0;
|
||||
dsk->name_ptr = 0;
|
||||
dsk->partition_name = 0;
|
||||
@ -113,15 +107,31 @@ iwm_init_drive(Disk *dsk, int smartport, int drive, int disk_525)
|
||||
dsk->last_phase = 0;
|
||||
dsk->nib_pos = 0;
|
||||
dsk->num_tracks = 0;
|
||||
dsk->trks = 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
disk_set_num_tracks(Disk *dsk, int num_tracks)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(dsk->trks != 0) {
|
||||
/* This should not be necessary! */
|
||||
free(dsk->trks);
|
||||
halt_printf("Needed to free dsk->trks: %p\n", dsk->trks);
|
||||
}
|
||||
dsk->num_tracks = num_tracks;
|
||||
dsk->trks = (Trk *)malloc(num_tracks * sizeof(Trk));
|
||||
|
||||
for(i = 0; i < num_tracks; i++) {
|
||||
dsk->tracks[i].dsk = dsk;
|
||||
dsk->tracks[i].nib_area = 0;
|
||||
dsk->tracks[i].track_dirty = 0;
|
||||
dsk->tracks[i].overflow_size = 0;
|
||||
dsk->tracks[i].track_len = 0;
|
||||
dsk->tracks[i].unix_pos = -1;
|
||||
dsk->tracks[i].unix_len = -1;
|
||||
dsk->trks[i].dsk = dsk;
|
||||
dsk->trks[i].nib_area = 0;
|
||||
dsk->trks[i].track_dirty = 0;
|
||||
dsk->trks[i].overflow_size = 0;
|
||||
dsk->trks[i].track_len = 0;
|
||||
dsk->trks[i].unix_pos = -1;
|
||||
dsk->trks[i].unix_len = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,21 +189,23 @@ iwm_reset()
|
||||
iwm.previous_write_bits = 0;
|
||||
|
||||
g_iwm_motor_on = 0;
|
||||
g_apple35_sel = 0;
|
||||
g_c031_disk35 = 0;
|
||||
}
|
||||
|
||||
void
|
||||
draw_iwm_status(int line, char *buf)
|
||||
{
|
||||
char *flag[2][2];
|
||||
int apple35_sel;
|
||||
|
||||
flag[0][0] = " ";
|
||||
flag[0][1] = " ";
|
||||
flag[1][0] = " ";
|
||||
flag[1][1] = " ";
|
||||
|
||||
apple35_sel = (g_c031_disk35 >> 6) & 1;
|
||||
if(g_iwm_motor_on) {
|
||||
flag[g_apple35_sel][iwm.drive_select] = "*";
|
||||
flag[apple35_sel][iwm.drive_select] = "*";
|
||||
}
|
||||
|
||||
sprintf(buf, "s6d1:%2d%s s6d2:%2d%s s5d1:%2d/%d%s "
|
||||
@ -204,12 +216,12 @@ draw_iwm_status(int line, char *buf)
|
||||
iwm.drive35[0].cur_qtr_track & 1, flag[1][0],
|
||||
iwm.drive35[1].cur_qtr_track >> 1,
|
||||
iwm.drive35[1].cur_qtr_track & 1, flag[1][1],
|
||||
g_fast_disk_emul, g_slow_525_emul_wr,
|
||||
(speed_fast << 7) + g_slot_motor_detect);
|
||||
g_fast_disk_emul, g_slow_525_emul_wr, g_c036_val_speed);
|
||||
|
||||
video_update_status_line(line, buf);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
iwm_flush_disk_to_unix(Disk *dsk)
|
||||
{
|
||||
@ -253,8 +265,8 @@ iwm_flush_disk_to_unix(Disk *dsk)
|
||||
num_dirty++;
|
||||
|
||||
/* Write it out */
|
||||
unix_pos = dsk->tracks[j].unix_pos;
|
||||
unix_len = dsk->tracks[j].unix_len;
|
||||
unix_pos = dsk->trks[j].unix_pos;
|
||||
unix_len = dsk->trks[j].unix_len;
|
||||
if(unix_pos < 0 || unix_len < 0x1000) {
|
||||
halt_printf("Disk:%s trk:%d, unix_pos:%08x, len:%08x\n",
|
||||
dsk->name_ptr, j, unix_pos, unix_len);
|
||||
@ -303,7 +315,7 @@ iwm_vbl_update(int doit_3_persec)
|
||||
}
|
||||
|
||||
motor_on = iwm.motor_on;
|
||||
if(g_apple35_sel) {
|
||||
if(g_c031_disk35 & 0x40) {
|
||||
motor_on = iwm.motor_on35;
|
||||
}
|
||||
|
||||
@ -327,11 +339,11 @@ iwm_show_stats()
|
||||
{
|
||||
printf("IWM stats: q7,q6: %d, %d, reset,enable2: %d,%d, mode: %02x\n",
|
||||
iwm.q7, iwm.q6, iwm.reset, iwm.enable2, iwm.iwm_mode);
|
||||
printf("motor: %d,%d, motor35:%d drive: %d, on: %d, head35: %d "
|
||||
printf("motor: %d,%d, motor35:%d drive: %d, c031:%02x "
|
||||
"phs: %d %d %d %d\n",
|
||||
iwm.motor_on, iwm.motor_off, g_iwm_motor_on,
|
||||
iwm.drive_select, g_apple35_sel,
|
||||
head_35, iwm.iwm_phase[0], iwm.iwm_phase[1], iwm.iwm_phase[2],
|
||||
iwm.drive_select, g_c031_disk35,
|
||||
iwm.iwm_phase[0], iwm.iwm_phase[1], iwm.iwm_phase[2],
|
||||
iwm.iwm_phase[3]);
|
||||
printf("iwm.drive525[0].fd: %d, [1].fd: %d\n",
|
||||
iwm.drive525[0].fd, iwm.drive525[1].fd);
|
||||
@ -355,7 +367,7 @@ iwm_touch_switches(int loc, double dcycs)
|
||||
on = loc & 1;
|
||||
drive = iwm.drive_select;
|
||||
phase = loc >> 1;
|
||||
if(g_apple35_sel) {
|
||||
if(g_c031_disk35 & 0x40) {
|
||||
dsk = &(iwm.drive35[drive]);
|
||||
} else {
|
||||
dsk = &(iwm.drive525[drive]);
|
||||
@ -366,9 +378,12 @@ iwm_touch_switches(int loc, double dcycs)
|
||||
/* phase adjustments. See if motor is on */
|
||||
|
||||
iwm.iwm_phase[phase] = on;
|
||||
iwm_printf("Iwm phase %d=%d, all phases: %d %d %d %d (%f)\n",
|
||||
phase, on, iwm.iwm_phase[0], iwm.iwm_phase[1],
|
||||
iwm.iwm_phase[2], iwm.iwm_phase[3], dcycs);
|
||||
|
||||
if(iwm.motor_on) {
|
||||
if(g_apple35_sel) {
|
||||
if(g_c031_disk35 & 0x40) {
|
||||
if(phase == 3 && on) {
|
||||
iwm_do_action35(dcycs);
|
||||
}
|
||||
@ -527,7 +542,7 @@ iwm525_phase_change(int drive, int phase)
|
||||
last_phase = 0;
|
||||
}
|
||||
if(qtr_track > 4*34) {
|
||||
printf("Disk arm moved past track 0x21, moving it back\n");
|
||||
printf("Disk arm moved past track 34, moving it back\n");
|
||||
qtr_track = 4*34;
|
||||
last_phase = 0;
|
||||
}
|
||||
@ -536,9 +551,9 @@ iwm525_phase_change(int drive, int phase)
|
||||
|
||||
dsk->last_phase = last_phase;
|
||||
|
||||
iwm_printf("Moving drive to qtr track: %04x, %d, %d, %d, "
|
||||
"%d %d %d %d\n",
|
||||
qtr_track, phase, delta, last_phase, iwm.iwm_phase[0],
|
||||
iwm_printf("Moving drive to qtr track: %04x (trk:%d.%02d), %d, %d, %d, "
|
||||
"%d %d %d %d\n", qtr_track, qtr_track>>2, 25*(qtr_track & 3),
|
||||
phase, delta, last_phase, iwm.iwm_phase[0],
|
||||
iwm.iwm_phase[1], iwm.iwm_phase[2], iwm.iwm_phase[3]);
|
||||
|
||||
/* sanity check stepping algorithm */
|
||||
@ -564,7 +579,7 @@ iwm_read_status35(double dcycs)
|
||||
if(iwm.motor_on) {
|
||||
/* Read status */
|
||||
state = (iwm.iwm_phase[1] << 3) + (iwm.iwm_phase[0] << 2) +
|
||||
(head_35 << 1) + iwm.iwm_phase[2];
|
||||
((g_c031_disk35 >> 6) & 2) + iwm.iwm_phase[2];
|
||||
|
||||
iwm_printf("Iwm status read state: %02x\n", state);
|
||||
|
||||
@ -666,7 +681,7 @@ iwm_do_action35(double dcycs)
|
||||
if(iwm.motor_on) {
|
||||
/* Perform action */
|
||||
state = (iwm.iwm_phase[1] << 3) + (iwm.iwm_phase[0] << 2) +
|
||||
(head_35 << 1) + iwm.iwm_phase[2];
|
||||
((g_c031_disk35 >> 6) & 2) + iwm.iwm_phase[2];
|
||||
switch(state) {
|
||||
case 0x00: /* Set step direction inward */
|
||||
/* towards higher tracks */
|
||||
@ -715,17 +730,6 @@ iwm_do_action35(double dcycs)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iwm_set_apple35_sel(int newval)
|
||||
{
|
||||
if(g_apple35_sel != newval) {
|
||||
/* Handle speed changes */
|
||||
set_halt(HALT_EVENT);
|
||||
}
|
||||
|
||||
g_apple35_sel = newval;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_read_c0ec(double dcycs)
|
||||
{
|
||||
@ -736,7 +740,7 @@ iwm_read_c0ec(double dcycs)
|
||||
|
||||
if(iwm.q7 == 0 && iwm.enable2 == 0 && iwm.motor_on) {
|
||||
drive = iwm.drive_select;
|
||||
if(g_apple35_sel) {
|
||||
if(g_c031_disk35 & 0x40) {
|
||||
dsk = &(iwm.drive35[drive]);
|
||||
return iwm_read_data_35(dsk, g_fast_disk_emul, dcycs);
|
||||
} else {
|
||||
@ -773,7 +777,7 @@ read_iwm(int loc, double dcycs)
|
||||
|
||||
state = (iwm.q7 << 1) + iwm.q6;
|
||||
drive = iwm.drive_select;
|
||||
if(g_apple35_sel) {
|
||||
if(g_c031_disk35 & 0x40) {
|
||||
dsk = &(iwm.drive35[drive]);
|
||||
} else {
|
||||
dsk = &(iwm.drive525[drive]);
|
||||
@ -806,7 +810,7 @@ read_iwm(int loc, double dcycs)
|
||||
iwm_printf("Read status under enable2: 1\n");
|
||||
status = 1;
|
||||
} else {
|
||||
if(g_apple35_sel) {
|
||||
if(g_c031_disk35 & 0x40) {
|
||||
status = iwm_read_status35(dcycs);
|
||||
} else {
|
||||
status = dsk->write_prot;
|
||||
@ -868,7 +872,7 @@ write_iwm(int loc, int val, double dcycs)
|
||||
state = (iwm.q7 << 1) + iwm.q6;
|
||||
drive = iwm.drive_select;
|
||||
fast_writes = g_fast_disk_emul;
|
||||
if(g_apple35_sel) {
|
||||
if(g_c031_disk35 & 0x40) {
|
||||
dsk = &(iwm.drive35[drive]);
|
||||
} else {
|
||||
dsk = &(iwm.drive525[drive]);
|
||||
@ -899,8 +903,11 @@ write_iwm(int loc, int val, double dcycs)
|
||||
if(iwm.enable2) {
|
||||
iwm_write_enable2(val, dcycs);
|
||||
} else {
|
||||
#if 0
|
||||
// Flobynoid writes to 0xc0e9 causing these messages...
|
||||
printf("Write iwm1, st: %02x, loc: %x: %02x\n",
|
||||
state, loc, val);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -915,10 +922,7 @@ write_iwm(int loc, int val, double dcycs)
|
||||
return;
|
||||
}
|
||||
|
||||
halt_printf("Got to end of write_iwm, loc:%02x, val: %02x\n", loc, val);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1064,7 +1068,7 @@ disk_unnib_4x4(Disk *dsk)
|
||||
}
|
||||
|
||||
int
|
||||
iwm_denib_track525(Disk *dsk, Track *trk, int qtr_track, byte *outbuf)
|
||||
iwm_denib_track525(Disk *dsk, Trk *trk, int qtr_track, byte *outbuf)
|
||||
{
|
||||
byte aux_buf[0x80];
|
||||
byte *buf;
|
||||
@ -1274,7 +1278,7 @@ iwm_denib_track525(Disk *dsk, Track *trk, int qtr_track, byte *outbuf)
|
||||
}
|
||||
|
||||
int
|
||||
iwm_denib_track35(Disk *dsk, Track *trk, int qtr_track, byte *outbuf)
|
||||
iwm_denib_track35(Disk *dsk, Trk *trk, int qtr_track, byte *outbuf)
|
||||
{
|
||||
word32 buf_c00[0x100];
|
||||
word32 buf_d00[0x100];
|
||||
@ -1601,17 +1605,14 @@ iwm_denib_track35(Disk *dsk, Track *trk, int qtr_track, byte *outbuf)
|
||||
int
|
||||
disk_track_to_unix(Disk *dsk, int qtr_track, byte *outbuf)
|
||||
{
|
||||
Track *trk;
|
||||
Trk *trk;
|
||||
int disk_525;
|
||||
|
||||
disk_525 = dsk->disk_525;
|
||||
|
||||
trk = &(dsk->tracks[qtr_track]);
|
||||
trk = &(dsk->trks[qtr_track]);
|
||||
|
||||
if(trk->track_len == 0 || trk->track_dirty == 0) {
|
||||
#if 0
|
||||
printf("disk_track_to_unix: dirty: %d\n", trk->track_dirty);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1652,7 +1653,7 @@ void
|
||||
disk_check_nibblization(Disk *dsk, int qtr_track, byte *buf, int size)
|
||||
{
|
||||
byte buffer[0x3000];
|
||||
Track *trk;
|
||||
Trk *trk;
|
||||
int ret, ret2;
|
||||
int i;
|
||||
|
||||
@ -1665,7 +1666,7 @@ disk_check_nibblization(Disk *dsk, int qtr_track, byte *buf, int size)
|
||||
buffer[i] = 0;
|
||||
}
|
||||
|
||||
trk = &(dsk->tracks[qtr_track]);
|
||||
trk = &(dsk->trks[qtr_track]);
|
||||
|
||||
if(dsk->disk_525) {
|
||||
ret = iwm_denib_track525(dsk, trk, qtr_track, &(buffer[0]));
|
||||
@ -1688,7 +1689,7 @@ disk_check_nibblization(Disk *dsk, int qtr_track, byte *buf, int size)
|
||||
ret, ret2, qtr_track);
|
||||
show_hex_data(buf, 0x1000);
|
||||
show_hex_data(buffer, 0x1000);
|
||||
iwm_show_a_track(&(dsk->tracks[qtr_track]));
|
||||
iwm_show_a_track(&(dsk->trks[qtr_track]));
|
||||
|
||||
exit(2);
|
||||
}
|
||||
@ -1702,7 +1703,7 @@ disk_unix_to_nib(Disk *dsk, int qtr_track, int unix_pos, int unix_len,
|
||||
int nib_len)
|
||||
{
|
||||
byte track_buf[TRACK_BUF_LEN];
|
||||
Track *trk;
|
||||
Trk *trk;
|
||||
int must_clear_track;
|
||||
int ret;
|
||||
int len;
|
||||
@ -1763,7 +1764,7 @@ disk_unix_to_nib(Disk *dsk, int qtr_track, int unix_pos, int unix_len,
|
||||
|
||||
dsk->nib_pos = 0; /* for consistency */
|
||||
|
||||
trk = &(dsk->tracks[qtr_track]);
|
||||
trk = &(dsk->trks[qtr_track]);
|
||||
trk->track_dirty = 0;
|
||||
trk->overflow_size = 0;
|
||||
trk->track_len = 2*nib_len;
|
||||
@ -1784,7 +1785,7 @@ disk_unix_to_nib(Disk *dsk, int qtr_track, int unix_pos, int unix_len,
|
||||
}
|
||||
|
||||
void
|
||||
iwm_nibblize_track_nib525(Disk *dsk, Track *trk, byte *track_buf, int qtr_track)
|
||||
iwm_nibblize_track_nib525(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track)
|
||||
{
|
||||
byte *nib_ptr;
|
||||
byte *trk_ptr;
|
||||
@ -1803,7 +1804,7 @@ iwm_nibblize_track_nib525(Disk *dsk, Track *trk, byte *track_buf, int qtr_track)
|
||||
}
|
||||
|
||||
void
|
||||
iwm_nibblize_track_525(Disk *dsk, Track *trk, byte *track_buf, int qtr_track)
|
||||
iwm_nibblize_track_525(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track)
|
||||
{
|
||||
byte partial_nib_buf[0x300];
|
||||
word32 *word_ptr;
|
||||
@ -1895,7 +1896,7 @@ iwm_nibblize_track_525(Disk *dsk, Track *trk, byte *track_buf, int qtr_track)
|
||||
}
|
||||
|
||||
void
|
||||
iwm_nibblize_track_35(Disk *dsk, Track *trk, byte *track_buf, int qtr_track)
|
||||
iwm_nibblize_track_35(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track)
|
||||
{
|
||||
int phys_to_log_sec[16];
|
||||
word32 buf_c00[0x100];
|
||||
@ -2150,7 +2151,7 @@ disk_4x4_nib_out(Disk *dsk, word32 val)
|
||||
void
|
||||
disk_nib_out(Disk *dsk, byte val, int size)
|
||||
{
|
||||
Track *trk;
|
||||
Trk *trk;
|
||||
int pos;
|
||||
int old_size;
|
||||
int track_len;
|
||||
@ -2160,9 +2161,12 @@ disk_nib_out(Disk *dsk, byte val, int size)
|
||||
|
||||
qtr_track = dsk->cur_qtr_track;
|
||||
|
||||
trk = &(dsk->tracks[qtr_track]);
|
||||
|
||||
track_len = 0;
|
||||
trk = 0;
|
||||
if(dsk->trks != 0) {
|
||||
trk = &(dsk->trks[qtr_track]);
|
||||
track_len = trk->track_len;
|
||||
}
|
||||
|
||||
if(track_len <= 10) {
|
||||
printf("Writing to an invalid qtr track: %02x!\n", qtr_track);
|
||||
@ -2234,7 +2238,7 @@ disk_nib_end_track(Disk *dsk)
|
||||
|
||||
dsk->nib_pos = 0;
|
||||
qtr_track = dsk->cur_qtr_track;
|
||||
dsk->tracks[qtr_track].track_dirty = 0;
|
||||
dsk->trks[qtr_track].track_dirty = 0;
|
||||
|
||||
dsk->disk_dirty = 0;
|
||||
}
|
||||
@ -2243,14 +2247,14 @@ void
|
||||
iwm_show_track(int slot_drive, int track)
|
||||
{
|
||||
Disk *dsk;
|
||||
Track *trk;
|
||||
Trk *trk;
|
||||
int drive;
|
||||
int sel35;
|
||||
int qtr_track;
|
||||
|
||||
if(slot_drive < 0) {
|
||||
drive = iwm.drive_select;
|
||||
sel35 = g_apple35_sel;
|
||||
sel35 = (g_c031_disk35 >> 6) & 1;
|
||||
} else {
|
||||
drive = slot_drive & 1;
|
||||
sel35 = !((slot_drive >> 1) & 1);
|
||||
@ -2267,22 +2271,25 @@ iwm_show_track(int slot_drive, int track)
|
||||
} else {
|
||||
qtr_track = track;
|
||||
}
|
||||
trk = &(dsk->tracks[qtr_track]);
|
||||
if(dsk->trks == 0) {
|
||||
return;
|
||||
}
|
||||
trk = &(dsk->trks[qtr_track]);
|
||||
|
||||
if(trk->track_len <= 0) {
|
||||
printf("Track_len: %d\n", trk->track_len);
|
||||
printf("No track for type: %d, drive: %d, qtrk: %02x\n",
|
||||
g_apple35_sel, drive, qtr_track);
|
||||
printf("No track for type: %d, drive: %d, qtrk: 0x%02x\n",
|
||||
sel35, drive, qtr_track);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Current drive: %d, q_track: %02x\n", drive, qtr_track);
|
||||
printf("Current drive: %d, q_track: 0x%02x\n", drive, qtr_track);
|
||||
|
||||
iwm_show_a_track(trk);
|
||||
}
|
||||
|
||||
void
|
||||
iwm_show_a_track(Track *trk)
|
||||
iwm_show_a_track(Trk *trk)
|
||||
{
|
||||
int sum;
|
||||
int len;
|
||||
|
@ -9,7 +9,7 @@
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_RCSID_C
|
||||
const char rcsid_iwm_h[] = "@(#)$KmKId: iwm.h,v 1.13 2003-07-08 23:29:48-04 kentd Exp $";
|
||||
const char rcsid_iwm_h[] = "@(#)$KmKId: iwm.h,v 1.14 2004-10-20 17:29:38-04 kentd Exp $";
|
||||
#endif
|
||||
|
||||
#define MAX_TRACKS (2*80)
|
||||
@ -24,7 +24,7 @@ const char rcsid_iwm_h[] = "@(#)$KmKId: iwm.h,v 1.13 2003-07-08 23:29:48-04 kent
|
||||
|
||||
typedef struct _Disk Disk;
|
||||
|
||||
STRUCT(Track) {
|
||||
STRUCT(Trk) {
|
||||
Disk *dsk;
|
||||
byte *nib_area;
|
||||
int track_dirty;
|
||||
@ -56,7 +56,7 @@ struct _Disk {
|
||||
int last_phase;
|
||||
int nib_pos;
|
||||
int num_tracks;
|
||||
Track tracks[MAX_TRACKS];
|
||||
Trk *trks;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
|
||||
#ifdef INCLUDE_IWM_RCSID_C
|
||||
const char rcsdif_iwm_35_525_h[] = "@(#)$KmKId: iwm_35_525.h,v 1.9 2002-11-14 01:03:16-05 kadickey Exp $";
|
||||
const char rcsdif_iwm_35_525_h[] = "@(#)$KmKId: iwm_35_525.h,v 1.14 2004-12-01 19:45:02-05 kentd Exp $";
|
||||
#endif
|
||||
|
||||
int
|
||||
IWM_READ_ROUT (Disk *dsk, int fast_disk_emul, double dcycs)
|
||||
{
|
||||
Track *trk;
|
||||
Trk *trk;
|
||||
double dcycs_last_read;
|
||||
int pos;
|
||||
int pos2;
|
||||
@ -30,12 +30,28 @@ IWM_READ_ROUT (Disk *dsk, int fast_disk_emul, double dcycs)
|
||||
|
||||
qtr_track = dsk->cur_qtr_track;
|
||||
|
||||
trk = &(dsk->tracks[qtr_track]);
|
||||
#if IWM_DISK_525
|
||||
qtr_track = qtr_track & -4; /* round to nearest whole trk! */
|
||||
#endif
|
||||
|
||||
trk = 0;
|
||||
track_len = 0;
|
||||
if(dsk->trks) {
|
||||
trk = &(dsk->trks[qtr_track]);
|
||||
track_len = trk->track_len;
|
||||
}
|
||||
|
||||
dcycs_last_read = dsk->dcycs_last_read;
|
||||
dcycs_passed = dcycs - dcycs_last_read;
|
||||
|
||||
cycs_passed = (int)dcycs_passed;
|
||||
|
||||
if(track_len == 0) {
|
||||
ret = (cycs_passed & 0x7f) + 0x80;
|
||||
iwm_printf("Reading c0ec, track_len 0, returning %02x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pos = dsk->nib_pos;
|
||||
if(pos >= track_len) {
|
||||
/* Arm may have moved from inner 3.5 track to outer one, */
|
||||
@ -43,11 +59,6 @@ IWM_READ_ROUT (Disk *dsk, int fast_disk_emul, double dcycs)
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
cycs_passed = (int)dcycs_passed;
|
||||
|
||||
if(track_len == 0) {
|
||||
return (cycs_passed & 0x7f) + 0x80;
|
||||
}
|
||||
size = trk->nib_area[pos];
|
||||
|
||||
while(size == 0) {
|
||||
@ -207,9 +218,9 @@ IWM_WRITE_ROUT (Disk *dsk, word32 val, int fast_disk_emul, double dcycs)
|
||||
int sdiff;
|
||||
int prev_bits;
|
||||
|
||||
if(dsk->fd < 0) {
|
||||
if(dsk->fd < 0 || dsk->trks == 0) {
|
||||
halt_printf("Tried to write to type: %d, drive: %d, fd: %d!\n",
|
||||
IWM_DISK_525, dsk->drive, dsk->fd);
|
||||
IWM_DISK_525, dsk->drive, dsk->fd, dsk->trks);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_joystick_driver_c[] = "@(#)$KmKId: joystick_driver.c,v 1.7 2002-11-19 03:09:59-05 kadickey Exp $";
|
||||
const char rcsid_joystick_driver_c[] = "@(#)$KmKId: joystick_driver.c,v 1.12 2004-10-17 21:28:48-04 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
#include <sys/time.h>
|
||||
@ -22,20 +22,23 @@ const char rcsid_joystick_driver_c[] = "@(#)$KmKId: joystick_driver.c,v 1.7 2002
|
||||
# include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
extern int g_joystick_type; /* in paddles.c */
|
||||
extern int g_paddle_button[];
|
||||
extern int g_joystick_native_type1; /* in paddles.c */
|
||||
extern int g_joystick_native_type2; /* in paddles.c */
|
||||
extern int g_joystick_native_type; /* in paddles.c */
|
||||
extern int g_paddle_buttons;
|
||||
extern int g_paddle_val[];
|
||||
|
||||
|
||||
const char *g_joystick_dev = "/dev/js0"; /* default joystick dev file */
|
||||
#define MAX_JOY_NAME 128
|
||||
|
||||
int g_joystick_fd = -1;
|
||||
int g_joystick_native_fd = -1;
|
||||
int g_joystick_num_axes = 0;
|
||||
int g_joystick_num_buttons = 0;
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
# define JOYSTICK_DEFINED
|
||||
void
|
||||
joystick_init()
|
||||
{
|
||||
@ -64,22 +67,24 @@ joystick_init()
|
||||
joy_name, g_joystick_num_axes, g_joystick_num_buttons,
|
||||
version);
|
||||
|
||||
g_joystick_type = JOYSTICK_LINUX;
|
||||
g_joystick_fd = fd;
|
||||
g_joystick_native_type1 = 1;
|
||||
g_joystick_native_type2 = -1;
|
||||
g_joystick_native_fd = fd;
|
||||
for(i = 0; i < 4; i++) {
|
||||
g_paddle_val[i] = 280;
|
||||
g_paddle_button[i] = 1;
|
||||
g_paddle_val[i] = 32767;
|
||||
}
|
||||
g_paddle_buttons = 0xc;
|
||||
|
||||
joystick_update();
|
||||
joystick_update(0.0);
|
||||
}
|
||||
|
||||
/* joystick_update_linux() called from paddles.c. Update g_paddle_val[] */
|
||||
/* and g_paddle_button[] arrays with current information */
|
||||
/* and g_paddle_buttons with current information */
|
||||
void
|
||||
joystick_update()
|
||||
joystick_update(double dcycs)
|
||||
{
|
||||
struct js_event js; /* the linux joystick event record */
|
||||
int mask;
|
||||
int val;
|
||||
int num;
|
||||
int type;
|
||||
@ -90,35 +95,42 @@ joystick_update()
|
||||
/* suck up to 20 events, then give up */
|
||||
len = sizeof(struct js_event);
|
||||
for(i = 0; i < 20; i++) {
|
||||
ret = read(g_joystick_fd, &js, len);
|
||||
ret = read(g_joystick_native_fd, &js, len);
|
||||
if(ret != len) {
|
||||
/* just get out */
|
||||
return;
|
||||
break;
|
||||
}
|
||||
type = js.type & ~JS_EVENT_INIT;
|
||||
val = js.value;
|
||||
num = js.number & 3; /* clamp to 0-3 */
|
||||
switch(type) {
|
||||
case JS_EVENT_BUTTON:
|
||||
g_paddle_button[num] = val;
|
||||
mask = 1 << num;
|
||||
if(val) {
|
||||
val = mask;
|
||||
}
|
||||
g_paddle_buttons = (g_paddle_buttons & ~mask) | val;
|
||||
break;
|
||||
case JS_EVENT_AXIS:
|
||||
/* val is -32767 to +32767, convert to 0->280 */
|
||||
/* want just 255, but go a little over for robustness*/
|
||||
g_paddle_val[num] = ((val + 32767) * 9) >> 11;
|
||||
/* val is -32767 to +32767 */
|
||||
g_paddle_val[num] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i > 0) {
|
||||
paddle_update_trigger_dcycs(dcycs);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
joystick_update_button()
|
||||
joystick_update_buttons()
|
||||
{
|
||||
}
|
||||
|
||||
#else /* !__linux__ */
|
||||
#endif /* LINUX */
|
||||
|
||||
#ifdef _WIN32
|
||||
# define JOYSTICK_DEFINED
|
||||
void
|
||||
joystick_init()
|
||||
{
|
||||
@ -129,99 +141,120 @@ joystick_init()
|
||||
|
||||
// Check that there is a joystick device
|
||||
if(joyGetNumDevs() <= 0) {
|
||||
printf("--No joystick hardware detected\n");
|
||||
printf("No joystick hardware detected\n");
|
||||
g_joystick_native_type1 = -1;
|
||||
g_joystick_native_type2 = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
g_joystick_native_type1 = -1;
|
||||
g_joystick_native_type2 = -1;
|
||||
|
||||
// Check that at least joystick 1 or joystick 2 is available
|
||||
ret1 = joyGetPos(JOYSTICKID1, &info);
|
||||
ret2 = joyGetDevCaps(JOYSTICKID1, &joycap, sizeof(joycap));
|
||||
if(ret1 == JOYERR_NOERROR && ret2 == JOYERR_NOERROR) {
|
||||
g_joystick_type = JOYSTICK_WIN32_1;
|
||||
printf("--Joystick #1 = %s\n", joycap.szPname);
|
||||
} else {
|
||||
g_joystick_native_type1 = JOYSTICKID1;
|
||||
printf("Joystick #1 = %s\n", joycap.szPname);
|
||||
g_joystick_native_type = JOYSTICKID1;
|
||||
}
|
||||
ret1 = joyGetPos(JOYSTICKID2, &info);
|
||||
ret2 = joyGetDevCaps(JOYSTICKID2, &joycap, sizeof(joycap));
|
||||
if(ret1 == JOYERR_NOERROR && ret2 == JOYERR_NOERROR) {
|
||||
g_joystick_type = JOYSTICK_WIN32_2;
|
||||
printf("--Joystick #2 = %s\n", joycap.szPname);
|
||||
} else {
|
||||
printf("No joysticks found...\n");
|
||||
g_joystick_type = JOYSTICK_MOUSE;
|
||||
return;
|
||||
g_joystick_native_type2 = JOYSTICKID2;
|
||||
printf("Joystick #2 = %s\n", joycap.szPname);
|
||||
if(g_joystick_native_type < 0) {
|
||||
g_joystick_native_type = JOYSTICKID2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
g_paddle_val[i] = 280;
|
||||
g_paddle_button[i] = 1;
|
||||
g_paddle_val[i] = 32767;
|
||||
}
|
||||
g_paddle_buttons = 0xc;
|
||||
|
||||
joystick_update();
|
||||
joystick_update(0.0);
|
||||
}
|
||||
|
||||
void
|
||||
joystick_update()
|
||||
joystick_update(double dcycs)
|
||||
{
|
||||
JOYCAPS joycap;
|
||||
JOYINFO info;
|
||||
UINT id;
|
||||
MMRESULT ret1, ret2;
|
||||
|
||||
id = JOYSTICKID1;
|
||||
if(g_joystick_type == JOYSTICK_WIN32_2) {
|
||||
id = JOYSTICKID2;
|
||||
}
|
||||
id = g_joystick_native_type;
|
||||
|
||||
ret1 = joyGetDevCaps(id, &joycap, sizeof(joycap));
|
||||
ret2 = joyGetPos(id, &info);
|
||||
if(ret1 == JOYERR_NOERROR && ret2 == JOYERR_NOERROR) {
|
||||
g_paddle_val[0] = (info.wXpos - joycap.wXmin) * 280 /
|
||||
g_paddle_val[0] = (info.wXpos - joycap.wXmin) * 32768 /
|
||||
(joycap.wXmax - joycap.wXmin);
|
||||
g_paddle_val[1] = (info.wYpos - joycap.wYmin) * 280 /
|
||||
g_paddle_val[1] = (info.wYpos - joycap.wYmin) * 32768 /
|
||||
(joycap.wYmax - joycap.wYmin);
|
||||
g_paddle_button[0] = ((info.wButtons & JOY_BUTTON1) ? 1 : 0);
|
||||
g_paddle_button[1] = ((info.wButtons & JOY_BUTTON2) ? 1 : 0);
|
||||
if(info.wButtons & JOY_BUTTON1) {
|
||||
g_paddle_buttons = g_paddle_buttons | 1;
|
||||
} else {
|
||||
g_paddle_buttons = g_paddle_buttons & (~1);
|
||||
}
|
||||
if(info.wButtons & JOY_BUTTON2) {
|
||||
g_paddle_buttons = g_paddle_buttons | 2;
|
||||
} else {
|
||||
g_paddle_buttons = g_paddle_buttons & (~2);
|
||||
}
|
||||
paddle_update_trigger_dcycs(dcycs);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
joystick_update_button()
|
||||
joystick_update_buttons()
|
||||
{
|
||||
JOYINFOEX info;
|
||||
UINT id;
|
||||
|
||||
id = JOYSTICKID1;
|
||||
if(g_joystick_type == JOYSTICK_WIN32_2) {
|
||||
id = JOYSTICKID2;
|
||||
}
|
||||
id = g_joystick_native_type;
|
||||
|
||||
info.dwSize = sizeof(JOYINFOEX);
|
||||
info.dwFlags = JOY_RETURNBUTTONS;
|
||||
if(joyGetPosEx(id, &info) == JOYERR_NOERROR) {
|
||||
g_paddle_button[0] = ((info.dwButtons & JOY_BUTTON1) ? 1 : 0);
|
||||
g_paddle_button[1] = ((info.dwButtons & JOY_BUTTON2) ? 1 : 0);
|
||||
if(info.dwButtons & JOY_BUTTON1) {
|
||||
g_paddle_buttons = g_paddle_buttons | 1;
|
||||
} else {
|
||||
g_paddle_buttons = g_paddle_buttons & (~1);
|
||||
}
|
||||
if(info.dwButtons & JOY_BUTTON2) {
|
||||
g_paddle_buttons = g_paddle_buttons | 2;
|
||||
} else {
|
||||
g_paddle_buttons = g_paddle_buttons & (~2);
|
||||
}
|
||||
}
|
||||
# else
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef JOYSTICK_DEFINED
|
||||
/* stubs for the routines */
|
||||
void
|
||||
joystick_init()
|
||||
{
|
||||
printf("No joy with joystick\n");
|
||||
g_joystick_native_type1 = -1;
|
||||
g_joystick_native_type2 = -1;
|
||||
g_joystick_native_type = -1;
|
||||
}
|
||||
|
||||
void
|
||||
joystick_update()
|
||||
joystick_update(double dcycs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
g_paddle_val[i] = 32767;
|
||||
}
|
||||
g_paddle_buttons = 0xc;
|
||||
}
|
||||
|
||||
void
|
||||
joystick_update_button()
|
||||
joystick_update_buttons()
|
||||
{
|
||||
}
|
||||
|
||||
# endif /* !WIN32 */
|
||||
#endif
|
||||
|
218
src/macdriver.c
218
src/macdriver.c
@ -1,6 +1,6 @@
|
||||
/************************************************************************/
|
||||
/* KEGS: Apple //gs Emulator */
|
||||
/* Copyright 2002 by Kent Dickey */
|
||||
/* Copyright 2002-2004 by Kent Dickey */
|
||||
/* */
|
||||
/* This code is covered by the GNU GPL */
|
||||
/* */
|
||||
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_macdriver_c[] = "@(#)$KmKId: macdriver.c,v 1.19 2004-03-23 17:27:56-05 kentd Exp $";
|
||||
const char rcsid_macdriver_c[] = "@(#)$KmKId: macdriver.c,v 1.24 2004-11-14 10:23:29-05 kentd Exp $";
|
||||
|
||||
// Quartz: CreateCGContextForPort vs QDBeginCGContext
|
||||
|
||||
@ -16,6 +16,7 @@ const char rcsid_macdriver_c[] = "@(#)$KmKId: macdriver.c,v 1.19 2004-03-23 17:2
|
||||
// Use CGPointMake to get a point
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <Quicktime/Quicktime.h>
|
||||
|
||||
#include "defc.h"
|
||||
#include "protos_macdriver.h"
|
||||
@ -25,6 +26,9 @@ const char rcsid_macdriver_c[] = "@(#)$KmKId: macdriver.c,v 1.19 2004-03-23 17:2
|
||||
#define MAX_MAC_ARGS 128
|
||||
|
||||
WindowRef g_main_window;
|
||||
WindowRef g_main_window_saved;
|
||||
Rect g_main_window_saved_rect;
|
||||
Ptr g_mac_fullscreen_state = 0;
|
||||
int g_quit_seen = 0;
|
||||
EventHandlerUPP g_quit_handler_UPP;
|
||||
EventHandlerUPP g_dummy_event_handler_UPP;
|
||||
@ -32,6 +36,7 @@ RgnHandle g_event_rgnhandle = 0;
|
||||
int g_ignore_next_click = 0;
|
||||
int g_mainwin_active = 0;
|
||||
GDHandle g_gdhandle = 0;
|
||||
|
||||
int g_mac_mouse_x = 0;
|
||||
int g_mac_mouse_y = 0;
|
||||
|
||||
@ -43,6 +48,8 @@ int g_mac_argc = 0;
|
||||
char *g_mac_argv[MAX_MAC_ARGS];
|
||||
word32 g_mac_shift_control_state = 0;
|
||||
extern char g_argv0_path[];
|
||||
extern char *g_fatal_log_strs[];
|
||||
extern int g_fatal_log;
|
||||
|
||||
extern word32 g_red_mask;
|
||||
extern word32 g_green_mask;
|
||||
@ -68,6 +75,13 @@ extern int g_send_sound_to_file;
|
||||
extern int g_quit_sim_now;
|
||||
extern int g_config_control_panel;
|
||||
|
||||
extern int g_video_act_width;
|
||||
extern int g_video_act_height;
|
||||
extern int g_video_act_margin_left;
|
||||
extern int g_video_act_margin_right;
|
||||
extern int g_video_act_margin_top;
|
||||
extern int g_video_act_margin_bottom;
|
||||
|
||||
int g_auto_repeat_on = -1;
|
||||
int g_x_shift_control_state = 0;
|
||||
|
||||
@ -99,8 +113,7 @@ extern char *g_status_ptrs[MAX_STATUS_LINES];
|
||||
extern const char g_kegs_version_str[];
|
||||
|
||||
#if 0
|
||||
char g_printf_buf[4096];
|
||||
int g_debug_file_fd = -1;
|
||||
extern int g_debug_file_fd;
|
||||
|
||||
/* HACK to debug startup issues when launched from Finder */
|
||||
int
|
||||
@ -110,7 +123,6 @@ printf(const char *fmt, ...)
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vsnprintf(g_printf_buf, 4090, fmt, ap);
|
||||
|
||||
if(g_debug_file_fd < 0) {
|
||||
g_debug_file_fd = open("/tmp/kegs.out",
|
||||
@ -118,8 +130,7 @@ printf(const char *fmt, ...)
|
||||
fprintf(stdout, "g_debug_file_fd = %d, %d\n", g_debug_file_fd,
|
||||
errno);
|
||||
}
|
||||
write(1, g_printf_buf, strlen(g_printf_buf));
|
||||
write(g_debug_file_fd, g_printf_buf, strlen(g_printf_buf));
|
||||
ret = kegs_vprintf(fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
@ -140,27 +151,103 @@ quit_event_handler(EventHandlerCallRef call_ref, EventRef event, void *ignore)
|
||||
}
|
||||
|
||||
void
|
||||
show_alert(const char *str1, const char *str2, const char *str3, int num)
|
||||
show_simple_alert(char *str1, char *str2, char *str3, int num)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
g_fatal_log_strs[0] = kegs_malloc_str(str1);
|
||||
g_fatal_log_strs[1] = kegs_malloc_str(str2);
|
||||
g_fatal_log_strs[2] = kegs_malloc_str(str3);
|
||||
g_fatal_log = 3;
|
||||
if(num != 0) {
|
||||
snprintf(buf, 250, ": %d", num);
|
||||
g_fatal_log_strs[g_fatal_log++] = kegs_malloc_str(buf);
|
||||
}
|
||||
x_show_alert(0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
x_dialog_create_kegs_conf(const char *str)
|
||||
{
|
||||
char *path;
|
||||
char tmp_buf[512];
|
||||
int ret;
|
||||
|
||||
ret = x_show_alert(1, str);
|
||||
if(ret) {
|
||||
// Create empty file
|
||||
path = "~/Library/KEGS";
|
||||
snprintf(tmp_buf, 500, "mkdir -p %s", path);
|
||||
system(tmp_buf);
|
||||
snprintf(tmp_buf, 500, "touch %s/%s", path, str);
|
||||
system(tmp_buf);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
x_show_alert(int is_fatal, const char *str)
|
||||
{
|
||||
DialogRef alert;
|
||||
DialogItemIndex out_item_hit;
|
||||
CFStringRef cfstrref;
|
||||
CFStringRef cfstrref, cfstrref2;
|
||||
CFStringRef okstrref;
|
||||
AlertStdCFStringAlertParamRec alert_param;
|
||||
OSStatus osstat;
|
||||
char *bufptr, *buf2ptr;
|
||||
int sum, len;
|
||||
int i;
|
||||
|
||||
if(num != 0) {
|
||||
snprintf(buf, 250, "%s%s%s: %d", str1, str2, str3, num);
|
||||
} else {
|
||||
snprintf(buf, 250, "%s%s%s", str1, str2, str3);
|
||||
/* The dialog eats all events--including key-up events */
|
||||
/* Call adb_all_keys_up() to prevent annoying key-repeat problems */
|
||||
/* for instance, a key-down causes a dialog to appear--and the */
|
||||
/* eats the key-up event...then as soon as the dialog goes, adb.c */
|
||||
/* auto-repeat will repeat the key, and the dialog re-appears...*/
|
||||
adb_all_keys_up();
|
||||
|
||||
sum = 20;
|
||||
for(i = 0; i < g_fatal_log; i++) {
|
||||
sum += strlen(g_fatal_log_strs[i]);
|
||||
}
|
||||
bufptr = malloc(sum);
|
||||
buf2ptr = bufptr;
|
||||
for(i = 0; i < g_fatal_log; i++) {
|
||||
len = strlen(g_fatal_log_strs[i]);
|
||||
len = MIN(len, sum);
|
||||
len = MAX(len, 0);
|
||||
memcpy(bufptr, g_fatal_log_strs[i], MIN(len, sum));
|
||||
bufptr += len;
|
||||
bufptr[0] = 0;
|
||||
sum = sum - len;
|
||||
}
|
||||
|
||||
cfstrref = CFStringCreateWithCString(NULL, buf,
|
||||
cfstrref = CFStringCreateWithCString(NULL, buf2ptr,
|
||||
kCFStringEncodingMacRoman);
|
||||
|
||||
CreateStandardAlert(kAlertStopAlert, cfstrref, CFSTR("Click OK"),
|
||||
NULL, &alert);
|
||||
RunStandardAlert(alert, NULL, &out_item_hit);
|
||||
}
|
||||
printf("buf2ptr: :%s:\n", buf2ptr);
|
||||
|
||||
osstat = GetStandardAlertDefaultParams(&alert_param,
|
||||
kStdCFStringAlertVersionOne);
|
||||
|
||||
if(str) {
|
||||
// Provide an extra option--create a file
|
||||
cfstrref2 = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
|
||||
CFSTR("Create ~/Library/KEGS/%s"), str);
|
||||
alert_param.otherText = cfstrref2;
|
||||
}
|
||||
okstrref = CFSTR("Click OK to continue");
|
||||
if(is_fatal) {
|
||||
okstrref = CFSTR("Clock OK to exit KEGS");
|
||||
}
|
||||
CreateStandardAlert(kAlertStopAlert, cfstrref, okstrref,
|
||||
&alert_param, &alert);
|
||||
out_item_hit = -1;
|
||||
RunStandardAlert(alert, NULL, &out_item_hit);
|
||||
printf("out_item_hit: %d\n", out_item_hit);
|
||||
free(buf2ptr);
|
||||
|
||||
clear_fatal_logs(); /* free the fatal_log string memory */
|
||||
return (out_item_hit >= 3);
|
||||
}
|
||||
|
||||
|
||||
pascal OSStatus
|
||||
@ -182,13 +269,13 @@ my_cmd_handler( EventHandlerCallRef handlerRef, EventRef event, void *userdata)
|
||||
osresult = noErr;
|
||||
break;
|
||||
case 'abou':
|
||||
show_alert("KEGSMAC v", g_kegs_version_str,
|
||||
show_simple_alert("KEGSMAC v", (char *)g_kegs_version_str,
|
||||
", Copyright 2004 Kent Dickey\n"
|
||||
"Latest version at http://kegs.sourceforge.net/\n", 0);
|
||||
osresult = noErr;
|
||||
break;
|
||||
case 'KCFG':
|
||||
g_config_control_panel = !g_config_control_panel;
|
||||
cfg_toggle_config_panel();
|
||||
osresult = noErr;
|
||||
break;
|
||||
case 'quit':
|
||||
@ -386,7 +473,7 @@ check_input_events()
|
||||
break;
|
||||
}
|
||||
if(err != noErr) {
|
||||
printf("err: %d\n", (int)err);
|
||||
printf("ReceiveNextEvent err: %d\n", (int)err);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -488,8 +575,10 @@ check_input_events()
|
||||
}
|
||||
mac_warp_mouse();
|
||||
} else {
|
||||
g_mac_mouse_x = mouse_point.h -BASE_MARGIN_LEFT;
|
||||
g_mac_mouse_y = mouse_point.v -BASE_MARGIN_TOP;
|
||||
g_mac_mouse_x = mouse_point.h -
|
||||
g_video_act_margin_left;
|
||||
g_mac_mouse_y = mouse_point.v -
|
||||
g_video_act_margin_top;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -723,6 +812,8 @@ main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// show_alert("About to show window", (int)g_main_window);
|
||||
update_main_window_size();
|
||||
|
||||
update_window();
|
||||
|
||||
// The window was created hidden so show it.
|
||||
@ -742,7 +833,7 @@ main(int argc, char* argv[])
|
||||
CantCreateWindow:
|
||||
CantSetMenuBar:
|
||||
CantGetNibRef:
|
||||
show_alert("ending", "", "error code", err);
|
||||
show_simple_alert("ending", "", "error code", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -773,6 +864,9 @@ xdriver_end()
|
||||
{
|
||||
|
||||
printf("xdriver_end\n");
|
||||
if(g_fatal_log >= 0) {
|
||||
x_show_alert(1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -932,6 +1026,12 @@ x_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy,
|
||||
void
|
||||
x_push_done()
|
||||
{
|
||||
CGrafPtr window_port;
|
||||
|
||||
SetPortWindowPort(g_main_window);
|
||||
window_port = GetWindowPort(g_main_window);
|
||||
|
||||
QDFlushPortBuffer(window_port, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -953,3 +1053,73 @@ x_hide_pointer(int do_hide)
|
||||
ShowCursor();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
x_full_screen(int do_full)
|
||||
{
|
||||
WindowRef new_window;
|
||||
short width, height;
|
||||
OSErr ret;
|
||||
|
||||
width = 640;
|
||||
height = 480;
|
||||
if(do_full && (g_mac_fullscreen_state == 0)) {
|
||||
g_main_window_saved = g_main_window;
|
||||
|
||||
GetWindowBounds(g_main_window, kWindowContentRgn,
|
||||
&g_main_window_saved_rect);
|
||||
ret = BeginFullScreen(&g_mac_fullscreen_state, 0,
|
||||
&width, &height, &new_window, 0, 0);
|
||||
printf("Ret beginfullscreen: %d\n", (int)ret);
|
||||
printf("New width: %d, new height: %d\n", width, height);
|
||||
if(ret == noErr) {
|
||||
g_main_window = new_window;
|
||||
} else {
|
||||
g_mac_fullscreen_state = 0;
|
||||
}
|
||||
} else if(!do_full && (g_mac_fullscreen_state != 0)) {
|
||||
ret = EndFullScreen(g_mac_fullscreen_state, 0);
|
||||
printf("ret endfullscreen: %d\n", (int)ret);
|
||||
g_main_window = g_main_window_saved;
|
||||
g_mac_fullscreen_state = 0;
|
||||
//InitCursor();
|
||||
SetWindowBounds(g_main_window, kWindowContentRgn,
|
||||
&g_main_window_saved_rect);
|
||||
}
|
||||
|
||||
update_main_window_size();
|
||||
|
||||
ShowWindow(g_main_window);
|
||||
BringToFront(g_main_window);
|
||||
update_window();
|
||||
}
|
||||
|
||||
void
|
||||
update_main_window_size()
|
||||
{
|
||||
Rect win_rect;
|
||||
int width, height;
|
||||
int left, excess_height;
|
||||
int top, bottom;
|
||||
|
||||
GetPortBounds(GetWindowPort(g_main_window), &win_rect);
|
||||
width = win_rect.right - win_rect.left;
|
||||
height = win_rect.bottom - win_rect.top;
|
||||
g_video_act_width = width;
|
||||
g_video_act_height = height;
|
||||
|
||||
left = MAX(0, (width - A2_WINDOW_WIDTH) / 2);
|
||||
left = MIN(left, BASE_MARGIN_LEFT);
|
||||
g_video_act_margin_left = left;
|
||||
g_video_act_margin_right = left;
|
||||
|
||||
|
||||
excess_height = (height - A2_WINDOW_HEIGHT) / 2;
|
||||
bottom = MAX(0, excess_height / 2); // No less than 0
|
||||
bottom = MIN(BASE_MARGIN_BOTTOM, bottom); // No more than 30
|
||||
g_video_act_margin_bottom = bottom;
|
||||
excess_height -= bottom;
|
||||
top = MAX(0, excess_height);
|
||||
top = MIN(BASE_MARGIN_TOP, top);
|
||||
g_video_act_margin_top = top;
|
||||
}
|
||||
|
629
src/moremem.c
629
src/moremem.c
File diff suppressed because it is too large
Load Diff
169
src/paddles.c
169
src/paddles.c
@ -8,25 +8,52 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_paddles_c[] = "@(#)$KmKId: paddles.c,v 1.7 2004-03-23 17:28:06-05 kentd Exp $";
|
||||
const char rcsid_paddles_c[] = "@(#)$KmKId: paddles.c,v 1.14 2004-10-19 14:52:36-04 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
|
||||
extern int g_mouse_fifo_x[]; /* from adb.c */
|
||||
extern int g_mouse_fifo_y[];
|
||||
extern int g_mouse_raw_x; /* from adb.c */
|
||||
extern int g_mouse_raw_y;
|
||||
|
||||
double g_paddle_trig_dcycs = 0.0;
|
||||
int g_swap_paddles = 0;
|
||||
int g_invert_paddles = 0;
|
||||
int g_joystick_scale_factor_x = 0x100;
|
||||
int g_joystick_scale_factor_y = 0x100;
|
||||
int g_joystick_trim_amount_x = 0;
|
||||
int g_joystick_trim_amount_y = 0;
|
||||
|
||||
int g_joystick_type = JOYSTICK_MOUSE;
|
||||
int g_joystick_type = 0; /* 0 = Keypad Joystick */
|
||||
int g_joystick_native_type1 = -1;
|
||||
int g_joystick_native_type2 = -1;
|
||||
int g_joystick_native_type = -1;
|
||||
|
||||
int g_paddle_button[4] = { 0, 0, 0, 0 };
|
||||
/* g_paddle_button[0] = button 0, etc */
|
||||
extern int g_paddle_buttons;
|
||||
|
||||
int g_paddle_val[4] = { 0, 0, 0, 0 };
|
||||
/* g_paddle_val[0]: Joystick X coord, [1]:Y coord */
|
||||
|
||||
double g_paddle_dcycs[4] = { 0.0, 0.0, 0.0, 0.0 };
|
||||
/* g_paddle_dcycs are the dcycs the paddle goes to 0 */
|
||||
|
||||
|
||||
void
|
||||
paddle_fixup_joystick_type()
|
||||
{
|
||||
/* If g_joystick_type points to an illegal value, change it */
|
||||
if(g_joystick_type == 2) {
|
||||
g_joystick_native_type = g_joystick_native_type1;
|
||||
if(g_joystick_native_type1 < 0) {
|
||||
g_joystick_type = 0;
|
||||
}
|
||||
}
|
||||
if(g_joystick_type == 3) {
|
||||
g_joystick_native_type = g_joystick_native_type2;
|
||||
if(g_joystick_native_type2 < 0) {
|
||||
g_joystick_type = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
paddle_trigger(double dcycs)
|
||||
@ -35,75 +62,117 @@ paddle_trigger(double dcycs)
|
||||
g_paddle_trig_dcycs = dcycs;
|
||||
|
||||
/* Determine what all the paddle values are right now */
|
||||
paddle_fixup_joystick_type();
|
||||
|
||||
switch(g_joystick_type) {
|
||||
case JOYSTICK_MOUSE:
|
||||
case 0: /* Keypad Joystick */
|
||||
paddle_trigger_keypad(dcycs);
|
||||
break;
|
||||
case 1: /* Mouse Joystick */
|
||||
paddle_trigger_mouse(dcycs);
|
||||
break;
|
||||
case JOYSTICK_LINUX:
|
||||
case JOYSTICK_WIN32_1:
|
||||
case JOYSTICK_WIN32_2:
|
||||
joystick_update();
|
||||
default:
|
||||
joystick_update(dcycs);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
paddle_trigger_mouse(double dcycs)
|
||||
{
|
||||
int val_x;
|
||||
int val_y;
|
||||
int val_x, val_y;
|
||||
int mouse_x, mouse_y;
|
||||
|
||||
val_x = 0;
|
||||
/* mous_phys_x is 0->560, convert that to 0-255 cyc */
|
||||
/* so, mult by 117 then divide by 256 */
|
||||
if(g_mouse_fifo_x[0] > BASE_MARGIN_LEFT) {
|
||||
val_x = (g_mouse_fifo_x[0] - BASE_MARGIN_LEFT) * 117;
|
||||
val_x = val_x >> 8;
|
||||
}
|
||||
|
||||
/* mous_phys_y is 0->384, convert that to 0-255 cyc */
|
||||
/* so, mult by 170 then divide by 256 (shift right by 8) */
|
||||
val_y = 0;
|
||||
if(g_mouse_fifo_y[0] > BASE_MARGIN_TOP) {
|
||||
val_y = ((g_mouse_fifo_y[0] - BASE_MARGIN_TOP) * 170) >> 8;
|
||||
}
|
||||
mouse_x = g_mouse_raw_x;
|
||||
mouse_y = g_mouse_raw_y;
|
||||
/* mous_phys_x is 0->560, convert that to -32768 to + 32767 cyc */
|
||||
/* So subtract 280 then mult by 117 */
|
||||
val_x = (mouse_x - 280) * 117;
|
||||
|
||||
if(val_x > 280) {
|
||||
val_x = 280;
|
||||
}
|
||||
if(val_y > 280) {
|
||||
val_y = 280;
|
||||
}
|
||||
/* mous_phys_y is 0->384, convert that to -32768 to + 32767 cyc */
|
||||
/* so subtract 192 then mult by 180 to overscale it a bit */
|
||||
val_y = (mouse_y - 192) * 180;
|
||||
|
||||
g_paddle_val[0] = val_x;
|
||||
g_paddle_val[1] = val_y;
|
||||
g_paddle_val[2] = 255;
|
||||
g_paddle_val[3] = 255;
|
||||
g_paddle_button[2] = 1;
|
||||
g_paddle_button[3] = 1;
|
||||
g_paddle_val[2] = 32767;
|
||||
g_paddle_val[3] = 32767;
|
||||
g_paddle_buttons |= 0xc;
|
||||
paddle_update_trigger_dcycs(dcycs);
|
||||
}
|
||||
|
||||
int
|
||||
read_paddles(int paddle, double dcycs)
|
||||
void
|
||||
paddle_trigger_keypad(double dcycs)
|
||||
{
|
||||
int get_y;
|
||||
int val_x, val_y;
|
||||
|
||||
|
||||
val_x = adb_get_keypad_xy(get_y=0);
|
||||
val_y = adb_get_keypad_xy(get_y=1);
|
||||
/* val_x and val_y are already scale -32768 to +32768 */
|
||||
|
||||
g_paddle_val[0] = val_x;
|
||||
g_paddle_val[1] = val_y;
|
||||
g_paddle_val[2] = 32767;
|
||||
g_paddle_val[3] = 32767;
|
||||
g_paddle_buttons |= 0xc;
|
||||
paddle_update_trigger_dcycs(dcycs);
|
||||
}
|
||||
|
||||
void
|
||||
paddle_update_trigger_dcycs(double dcycs)
|
||||
{
|
||||
double trig_dcycs;
|
||||
int val;
|
||||
int paddle_num;
|
||||
int scale, trim;
|
||||
int i;
|
||||
|
||||
/* This routine is called by any read to $c064-$c067 */
|
||||
for(i = 0; i < 4; i++) {
|
||||
paddle_num = i;
|
||||
if(g_swap_paddles) {
|
||||
paddle = paddle ^ 1;
|
||||
paddle_num = i ^ 1;
|
||||
}
|
||||
|
||||
paddle = paddle & 3;
|
||||
|
||||
val = g_paddle_val[paddle];
|
||||
|
||||
val = g_paddle_val[paddle_num];
|
||||
if(g_invert_paddles) {
|
||||
val = 255 - val;
|
||||
val = -val;
|
||||
}
|
||||
/* convert -32768 to +32768 into 0->2816.0 cycles (the */
|
||||
/* paddle delay const) */
|
||||
/* First multiply by the scale factor to adjust range */
|
||||
if(paddle_num & 1) {
|
||||
scale = g_joystick_scale_factor_y;
|
||||
trim = g_joystick_trim_amount_y;
|
||||
} else {
|
||||
scale = g_joystick_scale_factor_x;
|
||||
trim = g_joystick_trim_amount_x;
|
||||
}
|
||||
#if 0
|
||||
if(i == 0) {
|
||||
printf("val was %04x(%d) * scale %03x = %d\n",
|
||||
val, val, scale, (val*scale)>>16);
|
||||
}
|
||||
#endif
|
||||
val = val * scale >> 16;
|
||||
/* Val is now from -128 to + 128 since scale is */
|
||||
/* 256=1.0, 128 = 0.5 */
|
||||
val = val + 128 + trim;
|
||||
if(val >= 255) {
|
||||
val = 280; /* increase range */
|
||||
}
|
||||
trig_dcycs = dcycs + (val * 11.04);
|
||||
g_paddle_dcycs[i] = trig_dcycs;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert 0->255 into 0->2816.0 cycles (the paddle delay const) */
|
||||
trig_dcycs = g_paddle_trig_dcycs + (val * 11.0);
|
||||
int
|
||||
read_paddles(double dcycs, int paddle)
|
||||
{
|
||||
double trig_dcycs;
|
||||
|
||||
trig_dcycs = g_paddle_dcycs[paddle & 3];
|
||||
|
||||
if(dcycs < trig_dcycs) {
|
||||
return 0x80;
|
||||
@ -112,3 +181,9 @@ read_paddles(int paddle, double dcycs)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
paddle_update_buttons()
|
||||
{
|
||||
paddle_fixup_joystick_type();
|
||||
joystick_update_buttons();
|
||||
}
|
||||
|
91
src/protos.h
91
src/protos.h
@ -9,10 +9,13 @@
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_RCSID_C
|
||||
const char rcsid_protos_h[] = "@(#)$KmKId: protos.h,v 1.173 2004-03-23 17:26:19-05 kentd Exp $";
|
||||
const char rcsid_protos_h[] = "@(#)$KmKId: protos.h,v 1.188 2004-12-06 19:08:34-05 kentd Exp $";
|
||||
#endif
|
||||
|
||||
/* xdriver.c and macdriver.c and windriver.c */
|
||||
int x_show_alert(int is_fatal, const char *str);
|
||||
int win_nonblock_read_stdin(int fd, char *bufptr, int len);
|
||||
void x_dialog_create_kegs_conf(const char *str);
|
||||
void update_color_array(int col_num, int a2_color);
|
||||
void set_border_color(int val);
|
||||
void x_update_physical_colormap(void);
|
||||
@ -31,6 +34,7 @@ void x_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy,
|
||||
void x_push_done();
|
||||
void x_hide_pointer(int);
|
||||
void x_get_kimage(Kimage *kimage_ptr);
|
||||
void x_full_screen(int do_full);
|
||||
|
||||
/* test65.c */
|
||||
void do_gen_test(int got_num, int base_seed);
|
||||
@ -52,6 +56,7 @@ int get_memory16_act_stub_asm(word32 addr, int cycs);
|
||||
|
||||
void set_memory_c(word32 addr, word32 val, int cycs);
|
||||
void set_memory16_c(word32 addr, word32 val, int cycs);
|
||||
void set_memory24_c(word32 addr, word32 val, int cycs);
|
||||
|
||||
int enter_engine(Engine_reg *ptr);
|
||||
void clr_halt_act(void);
|
||||
@ -60,19 +65,19 @@ void set_halt_act(int val);
|
||||
/* special scc_macdriver.c prototypes */
|
||||
int scc_serial_mac_init(int port);
|
||||
void scc_serial_mac_change_params(int port);
|
||||
void scc_serial_mac_fill_readbuf(int port, double dcycs);
|
||||
void scc_serial_mac_fill_readbuf(int port, int space_left, double dcycs);
|
||||
void scc_serial_mac_empty_writebuf(int port);
|
||||
|
||||
/* special scc_windriver.c prototypes */
|
||||
int scc_serial_win_init(int port);
|
||||
void scc_serial_win_change_params(int port);
|
||||
void scc_serial_win_fill_readbuf(int port, double dcycs);
|
||||
void scc_serial_win_fill_readbuf(int port, int space_left, double dcycs);
|
||||
void scc_serial_win_empty_writebuf(int port);
|
||||
|
||||
/* special joystick_driver.c prototypes */
|
||||
void joystick_init(void);
|
||||
void joystick_update(void);
|
||||
void joystick_update_button(void);
|
||||
void joystick_update(double dcycs);
|
||||
void joystick_update_buttons(void);
|
||||
|
||||
|
||||
/* END_HDR */
|
||||
@ -103,8 +108,10 @@ int adb_read_c027(void);
|
||||
void adb_write_c027(int val);
|
||||
int read_adb_ram(word32 addr);
|
||||
void write_adb_ram(word32 addr, int val);
|
||||
int adb_get_keypad_xy(int get_y);
|
||||
int update_mouse(int x, int y, int button_states, int buttons_valid);
|
||||
int mouse_read_c024(double dcycs);
|
||||
void mouse_compress_fifo(double dcycs);
|
||||
void adb_key_event(int a2code, int is_up);
|
||||
word32 adb_read_c000(void);
|
||||
word32 adb_access_c010(void);
|
||||
@ -114,6 +121,7 @@ int adb_is_option_key_down(void);
|
||||
void adb_increment_speed(void);
|
||||
void adb_physical_key_update(int a2code, int is_up);
|
||||
void adb_virtual_key_update(int a2code, int is_up);
|
||||
void adb_all_keys_up(void);
|
||||
void adb_kbd_repeat_off(void);
|
||||
|
||||
|
||||
@ -127,9 +135,6 @@ void clk_write_bram(FILE *fconf);
|
||||
void update_cur_time(void);
|
||||
void clock_update(void);
|
||||
void clock_update_if_needed(void);
|
||||
word32 clock_read_c033(void);
|
||||
word32 clock_read_c034(void);
|
||||
void clock_write_c033(word32 val);
|
||||
void clock_write_c034(word32 val);
|
||||
void do_clock_data(void);
|
||||
|
||||
@ -141,10 +146,12 @@ void do_clock_data(void);
|
||||
void config_init_menus(Cfg_menu *menuptr);
|
||||
void config_init(void);
|
||||
void cfg_exit(void);
|
||||
void cfg_toggle_config_panel(void);
|
||||
void cfg_text_screen_dump(void);
|
||||
void config_vbl_update(int doit_3_persec);
|
||||
void config_parse_option(char *buf, int pos, int len, int line);
|
||||
void config_parse_bram(char *buf, int pos, int len);
|
||||
void config_load_roms(void);
|
||||
void config_parse_config_kegs_file(void);
|
||||
Disk *cfg_get_dsk_from_slot_drive(int slot, int drive);
|
||||
void config_generate_config_kegs_name(char *outstr, int maxlen, Disk *dsk, int with_extras);
|
||||
@ -166,7 +173,7 @@ void cfg_putchar(int c);
|
||||
void cfg_printf(const char *fmt, ...);
|
||||
void cfg_print_num(int num, int max_len);
|
||||
void cfg_get_disk_name(char *outstr, int maxlen, int type_ext, int with_extras);
|
||||
void cfg_parse_menu(Cfg_menu *menu_ptr, int menu_pos, int highlight_pos, int change);
|
||||
void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int change);
|
||||
void cfg_get_base_path(char *pathptr, const char *inptr, int go_up);
|
||||
void cfg_file_init(void);
|
||||
void cfg_free_alldirents(Cfg_listhdr *listhdrptr);
|
||||
@ -178,6 +185,7 @@ char *cfg_shorten_filename(const char *in_ptr, int maxlen);
|
||||
void cfg_fix_topent(Cfg_listhdr *listhdrptr);
|
||||
void cfg_file_draw(void);
|
||||
void cfg_partition_selected(void);
|
||||
void cfg_file_update_ptr(char *str);
|
||||
void cfg_file_selected(void);
|
||||
void cfg_file_handle_key(int key);
|
||||
void config_control_panel(void);
|
||||
@ -200,7 +208,9 @@ void xam_mem(int count);
|
||||
void show_hex_mem(int startbank, word32 start, int endbank, word32 end, int count);
|
||||
int read_line(char *buf, int len);
|
||||
void do_debug_list(void);
|
||||
void load_roms(void);
|
||||
void dis_do_memmove(void);
|
||||
void dis_do_pattern_search(void);
|
||||
void dis_do_compare(void);
|
||||
void do_debug_unix(void);
|
||||
void do_debug_load(void);
|
||||
int do_dis(FILE *outfile, word32 kpc, int accsize, int xsize, int op_provided, word32 instr);
|
||||
@ -216,7 +226,7 @@ void scc_hard_reset_port(int port);
|
||||
void scc_reset_port(int port);
|
||||
void scc_regen_clocks(int port);
|
||||
void scc_port_init(int port);
|
||||
void scc_try_to_empty_writebuf(int port);
|
||||
void scc_try_to_empty_writebuf(int port, double dcycs);
|
||||
void scc_try_fill_readbuf(int port, double dcycs);
|
||||
void scc_update(double dcycs);
|
||||
void do_scc_event(int type, double dcycs);
|
||||
@ -236,6 +246,8 @@ void scc_clr_tx_int(int port);
|
||||
void scc_set_zerocnt_int(int port);
|
||||
void scc_clr_zerocnt_int(int port);
|
||||
void scc_add_to_readbuf(int port, word32 val, double dcycs);
|
||||
void scc_add_to_readbufv(int port, double dcycs, const char *fmt, ...);
|
||||
void scc_transmit(int port, word32 val, double dcycs);
|
||||
void scc_add_to_writebuf(int port, word32 val, double dcycs);
|
||||
word32 scc_read_data(int port, double dcycs);
|
||||
void scc_write_data(int port, word32 val, double dcycs);
|
||||
@ -243,10 +255,23 @@ void scc_write_data(int port, word32 val, double dcycs);
|
||||
|
||||
/* scc_socket_driver.c */
|
||||
void scc_socket_init(int port);
|
||||
void scc_socket_maybe_open_incoming(int port, double dcycs);
|
||||
void scc_socket_open_outgoing(int port, double dcycs);
|
||||
void scc_socket_make_nonblock(int port, double dcycs);
|
||||
void scc_socket_change_params(int port);
|
||||
void scc_accept_socket(int port);
|
||||
void scc_socket_fill_readbuf(int port, double dcycs);
|
||||
void scc_socket_empty_writebuf(int port);
|
||||
void scc_socket_close(int port, int full_close, double dcycs);
|
||||
void scc_accept_socket(int port, double dcycs);
|
||||
void scc_socket_telnet_reqs(int port, double dcycs);
|
||||
void scc_socket_fill_readbuf(int port, int space_left, double dcycs);
|
||||
void scc_socket_recvd_char(int port, int c, double dcycs);
|
||||
void scc_socket_empty_writebuf(int port, double dcycs);
|
||||
void scc_socket_modem_write(int port, int c, double dcycs);
|
||||
void scc_socket_do_cmd_str(int port, double dcycs);
|
||||
void scc_socket_send_modem_code(int port, int code, double dcycs);
|
||||
void scc_socket_modem_hangup(int port, double dcycs);
|
||||
void scc_socket_modem_connect(int port, double dcycs);
|
||||
void scc_socket_modem_do_ring(int port, double dcycs);
|
||||
void scc_socket_do_answer(int port, double dcycs);
|
||||
|
||||
|
||||
/* scc_windriver.c */
|
||||
@ -257,6 +282,7 @@ void scc_socket_empty_writebuf(int port);
|
||||
|
||||
/* iwm.c */
|
||||
void iwm_init_drive(Disk *dsk, int smartport, int drive, int disk_525);
|
||||
void disk_set_num_tracks(Disk *dsk, int num_tracks);
|
||||
void iwm_init(void);
|
||||
void iwm_reset(void);
|
||||
void draw_iwm_status(int line, char *buf);
|
||||
@ -268,7 +294,6 @@ void iwm_move_to_track(Disk *dsk, int new_track);
|
||||
void iwm525_phase_change(int drive, int phase);
|
||||
int iwm_read_status35(double dcycs);
|
||||
void iwm_do_action35(double dcycs);
|
||||
void iwm_set_apple35_sel(int newval);
|
||||
int iwm_read_c0ec(double dcycs);
|
||||
int read_iwm(int loc, double dcycs);
|
||||
void write_iwm(int loc, int val, double dcycs);
|
||||
@ -279,20 +304,20 @@ int iwm_read_data(Disk *dsk, int fast_disk_emul, double dcycs);
|
||||
void iwm_write_data(Disk *dsk, word32 val, int fast_disk_emul, double dcycs);
|
||||
void sector_to_partial_nib(byte *in, byte *nib_ptr);
|
||||
int disk_unnib_4x4(Disk *dsk);
|
||||
int iwm_denib_track525(Disk *dsk, Track *trk, int qtr_track, byte *outbuf);
|
||||
int iwm_denib_track35(Disk *dsk, Track *trk, int qtr_track, byte *outbuf);
|
||||
int iwm_denib_track525(Disk *dsk, Trk *trk, int qtr_track, byte *outbuf);
|
||||
int iwm_denib_track35(Disk *dsk, Trk *trk, int qtr_track, byte *outbuf);
|
||||
int disk_track_to_unix(Disk *dsk, int qtr_track, byte *outbuf);
|
||||
void show_hex_data(byte *buf, int count);
|
||||
void disk_check_nibblization(Disk *dsk, int qtr_track, byte *buf, int size);
|
||||
void disk_unix_to_nib(Disk *dsk, int qtr_track, int unix_pos, int unix_len, int nib_len);
|
||||
void iwm_nibblize_track_nib525(Disk *dsk, Track *trk, byte *track_buf, int qtr_track);
|
||||
void iwm_nibblize_track_525(Disk *dsk, Track *trk, byte *track_buf, int qtr_track);
|
||||
void iwm_nibblize_track_35(Disk *dsk, Track *trk, byte *track_buf, int qtr_track);
|
||||
void iwm_nibblize_track_nib525(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track);
|
||||
void iwm_nibblize_track_525(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track);
|
||||
void iwm_nibblize_track_35(Disk *dsk, Trk *trk, byte *track_buf, int qtr_track);
|
||||
void disk_4x4_nib_out(Disk *dsk, word32 val);
|
||||
void disk_nib_out(Disk *dsk, byte val, int size);
|
||||
void disk_nib_end_track(Disk *dsk);
|
||||
void iwm_show_track(int slot_drive, int track);
|
||||
void iwm_show_a_track(Track *trk);
|
||||
void iwm_show_a_track(Trk *trk);
|
||||
|
||||
|
||||
/* joystick_driver.c */
|
||||
@ -334,9 +359,13 @@ int read_vid_counters(int loc, double dcycs);
|
||||
|
||||
|
||||
/* paddles.c */
|
||||
void paddle_fixup_joystick_type(void);
|
||||
void paddle_trigger(double dcycs);
|
||||
void paddle_trigger_mouse(double dcycs);
|
||||
int read_paddles(int paddle, double dcycs);
|
||||
void paddle_trigger_keypad(double dcycs);
|
||||
void paddle_update_trigger_dcycs(double dcycs);
|
||||
int read_paddles(double dcycs, int paddle);
|
||||
void paddle_update_buttons(void);
|
||||
|
||||
|
||||
/* sim65816.c */
|
||||
@ -351,11 +380,12 @@ void show_regs(void);
|
||||
void my_exit(int ret);
|
||||
void do_reset(void);
|
||||
void check_engine_asm_defines(void);
|
||||
byte *memalloc_align(int size, int skip_amt);
|
||||
byte *memalloc_align(int size, int skip_amt, void **alloc_ptr);
|
||||
void memory_ptr_init(void);
|
||||
int kegsmain(int argc, char **argv);
|
||||
void load_roms_init_memory(void);
|
||||
void kegs_expand_path(char *out_ptr, const char *in_ptr, int maxlen);
|
||||
void setup_kegs_file(char *outname, int maxlen, int ok_if_missing, const char **name_ptr);
|
||||
void setup_kegs_file(char *outname, int maxlen, int ok_if_missing, int can_create_file, const char **name_ptr);
|
||||
void initialize_events(void);
|
||||
void check_for_one_event_type(int type);
|
||||
void add_event_entry(double dcycs, int type);
|
||||
@ -371,8 +401,8 @@ void show_all_events(void);
|
||||
void show_pmhz(void);
|
||||
void setup_zip_speeds(void);
|
||||
void run_prog(void);
|
||||
void add_irq(void);
|
||||
void remove_irq(void);
|
||||
void add_irq(word32 irq_mask);
|
||||
void remove_irq(word32 irq_mask);
|
||||
void take_irq(int is_it_brk);
|
||||
void show_dtime_array(void);
|
||||
void update_60hz(double dcycs, double dtime_now);
|
||||
@ -388,6 +418,11 @@ void do_wdm(word32 arg);
|
||||
void do_wai(void);
|
||||
void do_stp(void);
|
||||
void size_fail(int val, word32 v1, word32 v2);
|
||||
int fatal_printf(const char *fmt, ...);
|
||||
int kegs_vprintf(const char *fmt, va_list ap);
|
||||
void must_write(int fd, char *bufptr, int len);
|
||||
void clear_fatal_logs(void);
|
||||
char *kegs_malloc_str(char *in_str);
|
||||
|
||||
|
||||
/* smartport.c */
|
||||
@ -433,8 +468,6 @@ int doc_read_c03c(double dcycs);
|
||||
int doc_read_c03d(double dcycs);
|
||||
void doc_write_c03c(int val, double dcycs);
|
||||
void doc_write_c03d(int val, double dcycs);
|
||||
void doc_write_c03e(int val);
|
||||
void doc_write_c03f(int val);
|
||||
void doc_show_ensoniq_state(int osc);
|
||||
|
||||
|
||||
@ -474,6 +507,7 @@ int video_rebuild_super_hires_palette(word32 scan_info, int line, int reparse);
|
||||
void redraw_changed_super_hires(int start_offset, int start_line, int num_lines, int in_reparse, byte *screen_data);
|
||||
void display_screen(void);
|
||||
void video_update_event_line(int line);
|
||||
void video_check_input_events(void);
|
||||
void video_update_through_line(int line);
|
||||
void video_refresh_lines(int st_line, int num_lines, int must_reparse);
|
||||
void refresh_border(void);
|
||||
@ -492,4 +526,5 @@ void video_update_color_array(int col_num, int a2_color);
|
||||
void video_update_colormap(void);
|
||||
void video_update_status_line(int line, const char *string);
|
||||
void video_show_debug_info(void);
|
||||
word32 float_bus(double dcycs);
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_RCSID_C
|
||||
const char rcsid_protos_engine_c_h[] = "@(#)$KmKId: protos_engine_c.h,v 1.10 2004-01-10 15:50:02-05 kentd Exp $";
|
||||
const char rcsid_protos_engine_c_h[] = "@(#)$KmKId: protos_engine_c.h,v 1.11 2004-10-11 22:48:16-04 kentd Exp $";
|
||||
#endif
|
||||
|
||||
/* END_HDR */
|
||||
@ -20,7 +20,7 @@ word32 get_memory8_io_stub(word32 addr, byte *stat, double *fcycs_ptr, double fp
|
||||
word32 get_memory16_pieces_stub(word32 addr, byte *stat, double *fcycs_ptr, Fplus *fplus_ptr, int in_bank);
|
||||
word32 get_memory24_pieces_stub(word32 addr, byte *stat, double *fcycs_ptr, Fplus *fplus_ptr, int in_bank);
|
||||
void set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr, double fplus_x_m1);
|
||||
void set_memory16_pieces_stub(word32 addr, word32 val, double *fcycs_ptr, Fplus *fplus_ptr, int in_bank);
|
||||
void set_memory16_pieces_stub(word32 addr, word32 val, double *fcycs_ptr, double fplus_1, double fplus_x_m1, int in_bank);
|
||||
void set_memory24_pieces_stub(word32 addr, word32 val, double *fcycs_ptr, Fplus *fplus_ptr, int in_bank);
|
||||
word32 get_memory_c(word32 addr, int cycs);
|
||||
word32 get_memory16_c(word32 addr, int cycs);
|
||||
|
@ -8,13 +8,15 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_protos_mac_h[] = "@(#)$KmKId: protos_macdriver.h,v 1.6 2004-03-23 17:27:31-05 kentd Exp $";
|
||||
const char rcsid_protos_mac_h[] = "@(#)$KmKId: protos_macdriver.h,v 1.11 2004-11-14 10:24:03-05 kentd Exp $";
|
||||
|
||||
/* END_HDR */
|
||||
|
||||
/* macdriver.c */
|
||||
pascal OSStatus quit_event_handler(EventHandlerCallRef call_ref, EventRef event, void *ignore);
|
||||
void show_alert(const char *str1, const char *str2, const char *str3, int num);
|
||||
void show_simple_alert(char *str1, char *str2, char *str3, int num);
|
||||
void x_dialog_create_kegs_conf(const char *str);
|
||||
int x_show_alert(int is_fatal, const char *str);
|
||||
pascal OSStatus my_cmd_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata);
|
||||
void update_window(void);
|
||||
void show_event(UInt32 event_class, UInt32 event_kind, int handled);
|
||||
@ -37,4 +39,6 @@ void x_push_done(void);
|
||||
void x_auto_repeat_on(int must);
|
||||
void x_auto_repeat_off(int must);
|
||||
void x_hide_pointer(int do_hide);
|
||||
void x_full_screen(int do_full);
|
||||
void update_main_window_size(void);
|
||||
|
||||
|
@ -8,29 +8,38 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_protos_x_h[] = "@(#)$KmKId: protos_xdriver.h,v 1.18 2002-11-19 03:10:38-05 kadickey Exp $";
|
||||
const char rcsid_protos_x_h[] = "@(#)$KmKId: protos_xdriver.h,v 1.19 2004-11-15 16:24:13-05 kentd Exp $";
|
||||
|
||||
/* END_HDR */
|
||||
|
||||
/* xdriver.c */
|
||||
int main(int argc, char **argv);
|
||||
void x_dialog_create_kegs_conf(const char *str);
|
||||
int x_show_alert(int is_fatal, const char *str);
|
||||
void x_update_color(int col_num, int red, int green, int blue, word32 rgb);
|
||||
void x_update_physical_colormap(void);
|
||||
void show_xcolor_array(void);
|
||||
int my_error_handler(Display *display, XErrorEvent *ev);
|
||||
void xdriver_end(void);
|
||||
void show_colormap(char *str, Colormap cmap, int index1, int index2, int index3);
|
||||
void x_badpipe(int signum);
|
||||
void dev_video_init(void);
|
||||
Visual *x_try_find_visual(int depth, int screen_num, XVisualInfo **visual_list_ptr);
|
||||
void x_set_mask_and_shift(word32 x_mask, word32 *mask_ptr, int *shift_left_ptr, int *shift_right_ptr);
|
||||
int xhandle_shm_error(Display *display, XErrorEvent *event);
|
||||
void x_get_kimage(Kimage *kimage_ptr);
|
||||
int get_shm(Kimage *kimage_ptr);
|
||||
void get_ximage(Kimage *kimage_ptr);
|
||||
void update_status_line(int line, const char *string);
|
||||
void redraw_status_lines(void);
|
||||
void x_redraw_status_lines(void);
|
||||
void x_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy, int width, int height);
|
||||
void x_push_done(void);
|
||||
int x_update_mouse(int raw_x, int raw_y, int button_states, int buttons_valid);
|
||||
void check_input_events(void);
|
||||
void x_hide_pointer(int do_hide);
|
||||
void handle_keysym(XEvent *xev_in);
|
||||
int x_keysym_to_a2code(int keysym, int is_up);
|
||||
void x_update_modifier_state(int state);
|
||||
void x_auto_repeat_on(int must);
|
||||
void x_auto_repeat_off(int must);
|
||||
void x_full_screen(int do_full);
|
||||
|
||||
|
208
src/scc.c
208
src/scc.c
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_scc_c[] = "@(#)$KmKId: scc.c,v 1.38 2003-11-20 23:50:32-05 kentd Exp $";
|
||||
const char rcsid_scc_c[] = "@(#)$KmKId: scc.c,v 1.44 2004-12-03 17:33:40-05 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
|
||||
@ -17,9 +17,10 @@ extern int g_code_yellow;
|
||||
extern double g_cur_dcycs;
|
||||
extern int g_raw_serial;
|
||||
extern int g_serial_out_masking;
|
||||
extern int g_irq_pending;
|
||||
|
||||
/* my scc port 0 == channel A = slot 1 */
|
||||
/* port 1 == channel B = slot 2 */
|
||||
/* my scc port 0 == channel A = slot 1 = c039/c03b */
|
||||
/* port 1 == channel B = slot 2 = c038/c03a */
|
||||
|
||||
#include "scc.h"
|
||||
#define SCC_R14_DPLL_SOURCE_BRG 0x100
|
||||
@ -45,23 +46,39 @@ void
|
||||
scc_init()
|
||||
{
|
||||
Scc *scc_ptr;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < 2; i++) {
|
||||
scc_ptr = &(scc_stat[i]);
|
||||
scc_ptr->accfd = -1;
|
||||
scc_ptr->sockfd = -1;
|
||||
scc_ptr->socket_state = -1;
|
||||
scc_ptr->rdwrfd = -1;
|
||||
scc_ptr->state = 0;
|
||||
scc_ptr->host_handle = 0;
|
||||
scc_ptr->host_handle2 = 0;
|
||||
scc_ptr->int_pending_rx = 0;
|
||||
scc_ptr->int_pending_tx = 0;
|
||||
scc_ptr->int_pending_zerocnt = 0;
|
||||
scc_ptr->br_event_pending = 0;
|
||||
scc_ptr->rx_event_pending = 0;
|
||||
scc_ptr->tx_event_pending = 0;
|
||||
scc_ptr->char_size = 8;
|
||||
scc_ptr->baud_rate = 9600;
|
||||
scc_ptr->telnet_mode = 0;
|
||||
scc_ptr->telnet_iac = 0;
|
||||
scc_ptr->out_char_dcycs = 0.0;
|
||||
scc_ptr->socket_num_rings = 0;
|
||||
scc_ptr->socket_last_ring_dcycs = 0;
|
||||
scc_ptr->modem_mode = 0;
|
||||
scc_ptr->modem_dial_or_acc_mode = 0;
|
||||
scc_ptr->modem_plus_mode = 0;
|
||||
scc_ptr->modem_s0_val = 0;
|
||||
scc_ptr->modem_cmd_len = 0;
|
||||
scc_ptr->modem_cmd_str[0] = 0;
|
||||
for(j = 0; j < 2; j++) {
|
||||
scc_ptr->telnet_local_mode[j] = 0;
|
||||
scc_ptr->telnet_remote_mode[j] = 0;
|
||||
scc_ptr->telnet_reqwill_mode[j] = 0;
|
||||
scc_ptr->telnet_reqdo_mode[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
scc_reset();
|
||||
@ -83,6 +100,7 @@ scc_reset()
|
||||
scc_ptr->in_wrptr = 0;
|
||||
scc_ptr->out_rdptr = 0;
|
||||
scc_ptr->out_wrptr = 0;
|
||||
scc_ptr->dcd = 0;
|
||||
scc_ptr->wantint_rx = 0;
|
||||
scc_ptr->wantint_tx = 0;
|
||||
scc_ptr->wantint_zerocnt = 0;
|
||||
@ -308,7 +326,7 @@ scc_port_init(int port)
|
||||
}
|
||||
|
||||
void
|
||||
scc_try_to_empty_writebuf(int port)
|
||||
scc_try_to_empty_writebuf(int port, double dcycs)
|
||||
{
|
||||
Scc *scc_ptr;
|
||||
int state;
|
||||
@ -329,7 +347,7 @@ scc_try_to_empty_writebuf(int port)
|
||||
scc_serial_win_empty_writebuf(port);
|
||||
#endif
|
||||
} else if(state == 1) {
|
||||
scc_socket_empty_writebuf(port);
|
||||
scc_socket_empty_writebuf(port, dcycs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,10 +355,22 @@ void
|
||||
scc_try_fill_readbuf(int port, double dcycs)
|
||||
{
|
||||
Scc *scc_ptr;
|
||||
int space_used, space_left;
|
||||
int state;
|
||||
|
||||
scc_ptr = &(scc_stat[port]);
|
||||
state = scc_ptr->state;
|
||||
|
||||
space_used = scc_ptr->in_wrptr - scc_ptr->in_rdptr;
|
||||
if(space_used < 0) {
|
||||
space_used += SCC_INBUF_SIZE;
|
||||
}
|
||||
space_left = (7*SCC_INBUF_SIZE/8) - space_used;
|
||||
if(space_left < 1) {
|
||||
/* Buffer is pretty full, don't try to get more */
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(scc_ptr->read_called_this_vbl) {
|
||||
return;
|
||||
@ -351,13 +381,13 @@ scc_try_fill_readbuf(int port, double dcycs)
|
||||
|
||||
if(state == 2) {
|
||||
#if defined(MAC)
|
||||
scc_serial_mac_fill_readbuf(port, dcycs);
|
||||
scc_serial_mac_fill_readbuf(port, space_left, dcycs);
|
||||
#endif
|
||||
#if defined(_WIN32)
|
||||
scc_serial_win_fill_readbuf(port, dcycs);
|
||||
scc_serial_win_fill_readbuf(port, space_left, dcycs);
|
||||
#endif
|
||||
} else if(state == 1) {
|
||||
scc_socket_fill_readbuf(port, dcycs);
|
||||
scc_socket_fill_readbuf(port, space_left, dcycs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,8 +400,8 @@ scc_update(double dcycs)
|
||||
scc_stat[0].read_called_this_vbl = 0;
|
||||
scc_stat[1].read_called_this_vbl = 0;
|
||||
|
||||
scc_try_to_empty_writebuf(0);
|
||||
scc_try_to_empty_writebuf(1);
|
||||
scc_try_to_empty_writebuf(0, dcycs);
|
||||
scc_try_to_empty_writebuf(1, dcycs);
|
||||
scc_try_fill_readbuf(0, dcycs);
|
||||
scc_try_fill_readbuf(1, dcycs);
|
||||
|
||||
@ -423,6 +453,9 @@ show_scc_state()
|
||||
scc_ptr->reg[j], scc_ptr->reg[j+1],
|
||||
scc_ptr->reg[j+2], scc_ptr->reg[j+3]);
|
||||
}
|
||||
printf("state: %d, accfd: %d, rdwrfd: %d, host:%p, host2:%p\n",
|
||||
scc_ptr->state, scc_ptr->accfd, scc_ptr->rdwrfd,
|
||||
scc_ptr->host_handle, scc_ptr->host_handle2);
|
||||
printf("in_rdptr: %04x, in_wr:%04x, out_rd:%04x, out_wr:%04x\n",
|
||||
scc_ptr->in_rdptr, scc_ptr->in_wrptr,
|
||||
scc_ptr->out_rdptr, scc_ptr->out_wrptr);
|
||||
@ -430,9 +463,6 @@ show_scc_state()
|
||||
scc_ptr->rx_queue_depth, scc_ptr->rx_queue[0],
|
||||
scc_ptr->rx_queue[1], scc_ptr->rx_queue[2],
|
||||
scc_ptr->rx_queue[3]);
|
||||
printf("int_pendings: rx:%d, tx:%d, zc:%d\n",
|
||||
scc_ptr->int_pending_rx, scc_ptr->int_pending_tx,
|
||||
scc_ptr->int_pending_zerocnt);
|
||||
printf("want_ints: rx:%d, tx:%d, zc:%d\n",
|
||||
scc_ptr->wantint_rx, scc_ptr->wantint_tx,
|
||||
scc_ptr->wantint_zerocnt);
|
||||
@ -446,6 +476,18 @@ show_scc_state()
|
||||
printf("char_size: %d, baud_rate: %d, mode: %d\n",
|
||||
scc_ptr->char_size, scc_ptr->baud_rate,
|
||||
scc_ptr->mode);
|
||||
printf("modem_dial_mode:%d, telnet_mode:%d iac:%d, "
|
||||
"modem_cmd_len:%d\n", scc_ptr->modem_dial_or_acc_mode,
|
||||
scc_ptr->telnet_mode, scc_ptr->telnet_iac,
|
||||
scc_ptr->modem_cmd_len);
|
||||
printf("telnet_loc_modes:%08x %08x, telnet_rem_motes:"
|
||||
"%08x %08x\n", scc_ptr->telnet_local_mode[0],
|
||||
scc_ptr->telnet_local_mode[1],
|
||||
scc_ptr->telnet_remote_mode[0],
|
||||
scc_ptr->telnet_remote_mode[1]);
|
||||
printf("modem_mode:%08x plus_mode: %d, out_char_dcycs: %f\n",
|
||||
scc_ptr->modem_mode, scc_ptr->modem_plus_mode,
|
||||
scc_ptr->out_char_dcycs);
|
||||
}
|
||||
|
||||
}
|
||||
@ -518,7 +560,11 @@ scc_read_reg(int port, double dcycs)
|
||||
switch(regnum) {
|
||||
case 0:
|
||||
case 4:
|
||||
ret = 0x68; /* 0x44 = no dcd, no cts,0x6c = dcd ok, cts ok*/
|
||||
ret = 0x60; /* 0x44 = no dcd, no cts,0x6c = dcd ok, cts ok*/
|
||||
if(scc_ptr->dcd) {
|
||||
ret |= 0x08;
|
||||
}
|
||||
ret |= 0x8; /* HACK HACK */
|
||||
if(scc_ptr->rx_queue_depth) {
|
||||
ret |= 0x01;
|
||||
}
|
||||
@ -559,12 +605,7 @@ scc_read_reg(int port, double dcycs)
|
||||
case 3:
|
||||
case 7:
|
||||
if(port == 0) {
|
||||
ret = (scc_stat[1].int_pending_zerocnt) |
|
||||
(scc_stat[1].int_pending_tx << 1) |
|
||||
(scc_stat[1].int_pending_rx << 2) |
|
||||
(scc_stat[0].int_pending_zerocnt << 3) |
|
||||
(scc_stat[0].int_pending_tx << 4) |
|
||||
(scc_stat[0].int_pending_rx << 5);
|
||||
ret = (g_irq_pending & 0x3f);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
@ -608,6 +649,7 @@ scc_write_reg(int port, word32 val, double dcycs)
|
||||
Scc *scc_ptr;
|
||||
word32 old_val;
|
||||
word32 changed_bits;
|
||||
word32 irq_mask;
|
||||
int regnum;
|
||||
int mode;
|
||||
int tmp1;
|
||||
@ -654,11 +696,16 @@ scc_write_reg(int port, word32 val, double dcycs)
|
||||
case 0x6: /* reset rr1 bits */
|
||||
break;
|
||||
case 0x7: /* reset highest pri int pending */
|
||||
if(scc_ptr->int_pending_rx) {
|
||||
irq_mask = g_irq_pending;
|
||||
if(port == 0) {
|
||||
/* Move SCC0 ints into SCC1 positions */
|
||||
irq_mask = irq_mask >> 3;
|
||||
}
|
||||
if(irq_mask & IRQ_PENDING_SCC1_RX) {
|
||||
scc_clr_rx_int(port);
|
||||
} else if(scc_ptr->int_pending_tx) {
|
||||
} else if(irq_mask & IRQ_PENDING_SCC1_TX) {
|
||||
scc_clr_tx_int(port);
|
||||
} else if(scc_ptr->int_pending_zerocnt) {
|
||||
} else if(irq_mask & IRQ_PENDING_SCC1_ZEROCNT) {
|
||||
scc_clr_zerocnt_int(port);
|
||||
}
|
||||
break;
|
||||
@ -673,7 +720,7 @@ scc_write_reg(int port, word32 val, double dcycs)
|
||||
break;
|
||||
case 0x1: /* reset rx crc */
|
||||
case 0x2: /* reset tx crc */
|
||||
halt_printf("Wr c03%x to wr0 of %02x!\n", 8+port, val);
|
||||
printf("Wr c03%x to wr0 of %02x!\n", 8+port, val);
|
||||
break;
|
||||
case 0x3: /* reset tx underrun/eom latch */
|
||||
/* if no extern status pending, or being reset now */
|
||||
@ -850,34 +897,48 @@ void
|
||||
scc_evaluate_ints(int port)
|
||||
{
|
||||
Scc *scc_ptr;
|
||||
word32 irq_add_mask, irq_remove_mask;
|
||||
int mie;
|
||||
|
||||
scc_ptr = &(scc_stat[port]);
|
||||
mie = scc_stat[0].reg[9] & 0x8; /* Master int en */
|
||||
|
||||
if(mie && scc_ptr->wantint_rx && !scc_ptr->int_pending_rx) {
|
||||
scc_ptr->int_pending_rx = 1;
|
||||
add_irq();
|
||||
if(!mie) {
|
||||
/* There can be no interrupts if MIE=0 */
|
||||
remove_irq(IRQ_PENDING_SCC1_RX | IRQ_PENDING_SCC1_TX |
|
||||
IRQ_PENDING_SCC1_ZEROCNT |
|
||||
IRQ_PENDING_SCC0_RX | IRQ_PENDING_SCC0_TX |
|
||||
IRQ_PENDING_SCC0_ZEROCNT);
|
||||
return;
|
||||
}
|
||||
if(scc_ptr->int_pending_rx && (!mie || !scc_ptr->wantint_rx)) {
|
||||
scc_ptr->int_pending_rx = 0;
|
||||
remove_irq();
|
||||
|
||||
irq_add_mask = 0;
|
||||
irq_remove_mask = 0;
|
||||
if(scc_ptr->wantint_rx) {
|
||||
irq_add_mask |= IRQ_PENDING_SCC1_RX;
|
||||
} else {
|
||||
irq_remove_mask |= IRQ_PENDING_SCC1_RX;
|
||||
}
|
||||
if(mie && scc_ptr->wantint_tx && !scc_ptr->int_pending_tx) {
|
||||
scc_ptr->int_pending_tx = 1;
|
||||
add_irq();
|
||||
if(scc_ptr->wantint_tx) {
|
||||
irq_add_mask |= IRQ_PENDING_SCC1_TX;
|
||||
} else {
|
||||
irq_remove_mask |= IRQ_PENDING_SCC1_TX;
|
||||
}
|
||||
if(scc_ptr->int_pending_tx && (!mie || !scc_ptr->wantint_tx)) {
|
||||
scc_ptr->int_pending_tx = 0;
|
||||
remove_irq();
|
||||
if(scc_ptr->wantint_zerocnt) {
|
||||
irq_add_mask |= IRQ_PENDING_SCC1_ZEROCNT;
|
||||
} else {
|
||||
irq_remove_mask |= IRQ_PENDING_SCC1_ZEROCNT;
|
||||
}
|
||||
if(mie && scc_ptr->wantint_zerocnt && !scc_ptr->int_pending_zerocnt) {
|
||||
scc_ptr->int_pending_zerocnt = 1;
|
||||
add_irq();
|
||||
if(port == 0) {
|
||||
/* Port 1 is in bits 0-2 and port 0 is in bits 3-5 */
|
||||
irq_add_mask = irq_add_mask << 3;
|
||||
irq_remove_mask = irq_remove_mask << 3;
|
||||
}
|
||||
if(scc_ptr->int_pending_zerocnt && (!mie || !scc_ptr->wantint_zerocnt)){
|
||||
scc_ptr->int_pending_zerocnt = 0;
|
||||
remove_irq();
|
||||
if(irq_add_mask) {
|
||||
add_irq(irq_add_mask);
|
||||
}
|
||||
if(irq_remove_mask) {
|
||||
remove_irq(irq_remove_mask);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1044,11 +1105,33 @@ scc_add_to_readbuf(int port, word32 val, double dcycs)
|
||||
}
|
||||
|
||||
void
|
||||
scc_add_to_writebuf(int port, word32 val, double dcycs)
|
||||
scc_add_to_readbufv(int port, double dcycs, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *bufptr;
|
||||
int ret, len, c;
|
||||
int i;
|
||||
|
||||
va_start(ap, fmt);
|
||||
bufptr = malloc(4096);
|
||||
bufptr[0] = 0;
|
||||
ret = vsnprintf(bufptr, 4090, fmt, ap);
|
||||
len = strlen(bufptr);
|
||||
for(i = 0; i < len; i++) {
|
||||
c = bufptr[i];
|
||||
if(c == 0x0a) {
|
||||
scc_add_to_readbuf(port, 0x0d, dcycs);
|
||||
}
|
||||
scc_add_to_readbuf(port, c, dcycs);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
scc_transmit(int port, word32 val, double dcycs)
|
||||
{
|
||||
Scc *scc_ptr;
|
||||
int out_wrptr;
|
||||
int out_wrptr_next;
|
||||
int out_rdptr;
|
||||
|
||||
scc_ptr = &(scc_stat[port]);
|
||||
@ -1081,6 +1164,31 @@ scc_add_to_writebuf(int port, word32 val, double dcycs)
|
||||
val = val & 0x7f;
|
||||
}
|
||||
|
||||
scc_add_to_writebuf(port, val, dcycs);
|
||||
}
|
||||
|
||||
void
|
||||
scc_add_to_writebuf(int port, word32 val, double dcycs)
|
||||
{
|
||||
Scc *scc_ptr;
|
||||
int out_wrptr;
|
||||
int out_wrptr_next;
|
||||
int out_rdptr;
|
||||
|
||||
scc_ptr = &(scc_stat[port]);
|
||||
|
||||
/* See if port initialized, if not, do so now */
|
||||
if(scc_ptr->state == 0) {
|
||||
scc_port_init(port);
|
||||
}
|
||||
if(scc_ptr->state < 0) {
|
||||
/* No working serial port, just toss it and go */
|
||||
return;
|
||||
}
|
||||
|
||||
out_wrptr = scc_ptr->out_wrptr;
|
||||
out_rdptr = scc_ptr->out_rdptr;
|
||||
|
||||
out_wrptr_next = (out_wrptr + 1) & (SCC_OUTBUF_SIZE - 1);
|
||||
if(out_wrptr_next != out_rdptr) {
|
||||
scc_ptr->out_buf[out_wrptr] = val;
|
||||
@ -1144,9 +1252,9 @@ scc_write_data(int port, word32 val, double dcycs)
|
||||
/* local loopback! */
|
||||
scc_add_to_readbuf(port, val, dcycs);
|
||||
} else {
|
||||
scc_add_to_writebuf(port, val, dcycs);
|
||||
scc_transmit(port, val, dcycs);
|
||||
}
|
||||
scc_try_to_empty_writebuf(port);
|
||||
scc_try_to_empty_writebuf(port, dcycs);
|
||||
|
||||
scc_maybe_tx_event(port, dcycs);
|
||||
}
|
||||
|
44
src/scc.h
44
src/scc.h
@ -9,30 +9,41 @@
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef INCLUDE_RCSID_C
|
||||
const char rcsid_scc_h[] = "@(#)$KmKId: scc.h,v 1.12 2003-11-21 00:27:00-05 kentd Exp $";
|
||||
const char rcsid_scc_h[] = "@(#)$KmKId: scc.h,v 1.17 2004-12-03 14:03:12-05 kentd Exp $";
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <winsock.h>
|
||||
# include <winsock2.h>
|
||||
#else
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#if defined(HPUX) || defined(__linux__) || defined(SOLARIS) || defined(MAC) || defined(__MACH__)
|
||||
#if defined(HPUX) || defined(__linux__) || defined(SOLARIS) || defined(MAC) || defined(__MACH__) || defined(_WIN32)
|
||||
# define SCC_SOCKETS
|
||||
#endif
|
||||
|
||||
|
||||
/* my scc port 0 == channel A, port 1 = channel B */
|
||||
|
||||
#define SCC_INBUF_SIZE 4096 /* must be a power of 2 */
|
||||
#define SCC_OUTBUF_SIZE 4096 /* must be a power of 2 */
|
||||
#define SCC_INBUF_SIZE 512 /* must be a power of 2 */
|
||||
#define SCC_OUTBUF_SIZE 512 /* must be a power of 2 */
|
||||
|
||||
#define SCC_MODEM_MAX_CMD_STR 128
|
||||
|
||||
#ifndef SOCKET
|
||||
# define SOCKET word32 /* for non-windows */
|
||||
#endif
|
||||
|
||||
STRUCT(Scc) {
|
||||
int port;
|
||||
int state;
|
||||
int accfd;
|
||||
SOCKET sockfd;
|
||||
int socket_state;
|
||||
int rdwrfd;
|
||||
void *host_handle;
|
||||
void *host_handle2;
|
||||
@ -60,9 +71,7 @@ STRUCT(Scc) {
|
||||
int wantint_rx;
|
||||
int wantint_tx;
|
||||
int wantint_zerocnt;
|
||||
int int_pending_rx;
|
||||
int int_pending_tx;
|
||||
int int_pending_zerocnt;
|
||||
int dcd;
|
||||
|
||||
double br_dcycs;
|
||||
double tx_dcycs;
|
||||
@ -74,5 +83,24 @@ STRUCT(Scc) {
|
||||
|
||||
int char_size;
|
||||
int baud_rate;
|
||||
double out_char_dcycs;
|
||||
|
||||
int socket_num_rings;
|
||||
int socket_last_ring_dcycs;
|
||||
word32 modem_mode;
|
||||
int modem_dial_or_acc_mode;
|
||||
int modem_plus_mode;
|
||||
int modem_s0_val;
|
||||
int telnet_mode;
|
||||
int telnet_iac;
|
||||
word32 telnet_local_mode[2];
|
||||
word32 telnet_remote_mode[2];
|
||||
word32 telnet_reqwill_mode[2];
|
||||
word32 telnet_reqdo_mode[2];
|
||||
int modem_cmd_len;
|
||||
byte modem_cmd_str[SCC_MODEM_MAX_CMD_STR + 5];
|
||||
};
|
||||
|
||||
#define SCCMODEM_NOECHO 0x0001
|
||||
#define SCCMODEM_NOVERBOSE 0x0002
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_scc_macdriver_c[] = "@(#)$KmKId: scc_macdriver.c,v 1.3 2003-11-03 01:52:49-05 kentd Exp $";
|
||||
const char rcsid_scc_macdriver_c[] = "@(#)$KmKId: scc_macdriver.c,v 1.5 2004-11-25 13:32:51-05 kentd Exp $";
|
||||
|
||||
/* This file contains the Mac serial calls */
|
||||
|
||||
@ -35,7 +35,8 @@ scc_serial_mac_init(int port)
|
||||
|
||||
scc_ptr->state = 0; /* mark as uninitialized */
|
||||
|
||||
sprintf(&str_buf[0], "/dev/tty.USA19QW11P1.1");
|
||||
/*sprintf(&str_buf[0], "/dev/tty.USA19QW11P1.1"); */
|
||||
sprintf(&str_buf[0], "/dev/tty.USA19H181P1.1");
|
||||
/* HACK: fix this... */
|
||||
|
||||
fd = open(&str_buf[0], O_RDWR | O_NONBLOCK);
|
||||
@ -129,7 +130,7 @@ scc_serial_mac_change_params(int port)
|
||||
}
|
||||
|
||||
void
|
||||
scc_serial_mac_fill_readbuf(int port, double dcycs)
|
||||
scc_serial_mac_fill_readbuf(int port, int space_left, double dcycs)
|
||||
{
|
||||
byte tmp_buf[256];
|
||||
Scc *scc_ptr;
|
||||
@ -145,7 +146,8 @@ scc_serial_mac_fill_readbuf(int port, double dcycs)
|
||||
}
|
||||
|
||||
/* Try reading some bytes */
|
||||
ret = read(fd, tmp_buf, 256);
|
||||
space_left = MIN(space_left, 256);
|
||||
ret = read(fd, tmp_buf, space_left);
|
||||
|
||||
if(ret > 0) {
|
||||
for(i = 0; i < ret; i++) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_scc_windriver_c[] = "@(#)$KmKId: scc_windriver.c,v 1.3 2003-09-20 15:05:15-04 kentd Exp $";
|
||||
const char rcsid_scc_windriver_c[] = "@(#)$KmKId: scc_windriver.c,v 1.4 2004-11-19 02:00:46-05 kentd Exp $";
|
||||
|
||||
/* This file contains the Win32 COM1/COM2 calls */
|
||||
|
||||
@ -151,7 +151,7 @@ scc_serial_win_change_params(int port)
|
||||
}
|
||||
|
||||
void
|
||||
scc_serial_win_fill_readbuf(int port, double dcycs)
|
||||
scc_serial_win_fill_readbuf(int port, int space_left, double dcycs)
|
||||
{
|
||||
byte tmp_buf[256];
|
||||
Scc *scc_ptr;
|
||||
@ -168,7 +168,8 @@ scc_serial_win_fill_readbuf(int port, double dcycs)
|
||||
}
|
||||
|
||||
/* Try reading some bytes */
|
||||
ret = ReadFile(host_handle, tmp_buf, 256, &bytes_read, NULL);
|
||||
space_left = MIN(256, space_left);
|
||||
ret = ReadFile(host_handle, tmp_buf, space_left, &bytes_read, NULL);
|
||||
|
||||
if(ret == 0) {
|
||||
printf("ReadFile ret 0\n");
|
||||
|
392
src/sim65816.c
392
src/sim65816.c
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_sim65816_c[] = "@(#)$KmKId: sim65816.c,v 1.346 2004-03-23 17:26:10-05 kentd Exp $";
|
||||
const char rcsid_sim65816_c[] = "@(#)$KmKId: sim65816.c,v 1.367 2004-11-22 02:39:26-05 kentd Exp $";
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@ -16,13 +16,16 @@ const char rcsid_sim65816_c[] = "@(#)$KmKId: sim65816.c,v 1.346 2004-03-23 17:26
|
||||
#include "defc.h"
|
||||
#undef INCLUDE_RCSID_C
|
||||
|
||||
#define PC_LOG_LEN (8*1024)
|
||||
|
||||
|
||||
char g_argv0_path[256] = "./";
|
||||
|
||||
const char *g_kegs_default_paths[] = { "", "./", "${HOME}/",
|
||||
"${HOME}/Library/KEGS/",
|
||||
"${0}/Contents/Resources/", "/usr/local/lib/",
|
||||
"/usr/local/kegs/", "/usr/local/lib/kegs/", "/usr/share/kegs/",
|
||||
"/usr/share/", "/var/lib/", "/usr/lib/", "/lib/", "/etc/",
|
||||
"/etc/kegs/", "${0}/", 0 };
|
||||
"/var/lib/", "/usr/lib/kegs/", "${0}/", 0 };
|
||||
|
||||
#define MAX_EVENTS 64
|
||||
|
||||
@ -38,26 +41,18 @@ const char *g_kegs_default_paths[] = { "", "./", "${HOME}/",
|
||||
|
||||
extern int g_stepping;
|
||||
|
||||
extern int statereg;
|
||||
extern int g_c068_statereg;
|
||||
extern int g_cur_a2_stat;
|
||||
|
||||
extern int wrdefram;
|
||||
extern int int_crom[8];
|
||||
extern int g_c08x_wrdefram;
|
||||
extern int g_c02d_int_crom;
|
||||
|
||||
extern int shadow_text;
|
||||
|
||||
extern int shadow_reg;
|
||||
extern int speed_fast;
|
||||
extern word32 g_slot_motor_detect;
|
||||
extern int g_c035_shadow_reg;
|
||||
extern int g_c036_val_speed;
|
||||
|
||||
extern int g_c023_val;
|
||||
extern int c023_1sec_int_irq_pending;
|
||||
extern int c023_scan_int_irq_pending;
|
||||
extern int c041_en_25sec_ints;
|
||||
extern int c041_en_vbl_ints;
|
||||
extern int g_c041_val;
|
||||
extern int g_c046_val;
|
||||
extern int c046_25sec_irq_pend;
|
||||
extern int c046_vbl_irq_pending;
|
||||
extern int g_zipgs_reg_c059;
|
||||
extern int g_zipgs_reg_c05a;
|
||||
extern int g_zipgs_reg_c05b;
|
||||
@ -71,9 +66,6 @@ extern int defs_instr_end_16;
|
||||
extern int op_routs_start;
|
||||
extern int op_routs_end;
|
||||
|
||||
extern int updated_mod_latch;
|
||||
extern int capslock_key_down;
|
||||
|
||||
Engine_reg engine;
|
||||
extern word32 table8[];
|
||||
extern word32 table16[];
|
||||
@ -83,7 +75,7 @@ extern byte doc_ram[];
|
||||
extern int g_iwm_motor_on;
|
||||
extern int g_fast_disk_emul;
|
||||
extern int g_slow_525_emul_wr;
|
||||
extern int g_apple35_sel;
|
||||
extern int g_c031_disk35;
|
||||
extern int g_config_control_panel;
|
||||
|
||||
extern int g_audio_enable;
|
||||
@ -94,7 +86,8 @@ void U_STACK_TRACE();
|
||||
double g_fcycles_stop = 0.0;
|
||||
int halt_sim = 0;
|
||||
int enter_debug = 0;
|
||||
int g_rom_version = 0;
|
||||
int g_rom_version = -1;
|
||||
int g_user_halt_bad = 0;
|
||||
int g_halt_on_bad_read = 0;
|
||||
int g_ignore_bad_acc = 1;
|
||||
int g_ignore_halts = 1;
|
||||
@ -102,15 +95,12 @@ int g_code_red = 0;
|
||||
int g_code_yellow = 0;
|
||||
int g_use_alib = 0;
|
||||
int g_raw_serial = 1;
|
||||
int g_iw2_emul = 0;
|
||||
int g_serial_out_masking = 0;
|
||||
int g_serial_modem[2] = { 0, 1 };
|
||||
|
||||
int g_config_iwm_vbl_count = 0;
|
||||
const char g_kegs_version_str[] = "0.86";
|
||||
|
||||
#if 0
|
||||
const double g_drecip_cycles_in_16ms = (1.0/(DCYCS_IN_16MS));
|
||||
const double g_dcycles_in_16ms = DCYCS_IN_16MS;
|
||||
#endif
|
||||
const char g_kegs_version_str[] = "0.91";
|
||||
|
||||
#define START_DCYCS (0.0)
|
||||
|
||||
@ -122,7 +112,8 @@ double g_dadjcycs = 0.0;
|
||||
|
||||
|
||||
int g_wait_pending = 0;
|
||||
int g_irq_pending = 0;
|
||||
int g_stp_pending = 0;
|
||||
extern int g_irq_pending;
|
||||
|
||||
int g_num_irq = 0;
|
||||
int g_num_brk = 0;
|
||||
@ -137,6 +128,11 @@ int g_engine_doc_int = 0;
|
||||
int g_testing = 0;
|
||||
int g_testing_enabled = 0;
|
||||
|
||||
#define MAX_FATAL_LOGS 20
|
||||
|
||||
int g_debug_file_fd = -1;
|
||||
int g_fatal_log = -1;
|
||||
char *g_fatal_log_strs[MAX_FATAL_LOGS];
|
||||
|
||||
word32 stop_run_at;
|
||||
|
||||
@ -161,25 +157,28 @@ byte *g_dummy_memory1_ptr = 0;
|
||||
byte *g_rom_fc_ff_ptr = 0;
|
||||
byte *g_rom_cards_ptr = 0;
|
||||
|
||||
void *g_memory_alloc_ptr = 0; /* for freeing memory area */
|
||||
|
||||
Page_info page_info_rd_wr[2*65536 + PAGE_INFO_PAD_SIZE];
|
||||
|
||||
int kbd_in_end = 0;
|
||||
byte kbd_in_buf[LEN_KBD_BUF];
|
||||
Pc_log g_pc_log_array[PC_LOG_LEN + 2];
|
||||
Data_log g_data_log_array[PC_LOG_LEN + 2];
|
||||
|
||||
Pc_log *g_log_pc_ptr = &(g_pc_log_array[0]);
|
||||
Pc_log *g_log_pc_start_ptr = &(g_pc_log_array[0]);
|
||||
Pc_log *g_log_pc_end_ptr = &(g_pc_log_array[PC_LOG_LEN]);
|
||||
|
||||
#define PC_LOG_LEN (8*1024)
|
||||
|
||||
Pc_log pc_log_array[PC_LOG_LEN + 2];
|
||||
|
||||
Pc_log *log_pc_ptr = &(pc_log_array[0]);
|
||||
Pc_log *log_pc_start_ptr = &(pc_log_array[0]);
|
||||
Pc_log *log_pc_end_ptr = &(pc_log_array[PC_LOG_LEN]);
|
||||
Data_log *g_log_data_ptr = &(g_data_log_array[0]);
|
||||
Data_log *g_log_data_start_ptr = &(g_data_log_array[0]);
|
||||
Data_log *g_log_data_end_ptr = &(g_data_log_array[PC_LOG_LEN]);
|
||||
|
||||
|
||||
void
|
||||
show_pc_log()
|
||||
{
|
||||
FILE *pcfile;
|
||||
Pc_log *log_pc_ptr;
|
||||
Data_log *log_data_ptr;
|
||||
double dcycs;
|
||||
double start_dcycs;
|
||||
word32 instr;
|
||||
@ -188,23 +187,52 @@ show_pc_log()
|
||||
word32 stack, direct;
|
||||
word32 dbank;
|
||||
word32 kpc;
|
||||
int data_wrap;
|
||||
int accsize, xsize;
|
||||
int num;
|
||||
int i;
|
||||
|
||||
pcfile = fopen("pc_log_out", "wt");
|
||||
pcfile = fopen("pc_log_out", "w");
|
||||
if(pcfile == 0) {
|
||||
fprintf(stderr,"fopen failed...errno: %d\n", errno);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
log_pc_ptr = g_log_pc_ptr;
|
||||
log_data_ptr = g_log_data_ptr;
|
||||
#if 0
|
||||
fprintf(pcfile, "current pc_log_ptr: %p, start: %p, end: %p\n",
|
||||
log_pc_ptr, log_pc_start_ptr, log_pc_end_ptr);
|
||||
#endif
|
||||
|
||||
start_dcycs = log_pc_ptr->dcycs;
|
||||
dcycs = start_dcycs;
|
||||
|
||||
data_wrap = 0;
|
||||
/* find first data entry */
|
||||
while(data_wrap < 2 && (log_data_ptr->dcycs < dcycs)) {
|
||||
log_data_ptr++;
|
||||
if(log_data_ptr >= g_log_data_end_ptr) {
|
||||
log_data_ptr = g_log_data_start_ptr;
|
||||
data_wrap++;
|
||||
}
|
||||
}
|
||||
fprintf(pcfile, "start_dcycs: %9.2f\n", start_dcycs);
|
||||
|
||||
for(i = 0; i < PC_LOG_LEN; i++) {
|
||||
dcycs = log_pc_ptr->dcycs;
|
||||
while((data_wrap < 2) && (log_data_ptr->dcycs <= dcycs) &&
|
||||
(log_data_ptr->dcycs >= start_dcycs)) {
|
||||
fprintf(pcfile, "DATA set %06x = %06x (%d) %9.2f\n",
|
||||
log_data_ptr->addr, log_data_ptr->val,
|
||||
log_data_ptr->size,
|
||||
log_data_ptr->dcycs - start_dcycs);
|
||||
log_data_ptr++;
|
||||
if(log_data_ptr >= g_log_data_end_ptr) {
|
||||
log_data_ptr = g_log_data_start_ptr;
|
||||
data_wrap++;
|
||||
}
|
||||
}
|
||||
dbank = (log_pc_ptr->dbank_kpc >> 24) & 0xff;
|
||||
kpc = log_pc_ptr->dbank_kpc & 0xffffff;
|
||||
instr = log_pc_ptr->instr;
|
||||
@ -214,9 +242,8 @@ show_pc_log()
|
||||
yreg = log_pc_ptr->xreg_yreg & 0xffff;;
|
||||
stack = (log_pc_ptr->stack_direct >> 16) & 0xffff;;
|
||||
direct = log_pc_ptr->stack_direct & 0xffff;;
|
||||
dcycs = log_pc_ptr->dcycs;
|
||||
|
||||
num = log_pc_ptr - log_pc_start_ptr;
|
||||
num = log_pc_ptr - g_log_pc_start_ptr;
|
||||
|
||||
accsize = 2;
|
||||
xsize = 2;
|
||||
@ -234,8 +261,8 @@ show_pc_log()
|
||||
|
||||
do_dis(pcfile, kpc, accsize, xsize, 1, instr);
|
||||
log_pc_ptr++;
|
||||
if(log_pc_ptr >= log_pc_end_ptr) {
|
||||
log_pc_ptr = log_pc_start_ptr;
|
||||
if(log_pc_ptr >= g_log_pc_end_ptr) {
|
||||
log_pc_ptr = g_log_pc_start_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -380,7 +407,7 @@ get_memory_io(word32 loc, double *cyc_ptr)
|
||||
}
|
||||
|
||||
g_code_yellow++;
|
||||
if(g_ignore_bad_acc) {
|
||||
if(g_ignore_bad_acc && !g_user_halt_bad) {
|
||||
/* print no message, just get out. User doesn't want */
|
||||
/* to be bothered by buggy programs */
|
||||
return 0;
|
||||
@ -389,7 +416,7 @@ get_memory_io(word32 loc, double *cyc_ptr)
|
||||
printf("get_memory_io for addr: %06x\n", loc);
|
||||
printf("stat for addr: %06x = %p\n", loc,
|
||||
GET_PAGE_INFO_RD((loc >> 8) & 0xffff));
|
||||
set_halt(g_halt_on_bad_read);
|
||||
set_halt(g_halt_on_bad_read | g_user_halt_bad);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -498,7 +525,7 @@ set_memory_io(word32 loc, int val, double *cyc_ptr)
|
||||
return;
|
||||
}
|
||||
|
||||
if(g_ignore_bad_acc) {
|
||||
if(g_ignore_bad_acc && !g_user_halt_bad) {
|
||||
/* print no message, just get out. User doesn't want */
|
||||
/* to be bothered by buggy programs */
|
||||
return;
|
||||
@ -579,15 +606,14 @@ my_exit(int ret)
|
||||
void
|
||||
do_reset()
|
||||
{
|
||||
int i;
|
||||
|
||||
statereg = 0x08 + 0x04 + 0x01; /* rdrom, lcbank2, intcx */
|
||||
g_c068_statereg = 0x08 + 0x04 + 0x01; /* rdrom, lcbank2, intcx */
|
||||
g_c035_shadow_reg = 0;
|
||||
|
||||
wrdefram = 1;
|
||||
for(i = 1; i < 7; i++) {
|
||||
int_crom[i] = 0;
|
||||
}
|
||||
int_crom[7] = 0;
|
||||
g_c08x_wrdefram = 1;
|
||||
g_c02d_int_crom = 0;
|
||||
g_c023_val = 0;
|
||||
g_c041_val = 0;
|
||||
|
||||
engine.psr = (engine.psr | 0x134) & ~(0x08);
|
||||
engine.stack = 0x100 + (engine.stack & 0xff);
|
||||
@ -596,6 +622,7 @@ do_reset()
|
||||
engine.xreg &= 0xff;
|
||||
engine.yreg &= 0xff;
|
||||
g_wait_pending = 0;
|
||||
g_stp_pending = 0;
|
||||
|
||||
|
||||
video_reset();
|
||||
@ -606,6 +633,8 @@ do_reset()
|
||||
setup_pageinfo();
|
||||
change_display_mode(g_cur_dcycs);
|
||||
|
||||
g_irq_pending = 0;
|
||||
|
||||
engine.kpc = get_memory16_c(0x00fffc, 0);
|
||||
|
||||
g_stepping = 0;
|
||||
@ -665,14 +694,18 @@ check_engine_asm_defines()
|
||||
}
|
||||
|
||||
byte *
|
||||
memalloc_align(int size, int skip_amt)
|
||||
memalloc_align(int size, int skip_amt, void **alloc_ptr)
|
||||
{
|
||||
byte *bptr;
|
||||
word32 addr;
|
||||
word32 offset;
|
||||
|
||||
skip_amt = MAX(256, skip_amt);
|
||||
bptr = malloc(size + skip_amt);
|
||||
bptr = calloc(size + skip_amt, 1);
|
||||
if(alloc_ptr) {
|
||||
/* Save allocation address */
|
||||
*alloc_ptr = bptr;
|
||||
}
|
||||
|
||||
addr = PTR2WORD(bptr) & 0xff;
|
||||
|
||||
@ -681,11 +714,7 @@ memalloc_align(int size, int skip_amt)
|
||||
|
||||
offset = ((addr + skip_amt - 1) & (~0xff)) - addr;
|
||||
|
||||
bptr += offset;
|
||||
|
||||
/* Gilles Tschopp recommended zeroing memory, this is a good idea */
|
||||
memset(bptr, 0, size);
|
||||
return bptr;
|
||||
return (bptr + offset);
|
||||
}
|
||||
|
||||
void
|
||||
@ -693,9 +722,15 @@ memory_ptr_init()
|
||||
{
|
||||
word32 mem_size;
|
||||
|
||||
/* This routine may be called several times--each time the ROM file */
|
||||
/* changes this will be called */
|
||||
mem_size = MIN(0xdf0000, g_mem_size_base + g_mem_size_exp);
|
||||
g_mem_size_total = mem_size;
|
||||
g_memory_ptr = memalloc_align(mem_size, 3*1024);
|
||||
if(g_memory_alloc_ptr) {
|
||||
free(g_memory_alloc_ptr);
|
||||
g_memory_alloc_ptr = 0;
|
||||
}
|
||||
g_memory_ptr = memalloc_align(mem_size, 256, &g_memory_alloc_ptr);
|
||||
|
||||
printf("RAM size is 0 - %06x (%.2fMB)\n", mem_size,
|
||||
(double)mem_size/(1024.0*1024.0));
|
||||
@ -807,8 +842,7 @@ kegsmain(int argc, char **argv)
|
||||
printf("Not using X shared memory\n");
|
||||
g_use_shmem = 0;
|
||||
} else if(!strcmp("-joystick", argv[i])) {
|
||||
printf("Trying to use joystick\n");
|
||||
joystick_init();
|
||||
printf("Ignoring -joystick option\n");
|
||||
} else if(!strcmp("-dhr140", argv[i])) {
|
||||
printf("Using simple dhires color map\n");
|
||||
g_use_dhr140 = 1;
|
||||
@ -854,8 +888,7 @@ kegsmain(int argc, char **argv)
|
||||
iwm_init();
|
||||
config_init();
|
||||
|
||||
load_roms();
|
||||
memory_ptr_init();
|
||||
load_roms_init_memory();
|
||||
|
||||
init_reg();
|
||||
clear_halt();
|
||||
@ -870,8 +903,11 @@ kegsmain(int argc, char **argv)
|
||||
sound_init();
|
||||
|
||||
scc_init();
|
||||
clk_setup_bram_version(); /* load_roms must be called first! */
|
||||
adb_init();
|
||||
joystick_init();
|
||||
if(g_rom_version >= 3) {
|
||||
g_c036_val_speed |= 0x40; /* set power-on bit */
|
||||
}
|
||||
|
||||
do_reset();
|
||||
g_stepping = 0;
|
||||
@ -884,6 +920,27 @@ kegsmain(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
load_roms_init_memory()
|
||||
{
|
||||
config_load_roms();
|
||||
memory_ptr_init();
|
||||
clk_setup_bram_version(); /* Must be after config_load_roms */
|
||||
if(g_rom_version >= 3) {
|
||||
g_c036_val_speed |= 0x40; /* set power-on bit */
|
||||
} else {
|
||||
g_c036_val_speed &= (~0x40); /* clear the bit */
|
||||
}
|
||||
do_reset();
|
||||
|
||||
/* if user booted ROM 01, switches to ROM 03, then switches back */
|
||||
/* to ROM 01, then the reset routines call to Tool $0102 looks */
|
||||
/* at uninitialized $e1/15fe and if it is negative it will JMP */
|
||||
/* through $e1/1688 which ROM 03 left pointing to fc/0199 */
|
||||
/* So set e1/15fe = 0 */
|
||||
set_memory16_c(0xe115fe, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
kegs_expand_path(char *out_ptr, const char *in_ptr, int maxlen)
|
||||
{
|
||||
@ -952,7 +1009,7 @@ kegs_expand_path(char *out_ptr, const char *in_ptr, int maxlen)
|
||||
|
||||
void
|
||||
setup_kegs_file(char *outname, int maxlen, int ok_if_missing,
|
||||
const char **name_ptr)
|
||||
int can_create_file, const char **name_ptr)
|
||||
{
|
||||
char local_path[256];
|
||||
struct stat stat_buf;
|
||||
@ -984,20 +1041,41 @@ setup_kegs_file(char *outname, int maxlen, int ok_if_missing,
|
||||
path_ptr++;
|
||||
}
|
||||
|
||||
if(ok_if_missing) {
|
||||
outname[0] = 0;
|
||||
if(ok_if_missing > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* couldn't find it, print out all the attempts */
|
||||
path_ptr = save_path_ptr;
|
||||
printf("Could not find %s in any of these directories:\n", *name_ptr);
|
||||
fatal_printf("Could not find required file \"%s\" in any of these "
|
||||
"directories:\n", *name_ptr);
|
||||
while(*path_ptr) {
|
||||
printf(" %s\n", *path_ptr++);
|
||||
fatal_printf(" %s\n", *path_ptr++);
|
||||
}
|
||||
|
||||
if(can_create_file) {
|
||||
// Ask user if it's OK to create the file
|
||||
x_dialog_create_kegs_conf(*name_ptr);
|
||||
can_create_file = 0;
|
||||
|
||||
// But clear out the fatal_printfs first
|
||||
clear_fatal_logs();
|
||||
setup_kegs_file(outname, maxlen, ok_if_missing,
|
||||
can_create_file, name_ptr);
|
||||
// It's one-level of recursion--it cannot loop since we
|
||||
// clear can_create_file.
|
||||
// If it returns, then there was succes and we should get out
|
||||
return;
|
||||
} else if(ok_if_missing) {
|
||||
/* Just show an alert and return if ok_if_missing < 0 */
|
||||
x_show_alert(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
system("pwd");
|
||||
|
||||
exit(2);
|
||||
my_exit(2);
|
||||
}
|
||||
|
||||
Event g_event_list[MAX_EVENTS];
|
||||
@ -1248,14 +1326,11 @@ Fplus g_recip_projected_pmhz_fast;
|
||||
Fplus g_recip_projected_pmhz_zip;
|
||||
Fplus g_recip_projected_pmhz_unl;
|
||||
|
||||
Fplus *g_cur_fplus_ptr = 0;
|
||||
|
||||
void
|
||||
show_pmhz()
|
||||
{
|
||||
printf("Pmhz: %f, plus_1: %f, fast: %d, limit: %d\n",
|
||||
g_projected_pmhz, g_cur_fplus_ptr->plus_1, speed_fast,
|
||||
g_limit_speed);
|
||||
printf("Pmhz: %f, c036:%02x, limit: %d\n",
|
||||
g_projected_pmhz, g_c036_val_speed, g_limit_speed);
|
||||
|
||||
}
|
||||
|
||||
@ -1329,12 +1404,15 @@ run_prog()
|
||||
zip_speed_0tof = g_zipgs_reg_c05a & 0xf0;
|
||||
setup_zip_speeds();
|
||||
|
||||
if(g_cur_fplus_ptr == 0) {
|
||||
if(engine.fplus_ptr == 0) {
|
||||
g_recip_projected_pmhz_unl = g_recip_projected_pmhz_slow;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
fflush(stdout);
|
||||
if(g_config_control_panel) {
|
||||
config_control_panel();
|
||||
}
|
||||
|
||||
if(g_irq_pending && !(engine.psr & 0x4)) {
|
||||
irq_printf("taking an irq!\n");
|
||||
@ -1344,11 +1422,11 @@ run_prog()
|
||||
|
||||
motor_on = g_iwm_motor_on;
|
||||
limit_speed = g_limit_speed;
|
||||
apple35_sel = g_apple35_sel;
|
||||
apple35_sel = g_c031_disk35 & 0x40;
|
||||
zip_en = ((g_zipgs_reg_c05b & 0x10) == 0);
|
||||
zip_follow_cps = ((g_zipgs_reg_c059 & 0x8) != 0);
|
||||
zip_speed_0tof_new = g_zipgs_reg_c05a & 0xf0;
|
||||
fast = speed_fast || (zip_en && !zip_follow_cps);
|
||||
fast = (g_c036_val_speed & 0x80) || (zip_en && !zip_follow_cps);
|
||||
|
||||
if(zip_speed_0tof_new != zip_speed_0tof) {
|
||||
zip_speed_0tof = zip_speed_0tof_new;
|
||||
@ -1356,7 +1434,7 @@ run_prog()
|
||||
}
|
||||
|
||||
iwm_1 = motor_on && !apple35_sel &&
|
||||
(g_slot_motor_detect & 0x4) &&
|
||||
(g_c036_val_speed & 0x4) &&
|
||||
(g_slow_525_emul_wr || !g_fast_disk_emul);
|
||||
iwm_25 = (motor_on && apple35_sel) && !g_fast_disk_emul;
|
||||
faster_than_28 = fast && (!iwm_1 && !iwm_25) && zip_en &&
|
||||
@ -1381,7 +1459,6 @@ run_prog()
|
||||
fplus_ptr = &g_recip_projected_pmhz_slow;
|
||||
}
|
||||
|
||||
g_cur_fplus_ptr = fplus_ptr;
|
||||
engine.fplus_ptr = fplus_ptr;
|
||||
|
||||
this_type = g_event_start.next->type;
|
||||
@ -1514,9 +1591,6 @@ run_prog()
|
||||
if(g_stepping) {
|
||||
break;
|
||||
}
|
||||
if(g_config_control_panel) {
|
||||
config_control_panel();
|
||||
}
|
||||
}
|
||||
|
||||
if(!g_testing) {
|
||||
@ -1527,19 +1601,20 @@ run_prog()
|
||||
}
|
||||
|
||||
void
|
||||
add_irq()
|
||||
add_irq(word32 irq_mask)
|
||||
{
|
||||
g_irq_pending++;
|
||||
if(g_irq_pending & irq_mask) {
|
||||
/* Already requested, just get out */
|
||||
return;
|
||||
}
|
||||
g_irq_pending |= irq_mask;
|
||||
set_halt(HALT_EVENT);
|
||||
}
|
||||
|
||||
void
|
||||
remove_irq()
|
||||
remove_irq(word32 irq_mask)
|
||||
{
|
||||
g_irq_pending--;
|
||||
if(g_irq_pending < 0) {
|
||||
halt_printf("remove_irq: g_irq_pending: %d\n", g_irq_pending);
|
||||
}
|
||||
g_irq_pending = g_irq_pending & (~irq_mask);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1559,10 +1634,6 @@ take_irq(int is_it_brk)
|
||||
g_wait_pending = 0;
|
||||
}
|
||||
|
||||
if(g_irq_pending < 0) {
|
||||
halt_printf("g_irq_pending: %d!\n", g_irq_pending);
|
||||
}
|
||||
|
||||
if(engine.psr & 0x100) {
|
||||
/* Emulation */
|
||||
set_memory_c(engine.stack, (engine.kpc >> 8) & 0xff, 0);
|
||||
@ -1577,7 +1648,7 @@ take_irq(int is_it_brk)
|
||||
engine.stack = ((engine.stack -1) & 0xff) + 0x100;
|
||||
|
||||
va = 0xfffffe;
|
||||
if(shadow_reg & 0x40) {
|
||||
if(g_c035_shadow_reg & 0x40) {
|
||||
/* I/O shadowing off...use ram locs */
|
||||
va = 0x00fffe;
|
||||
}
|
||||
@ -1599,13 +1670,13 @@ take_irq(int is_it_brk)
|
||||
if(is_it_brk) {
|
||||
/* break */
|
||||
va = 0xffffe6;
|
||||
if(shadow_reg & 0x40) {
|
||||
if(g_c035_shadow_reg & 0x40) {
|
||||
va = 0xffe6;
|
||||
}
|
||||
} else {
|
||||
/* irq */
|
||||
va = 0xffffee;
|
||||
if(shadow_reg & 0x40) {
|
||||
if(g_c035_shadow_reg & 0x40) {
|
||||
va = 0xffee;
|
||||
}
|
||||
}
|
||||
@ -1967,19 +2038,18 @@ update_60hz(double dcycs, double dtime_now)
|
||||
g_dtime_eff_pmhz_array[prev_vbl_index] = eff_pmhz;
|
||||
|
||||
|
||||
if(c041_en_vbl_ints) {
|
||||
if(g_c041_val & C041_EN_VBL_INTS) {
|
||||
add_event_vbl();
|
||||
}
|
||||
|
||||
g_25sec_cntr++;
|
||||
if(g_25sec_cntr >= 16) {
|
||||
g_25sec_cntr = 0;
|
||||
if(c041_en_25sec_ints && !c046_25sec_irq_pend) {
|
||||
if(g_c041_val & C041_EN_25SEC_INTS) {
|
||||
add_irq(IRQ_PENDING_C046_25SEC);
|
||||
g_c046_val |= 0x10;
|
||||
c046_25sec_irq_pend = 1;
|
||||
add_irq();
|
||||
irq_printf("Setting c046 .25 sec int to 1, "
|
||||
"g_irq_pend: %d\n", g_irq_pending);
|
||||
irq_printf("Setting c046 .25 sec int, g_irq_pend:%d\n",
|
||||
g_irq_pending);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1988,10 +2058,9 @@ update_60hz(double dcycs, double dtime_now)
|
||||
g_1sec_cntr = 0;
|
||||
tmp = g_c023_val;
|
||||
tmp |= 0x40; /* set 1sec int */
|
||||
if((tmp & 0x04) && !c023_1sec_int_irq_pending) {
|
||||
c023_1sec_int_irq_pending = 1;
|
||||
if(tmp & 0x04) {
|
||||
tmp |= 0x80;
|
||||
add_irq();
|
||||
add_irq(IRQ_PENDING_C023_1SEC);
|
||||
irq_printf("Setting c023 to %02x irq_pend: %d\n",
|
||||
tmp, g_irq_pending);
|
||||
}
|
||||
@ -2017,16 +2086,15 @@ update_60hz(double dcycs, double dtime_now)
|
||||
sound_update(dcycs);
|
||||
clock_update();
|
||||
scc_update(dcycs);
|
||||
joystick_update_button();
|
||||
paddle_update_buttons();
|
||||
}
|
||||
|
||||
void
|
||||
do_vbl_int()
|
||||
{
|
||||
if(c041_en_vbl_ints && !c046_vbl_irq_pending) {
|
||||
if(g_c041_val & C041_EN_VBL_INTS) {
|
||||
g_c046_val |= 0x08;
|
||||
c046_vbl_irq_pending = 1;
|
||||
add_irq();
|
||||
add_irq(IRQ_PENDING_C046_VBL);
|
||||
irq_printf("Setting c046 vbl_int_status to 1, irq_pend: %d\n",
|
||||
g_irq_pending);
|
||||
}
|
||||
@ -2045,12 +2113,12 @@ do_scan_int(double dcycs, int line)
|
||||
}
|
||||
|
||||
/* make sure scan int is still enabled for this line */
|
||||
if(g_slow_memory_ptr[0x19d00 + line] & 0x40) {
|
||||
if((g_slow_memory_ptr[0x19d00 + line] & 0x40) &&
|
||||
(g_cur_a2_stat & ALL_STAT_SUPER_HIRES)) {
|
||||
/* valid interrupt, do it */
|
||||
c023_val |= 0xa0; /* vgc_int and scan_int */
|
||||
if((c023_val & 0x02) && !c023_scan_int_irq_pending) {
|
||||
add_irq();
|
||||
c023_scan_int_irq_pending = 1;
|
||||
if(c023_val & 0x02) {
|
||||
add_irq(IRQ_PENDING_C023_SCAN);
|
||||
irq_printf("Setting c023 to %02x, irq_pend: %d\n",
|
||||
c023_val, g_irq_pending);
|
||||
}
|
||||
@ -2063,7 +2131,6 @@ do_scan_int(double dcycs, int line)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
check_scan_line_int(double dcycs, int cur_video_line)
|
||||
{
|
||||
@ -2128,6 +2195,7 @@ init_reg()
|
||||
engine.stack = 0x1ff;
|
||||
engine.direct = 0;
|
||||
engine.psr = 0x134;
|
||||
engine.fplus_ptr = 0;
|
||||
|
||||
}
|
||||
|
||||
@ -2174,6 +2242,9 @@ handle_action(word32 ret)
|
||||
case RET_WDM:
|
||||
do_wdm(ret & 0xff);
|
||||
break;
|
||||
case RET_STP:
|
||||
do_stp();
|
||||
break;
|
||||
default:
|
||||
halt_printf("Unknown special action: %08x!\n", ret);
|
||||
}
|
||||
@ -2274,7 +2345,11 @@ do_wai()
|
||||
void
|
||||
do_stp()
|
||||
{
|
||||
halt_printf("Hit do_stp at addr: %06x\n", engine.kpc);
|
||||
if(!g_stp_pending) {
|
||||
g_stp_pending = 1;
|
||||
halt_printf("Hit STP instruction at: %06x, press RESET to "
|
||||
"continue\n", engine.kpc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2283,3 +2358,86 @@ size_fail(int val, word32 v1, word32 v2)
|
||||
halt_printf("Size failure, val: %08x, %08x %08x\n", val, v1, v2);
|
||||
}
|
||||
|
||||
int
|
||||
fatal_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
if(g_fatal_log < 0) {
|
||||
g_fatal_log = 0;
|
||||
}
|
||||
ret = kegs_vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
kegs_vprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
char *bufptr, *buf2ptr;
|
||||
int len;
|
||||
int ret;
|
||||
|
||||
bufptr = malloc(4096);
|
||||
ret = vsnprintf(bufptr, 4090, fmt, ap);
|
||||
|
||||
len = strlen(bufptr);
|
||||
if(g_fatal_log >= 0 && g_fatal_log < MAX_FATAL_LOGS) {
|
||||
buf2ptr = malloc(len+1);
|
||||
memcpy(buf2ptr, bufptr, len+1);
|
||||
g_fatal_log_strs[g_fatal_log++] = buf2ptr;
|
||||
}
|
||||
must_write(1, bufptr, len);
|
||||
if(g_debug_file_fd >= 0) {
|
||||
must_write(g_debug_file_fd, bufptr, len);
|
||||
}
|
||||
free(bufptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
must_write(int fd, char *bufptr, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while(len > 0) {
|
||||
ret = write(fd, bufptr, len);
|
||||
if(ret >= 0) {
|
||||
len -= ret;
|
||||
bufptr += ret;
|
||||
} else if(errno != EAGAIN && errno != EINTR) {
|
||||
return; // just get out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clear_fatal_logs()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < g_fatal_log; i++) {
|
||||
free(g_fatal_log_strs[i]);
|
||||
g_fatal_log_strs[i] = 0;
|
||||
}
|
||||
g_fatal_log = -1;
|
||||
}
|
||||
|
||||
char *
|
||||
kegs_malloc_str(char *in_str)
|
||||
{
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
len = strlen(in_str) + 1;
|
||||
str = malloc(len);
|
||||
memcpy(str, in_str, len);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_smartport_c[] = "@(#)$KmKId: smartport.c,v 1.29 2003-11-17 15:44:44-05 kentd Exp $";
|
||||
const char rcsid_smartport_c[] = "@(#)$KmKId: smartport.c,v 1.31 2004-11-12 23:10:50-05 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
|
||||
@ -195,12 +195,9 @@ do_c70d(word32 arg0)
|
||||
/* see technotes/smpt/tn-smpt-002 */
|
||||
set_memory_c(status_ptr, g_highest_smartport_unit+1, 0);
|
||||
set_memory_c(status_ptr+1, 0xff, 0); /* interrupt stat*/
|
||||
set_memory_c(status_ptr+2, 0x02, 0); /* vendor id */
|
||||
set_memory_c(status_ptr+3, 0x00, 0); /* vendor id */
|
||||
set_memory_c(status_ptr+4, 0x00, 0); /* version lo */
|
||||
set_memory_c(status_ptr+5, 0x10, 0); /* version hi */
|
||||
set_memory_c(status_ptr+6, 0x00, 0);
|
||||
set_memory_c(status_ptr+7, 0x00, 0);
|
||||
set_memory16_c(status_ptr+2, 0x0002, 0); /* vendor id */
|
||||
set_memory16_c(status_ptr+4, 0x1000, 0); /* version */
|
||||
set_memory16_c(status_ptr+6, 0x0000, 0);
|
||||
|
||||
engine.xreg = 8;
|
||||
engine.yreg = 0;
|
||||
@ -219,9 +216,7 @@ do_c70d(word32 arg0)
|
||||
size = (size+511) / 512;
|
||||
}
|
||||
set_memory_c(status_ptr, stat_val, 0);
|
||||
set_memory_c(status_ptr +1, size & 0xff, 0);
|
||||
set_memory_c(status_ptr +2, (size >> 8) & 0xff, 0);
|
||||
set_memory_c(status_ptr +3, (size >> 16) & 0xff, 0);
|
||||
set_memory24_c(status_ptr +1, size, 0);
|
||||
engine.xreg = 4;
|
||||
if(cmd & 0x40) {
|
||||
set_memory_c(status_ptr + 4,
|
||||
@ -249,9 +244,7 @@ do_c70d(word32 arg0)
|
||||
}
|
||||
/* DIB for unit 1 */
|
||||
set_memory_c(status_ptr, stat_val, 0);
|
||||
set_memory_c(status_ptr +1, size & 0xff, 0);
|
||||
set_memory_c(status_ptr +2, (size >> 8) & 0xff, 0);
|
||||
set_memory_c(status_ptr +3, (size >> 16) & 0xff, 0);
|
||||
set_memory24_c(status_ptr +1, size, 0);
|
||||
if(cmd & 0x40) {
|
||||
set_memory_c(status_ptr + 4,
|
||||
(size >> 24) & 0xff, 0);
|
||||
@ -267,11 +260,8 @@ do_c70d(word32 arg0)
|
||||
set_memory_c(status_ptr +8, 'S', 0);
|
||||
|
||||
/* hard disk supporting extended calls */
|
||||
set_memory_c(status_ptr + 21, 0x02, 0);
|
||||
set_memory_c(status_ptr + 22, 0xa0, 0);
|
||||
|
||||
set_memory_c(status_ptr + 23, 0x00, 0);
|
||||
set_memory_c(status_ptr + 24, 0x00, 0);
|
||||
set_memory16_c(status_ptr + 21, 0xa002, 0);
|
||||
set_memory16_c(status_ptr + 23, 0x0000, 0);
|
||||
|
||||
if(cmd & 0x40) {
|
||||
engine.xreg = 26;
|
||||
@ -766,18 +756,15 @@ do_c700(word32 ret)
|
||||
ret = do_read_c7(0, 0x800, 0);
|
||||
|
||||
set_memory_c(0x7f8, 7, 0);
|
||||
set_memory_c(0x42, 0x01, 0);
|
||||
set_memory_c(0x43, 0x70, 0);
|
||||
set_memory_c(0x44, 0x0, 0);
|
||||
set_memory_c(0x45, 0x8, 0);
|
||||
set_memory_c(0x46, 0x0, 0);
|
||||
set_memory_c(0x47, 0x0, 0);
|
||||
set_memory16_c(0x42, 0x7001, 0);
|
||||
set_memory16_c(0x44, 0x0800, 0);
|
||||
set_memory16_c(0x46, 0x0000, 0);
|
||||
engine.xreg = 0x70;
|
||||
engine.kpc = 0x801;
|
||||
|
||||
if(ret != 0) {
|
||||
printf("Failure reading boot disk in s7d1!\n");
|
||||
engine.kpc = 0xe000;
|
||||
engine.kpc = 0xff59; /* Jump to monitor, fix $36-$39 */
|
||||
}
|
||||
}
|
||||
|
||||
|
64
src/sound.c
64
src/sound.c
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_sound_c[] = "@(#)$KmKId: sound.c,v 1.103 2003-10-17 15:07:47-04 kentd Exp $";
|
||||
const char rcsid_sound_c[] = "@(#)$KmKId: sound.c,v 1.108 2004-10-31 00:56:07-04 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
|
||||
@ -25,6 +25,7 @@ extern int g_use_shmem;
|
||||
extern word32 g_vbl_count;
|
||||
extern int g_preferred_rate;
|
||||
|
||||
extern int g_c03ef_doc_ptr;
|
||||
|
||||
extern double g_last_vbl_dcycs;
|
||||
|
||||
@ -34,7 +35,6 @@ byte doc_ram[0x10000 + 16];
|
||||
|
||||
word32 doc_sound_ctl = 0;
|
||||
word32 doc_saved_val = 0;
|
||||
word32 doc_ptr = 0;
|
||||
int g_doc_num_osc_en = 1;
|
||||
double g_dcycs_per_doc_update = 1.0;
|
||||
double g_dupd_per_dcyc = 1.0;
|
||||
@ -154,7 +154,7 @@ show_doc_log(void)
|
||||
int pos;
|
||||
int i;
|
||||
|
||||
docfile = fopen("doc_log_out", "wt");
|
||||
docfile = fopen("doc_log_out", "w");
|
||||
if(docfile == 0) {
|
||||
printf("fopen failed, errno: %d\n", errno);
|
||||
return;
|
||||
@ -397,10 +397,12 @@ sound_reset(double dcycs)
|
||||
halt_printf("reset: has_irq[%02x] = %d\n", i,
|
||||
g_doc_regs[i].has_irq_pending);
|
||||
}
|
||||
g_doc_regs[i].has_irq_pending = 0;
|
||||
}
|
||||
if(g_num_osc_interrupting) {
|
||||
halt_printf("reset: num_osc_int:%d\n", g_num_osc_interrupting);
|
||||
}
|
||||
g_num_osc_interrupting = 0;
|
||||
|
||||
g_doc_num_osc_en = 1;
|
||||
UPDATE_G_DCYCS_PER_DOC_UPDATE(1);
|
||||
@ -1212,7 +1214,7 @@ add_sound_irq(int osc)
|
||||
g_doc_regs[osc].has_irq_pending = num_osc_interrupting;
|
||||
g_num_osc_interrupting = num_osc_interrupting;
|
||||
|
||||
add_irq();
|
||||
add_irq(IRQ_PENDING_DOC);
|
||||
if(num_osc_interrupting == 1) {
|
||||
doc_reg_e0 = 0x00 + (osc << 1);
|
||||
}
|
||||
@ -1238,7 +1240,9 @@ remove_sound_irq(int osc, int must)
|
||||
g_num_osc_interrupting--;
|
||||
g_doc_regs[osc].has_irq_pending = 0;
|
||||
DOC_LOG("rem_irq", osc, g_cur_dcycs * g_dsamps_per_dcyc, 0);
|
||||
remove_irq();
|
||||
if(g_num_osc_interrupting == 0) {
|
||||
remove_irq(IRQ_PENDING_DOC);
|
||||
}
|
||||
|
||||
first = 0x40 | (doc_reg_e0 >> 1);
|
||||
/* if none found, then def = no ints */
|
||||
@ -1641,13 +1645,13 @@ doc_read_c03d(double dcycs)
|
||||
|
||||
if(doc_sound_ctl & 0x40) {
|
||||
/* Read RAM */
|
||||
doc_saved_val = doc_ram[doc_ptr];
|
||||
doc_saved_val = doc_ram[g_c03ef_doc_ptr];
|
||||
} else {
|
||||
/* Read DOC */
|
||||
doc_saved_val = 0;
|
||||
|
||||
osc = doc_ptr & 0x1f;
|
||||
type = (doc_ptr >> 5) & 0x7;
|
||||
osc = g_c03ef_doc_ptr & 0x1f;
|
||||
type = (g_c03ef_doc_ptr >> 5) & 0x7;
|
||||
rptr = &(g_doc_regs[osc]);
|
||||
|
||||
switch(type) {
|
||||
@ -1698,24 +1702,24 @@ doc_read_c03d(double dcycs)
|
||||
default:
|
||||
doc_saved_val = 0;
|
||||
halt_printf("Reading bad doc_reg[%04x]: %02x\n",
|
||||
doc_ptr, doc_saved_val);
|
||||
g_c03ef_doc_ptr, doc_saved_val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
doc_saved_val = 0;
|
||||
halt_printf("Reading bad doc_reg[%04x]: %02x\n",
|
||||
doc_ptr, doc_saved_val);
|
||||
g_c03ef_doc_ptr, doc_saved_val);
|
||||
}
|
||||
}
|
||||
|
||||
doc_printf("read c03d, doc_ptr: %04x, ret: %02x, saved: %02x\n",
|
||||
doc_ptr, ret, doc_saved_val);
|
||||
g_c03ef_doc_ptr, ret, doc_saved_val);
|
||||
|
||||
DOC_LOG("read c03d", -1, dsamps, (doc_ptr << 16) +
|
||||
DOC_LOG("read c03d", -1, dsamps, (g_c03ef_doc_ptr << 16) +
|
||||
(doc_saved_val << 8) + ret);
|
||||
|
||||
if(doc_sound_ctl & 0x20) {
|
||||
doc_ptr = (doc_ptr + 1) & 0xffff;
|
||||
g_c03ef_doc_ptr = (g_c03ef_doc_ptr + 1) & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
@ -1758,17 +1762,17 @@ doc_write_c03d(int val, double dcycs)
|
||||
dsamps = dcycs * g_dsamps_per_dcyc;
|
||||
eff_dsamps = dsamps;
|
||||
doc_printf("write c03d, doc_ptr: %04x, val: %02x\n",
|
||||
doc_ptr, val);
|
||||
g_c03ef_doc_ptr, val);
|
||||
|
||||
DOC_LOG("write c03d", -1, dsamps, (doc_ptr << 16) + val);
|
||||
DOC_LOG("write c03d", -1, dsamps, (g_c03ef_doc_ptr << 16) + val);
|
||||
|
||||
if(doc_sound_ctl & 0x40) {
|
||||
/* RAM */
|
||||
doc_ram[doc_ptr] = val;
|
||||
doc_ram[g_c03ef_doc_ptr] = val;
|
||||
} else {
|
||||
/* DOC */
|
||||
osc = doc_ptr & 0x1f;
|
||||
type = (doc_ptr >> 5) & 0x7;
|
||||
osc = g_c03ef_doc_ptr & 0x1f;
|
||||
type = (g_c03ef_doc_ptr >> 5) & 0x7;
|
||||
|
||||
rptr = &(g_doc_regs[osc]);
|
||||
ctl = rptr->ctl;
|
||||
@ -1777,7 +1781,7 @@ doc_write_c03d(int val, double dcycs)
|
||||
if(type < 2 || type == 4 || type == 6) {
|
||||
halt_printf("Osc %d is running, old ctl: %02x, "
|
||||
"but write reg %02x=%02x\n",
|
||||
osc, ctl, doc_ptr & 0xff, val);
|
||||
osc, ctl, g_c03ef_doc_ptr & 0xff, val);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1901,35 +1905,23 @@ doc_write_c03d(int val, double dcycs)
|
||||
/* and apparently TaskForce, OOTW, etc */
|
||||
/* writes to e2-ff, for no apparent reason */
|
||||
doc_printf("Writing doc 0x%x with %02x\n",
|
||||
doc_ptr, val);
|
||||
g_c03ef_doc_ptr, val);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
halt_printf("Writing %02x into bad doc_reg[%04x]\n",
|
||||
val, doc_ptr);
|
||||
val, g_c03ef_doc_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if(doc_sound_ctl & 0x20) {
|
||||
doc_ptr = (doc_ptr + 1) & 0xffff;
|
||||
g_c03ef_doc_ptr = (g_c03ef_doc_ptr + 1) & 0xffff;
|
||||
}
|
||||
|
||||
doc_saved_val = val;
|
||||
}
|
||||
|
||||
void
|
||||
doc_write_c03e(int val)
|
||||
{
|
||||
doc_ptr = (doc_ptr & 0xff00) + val;
|
||||
}
|
||||
|
||||
void
|
||||
doc_write_c03f(int val)
|
||||
{
|
||||
doc_ptr = (doc_ptr & 0xff) + (val << 8);
|
||||
}
|
||||
|
||||
void
|
||||
doc_show_ensoniq_state(int osc)
|
||||
{
|
||||
@ -1939,8 +1931,8 @@ doc_show_ensoniq_state(int osc)
|
||||
printf("Ensoniq state\n");
|
||||
printf("c03c doc_sound_ctl: %02x, doc_saved_val: %02x\n",
|
||||
doc_sound_ctl, doc_saved_val);
|
||||
printf("doc_ptr: %04x, num_osc_en: %02x, e0: %02x\n", doc_ptr,
|
||||
g_doc_num_osc_en, doc_reg_e0);
|
||||
printf("doc_ptr: %04x, num_osc_en: %02x, e0: %02x\n",
|
||||
g_c03ef_doc_ptr, g_doc_num_osc_en, doc_reg_e0);
|
||||
|
||||
for(i = 0; i < 32; i += 8) {
|
||||
printf("irqp: %02x: %04x %04x %04x %04x %04x %04x %04x %04x\n",
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_sound_driver_c[] = "@(#)$KmKId: sound_driver.c,v 1.16 2004-03-22 19:08:08-05 kentd Exp $";
|
||||
const char rcsid_sound_driver_c[] = "@(#)$KmKId: sound_driver.c,v 1.17 2004-09-21 10:37:15-04 kentd Exp $";
|
||||
|
||||
#include "defc.h"
|
||||
#include "sound.h"
|
||||
@ -17,10 +17,6 @@ const char rcsid_sound_driver_c[] = "@(#)$KmKId: sound_driver.c,v 1.16 2004-03-2
|
||||
# include <sys/audio.h>
|
||||
#endif
|
||||
|
||||
#ifdef SOLARIS
|
||||
# include <sys/audioio.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(OSS)
|
||||
# include <sys/soundcard.h>
|
||||
#endif
|
||||
@ -33,7 +29,6 @@ const char rcsid_sound_driver_c[] = "@(#)$KmKId: sound_driver.c,v 1.16 2004-03-2
|
||||
|
||||
|
||||
extern int Verbose;
|
||||
extern int g_use_alib;
|
||||
|
||||
extern int g_audio_rate;
|
||||
|
||||
@ -57,7 +52,6 @@ word32 *g_childsnd_shm_addr = 0;
|
||||
|
||||
void child_sound_init_linux();
|
||||
void child_sound_init_hpdev();
|
||||
void child_sound_init_solaris();
|
||||
void child_sound_init_win32();
|
||||
void child_sound_init_mac();
|
||||
|
||||
@ -137,9 +131,6 @@ child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
|
||||
#ifdef HPUX
|
||||
child_sound_init_hpdev();
|
||||
#endif
|
||||
#ifdef SOLARIS
|
||||
child_sound_init_solaris();
|
||||
#endif
|
||||
#if defined(__linux__) || defined(OSS)
|
||||
child_sound_init_linux();
|
||||
#endif
|
||||
@ -360,37 +351,6 @@ child_sound_init_hpdev()
|
||||
}
|
||||
#endif /* HPUX */
|
||||
|
||||
#ifdef SOLARIS
|
||||
void
|
||||
child_sound_init_solaris()
|
||||
{
|
||||
struct audio_info audioi;
|
||||
int ret;
|
||||
|
||||
g_audio_socket = open("/dev/audio", O_WRONLY, 0);
|
||||
if(g_audio_socket < 0) {
|
||||
printf("open /dev/audio failed, ret: %d, errno:%d\n",
|
||||
g_audio_socket, errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = ioctl(g_audio_socket, AUDIO_GETINFO, &audioi);
|
||||
if(ret < 0) {
|
||||
printf("ioctl audio getinfo ret: %d, errno:%d\n", ret, errno);
|
||||
exit(1);
|
||||
}
|
||||
audioi.play.sample_rate = g_preferred_rate;
|
||||
audioi.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
audioi.play.precision = 16;
|
||||
audioi.play.channels = 2;
|
||||
ret = ioctl(g_audio_socket, AUDIO_SETINFO, &audioi);
|
||||
if(ret < 0) {
|
||||
printf("ioctl audio setinfo ret: %d, errno:%d\n", ret, errno);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif /* SOLARIS */
|
||||
|
||||
#if defined(__linux__) || defined(OSS)
|
||||
void
|
||||
child_sound_init_linux()
|
||||
|
@ -3,7 +3,7 @@ TARGET = xkegs
|
||||
OBJECTS = $(OBJECTS1) xdriver.o
|
||||
CC = gcc
|
||||
CCOPTS = -O
|
||||
OPTS = -DNDEBUG -DSOLARIS -DKEGS_LITTLE_ENDIAN -DOSS
|
||||
OPTS = -DNDEBUG -DSOLARIS -DKEGS_LITTLE_ENDIAN -DSOLARISSOUND
|
||||
SUFFIX =
|
||||
NAME = xkegs
|
||||
LDFLAGS =
|
||||
|
210
src/video.c
210
src/video.c
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_video_c[] = "@(#)$KmKId: video.c,v 1.125 2004-03-23 17:25:50-05 kentd Exp $";
|
||||
const char rcsid_video_c[] = "@(#)$KmKId: video.c,v 1.135 2004-11-12 23:09:44-05 kentd Exp $";
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@ -41,12 +41,11 @@ extern byte *g_slow_memory_ptr;
|
||||
extern int g_screen_depth;
|
||||
extern int g_screen_mdepth;
|
||||
|
||||
extern int statereg;
|
||||
extern double g_cur_dcycs;
|
||||
|
||||
extern int g_line_ref_amt;
|
||||
|
||||
extern int g_border_color;
|
||||
extern int g_c034_val;
|
||||
extern int g_config_control_panel;
|
||||
|
||||
typedef byte Change;
|
||||
@ -72,6 +71,15 @@ Kimage g_mainwin_kimage;
|
||||
|
||||
extern double g_last_vbl_dcycs;
|
||||
|
||||
double g_video_dcycs_check_input = 0.0;
|
||||
int g_video_extra_check_inputs = 0;
|
||||
int g_video_act_margin_left = BASE_MARGIN_LEFT;
|
||||
int g_video_act_margin_right = BASE_MARGIN_RIGHT;
|
||||
int g_video_act_margin_top = BASE_MARGIN_TOP;
|
||||
int g_video_act_margin_bottom = BASE_MARGIN_BOTTOM;
|
||||
int g_video_act_width = X_A2_WINDOW_WIDTH;
|
||||
int g_video_act_height = X_A2_WINDOW_HEIGHT;
|
||||
|
||||
int g_need_redraw = 1;
|
||||
int g_palette_change_summary = 0;
|
||||
word32 g_palette_change_cnt[16];
|
||||
@ -98,6 +106,7 @@ int g_expanded_col_2[16];
|
||||
|
||||
int g_cur_a2_stat = ALL_STAT_TEXT | ALL_STAT_ANNUNC3 |
|
||||
(0xf << BIT_ALL_STAT_TEXT_COLOR);
|
||||
extern int g_save_cur_a2_stat; /* from config.c */
|
||||
|
||||
int g_a2vid_palette = 0xe;
|
||||
int g_installed_full_superhires_colormap = 0;
|
||||
@ -445,8 +454,6 @@ video_init()
|
||||
video_reset();
|
||||
display_screen();
|
||||
|
||||
vid_printf("Done with display_screen\n");
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
@ -463,7 +470,8 @@ show_a2_line_stuff()
|
||||
g_a2_line_right_edge[i]);
|
||||
}
|
||||
|
||||
printf("new_a2_stat_cur_line: %d\n", g_new_a2_stat_cur_line);
|
||||
printf("new_a2_stat_cur_line: %d, cur_a2_stat:%04x\n",
|
||||
g_new_a2_stat_cur_line, g_cur_a2_stat);
|
||||
for(i = 0; i < 200; i++) {
|
||||
printf("cur_all[%d]: %03x new_all: %03x\n", i,
|
||||
g_a2_cur_all_stat[i], g_a2_new_all_stat[i]);
|
||||
@ -476,13 +484,20 @@ int g_flash_count = 0;
|
||||
void
|
||||
video_reset()
|
||||
{
|
||||
int stat;
|
||||
int i;
|
||||
|
||||
g_installed_full_superhires_colormap = (g_screen_depth != 8);
|
||||
g_cur_a2_stat = ALL_STAT_TEXT | ALL_STAT_ANNUNC3 |
|
||||
stat = ALL_STAT_TEXT | ALL_STAT_ANNUNC3 |
|
||||
(0xf << BIT_ALL_STAT_TEXT_COLOR);
|
||||
if(g_use_bw_hires) {
|
||||
g_cur_a2_stat |= ALL_STAT_COLOR_C021;
|
||||
stat |= ALL_STAT_COLOR_C021;
|
||||
}
|
||||
if(g_config_control_panel) {
|
||||
/* Don't update cur_a2_stat when in configuration panel */
|
||||
g_save_cur_a2_stat = stat;
|
||||
} else {
|
||||
g_cur_a2_stat = stat;
|
||||
}
|
||||
|
||||
g_palette_change_summary = 0;
|
||||
@ -502,17 +517,11 @@ word32 g_cycs_in_check_input = 0;
|
||||
void
|
||||
video_update()
|
||||
{
|
||||
register word32 start_time;
|
||||
register word32 end_time;
|
||||
int did_video;
|
||||
|
||||
update_border_info();
|
||||
|
||||
GET_ITIMER(start_time);
|
||||
check_input_events();
|
||||
GET_ITIMER(end_time);
|
||||
|
||||
g_cycs_in_check_input += (end_time - start_time);
|
||||
video_check_input_events();
|
||||
|
||||
g_screen_redraw_skip_count--;
|
||||
did_video = 0;
|
||||
@ -536,8 +545,7 @@ video_update()
|
||||
|
||||
if(did_video) {
|
||||
g_new_a2_stat_cur_line = 0;
|
||||
g_a2_new_all_stat[0] = (g_cur_a2_stat & (~ALL_STAT_PAGE2)) +
|
||||
PAGE2;
|
||||
g_a2_new_all_stat[0] = g_cur_a2_stat;
|
||||
g_vid_update_last_line = 0;
|
||||
video_update_through_line(0);
|
||||
}
|
||||
@ -740,8 +748,7 @@ change_display_mode(double dcycs)
|
||||
video_update_all_stat_through_line(tmp_line);
|
||||
|
||||
if(line < 200) {
|
||||
g_a2_new_all_stat[line] =
|
||||
(g_cur_a2_stat & (~ALL_STAT_PAGE2)) + PAGE2;
|
||||
g_a2_new_all_stat[line] = g_cur_a2_stat;
|
||||
}
|
||||
/* otherwise, g_cur_a2_stat is covered at the end of vbl */
|
||||
}
|
||||
@ -813,12 +820,12 @@ update_border_info()
|
||||
|
||||
color_now = g_vbl_border_color;
|
||||
|
||||
dlines_per_dcyc = (double)(262.0 / DCYCS_IN_16MS);
|
||||
dlines_per_dcyc = (double)(1.0 / 65.0);
|
||||
limit = g_num_border_changes;
|
||||
if(g_border_last_vbl_changes || limit) {
|
||||
/* add a dummy entry */
|
||||
g_border_changes[limit].fcycs = DCYCS_IN_16MS + 21.0;
|
||||
g_border_changes[limit].val = g_border_color;
|
||||
g_border_changes[limit].val = (g_c034_val & 0xf);
|
||||
limit++;
|
||||
}
|
||||
last_line_offset = (-1 << 8) + 44;
|
||||
@ -826,7 +833,7 @@ update_border_info()
|
||||
dcycs = g_border_changes[i].fcycs;
|
||||
dline = dcycs * dlines_per_dcyc;
|
||||
new_line = (int)dline;
|
||||
dcyc_line_start = (double)new_line * (DCYCS_IN_16MS/262.0);
|
||||
dcyc_line_start = (double)new_line * 65.0;
|
||||
offset = ((int)(dcycs - dcyc_line_start)) & 0xff;
|
||||
|
||||
/* here comes the tricky part */
|
||||
@ -880,7 +887,7 @@ update_border_info()
|
||||
}
|
||||
|
||||
g_num_border_changes = 0;
|
||||
g_vbl_border_color = g_border_color;
|
||||
g_vbl_border_color = (g_c034_val & 0xf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -943,8 +950,8 @@ update_border_line(int st_line_offset, int end_line_offset, int color)
|
||||
right = MIN(4, end_offset - 44);
|
||||
video_border_pixel_write(&g_kimage_border_sides,
|
||||
2*line, 2, val,
|
||||
32 + (left * EFF_BORDER_WIDTH/4),
|
||||
32 + (right * EFF_BORDER_WIDTH/4));
|
||||
BORDER_WIDTH + (left * EFF_BORDER_WIDTH/4),
|
||||
BORDER_WIDTH + (right * EFF_BORDER_WIDTH/4));
|
||||
g_border_sides_refresh_needed = 1;
|
||||
}
|
||||
}
|
||||
@ -2638,6 +2645,26 @@ video_update_event_line(int line)
|
||||
add_event_vid_upd(1); /* add event for new screen */
|
||||
}
|
||||
}
|
||||
|
||||
if(g_video_extra_check_inputs) {
|
||||
if(g_video_dcycs_check_input < g_cur_dcycs) {
|
||||
video_check_input_events();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
video_check_input_events()
|
||||
{
|
||||
word32 start_time, end_time;
|
||||
|
||||
g_video_dcycs_check_input = g_cur_dcycs + 4000.0;
|
||||
|
||||
GET_ITIMER(start_time);
|
||||
check_input_events();
|
||||
GET_ITIMER(end_time);
|
||||
|
||||
g_cycs_in_check_input += (end_time - start_time);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2654,7 +2681,7 @@ video_update_through_line(int line)
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
vid_printf("\nvideo_upd for line %d, lines: %06x\n\n", line,
|
||||
vid_printf("\nvideo_upd for line %d, lines: %06x\n", line,
|
||||
get_lines_since_vbl(g_cur_dcycs));
|
||||
#endif
|
||||
|
||||
@ -3062,9 +3089,8 @@ video_push_lines(Kimage *kimage_ptr, int start_line, int end_line, int left_pix,
|
||||
g_refresh_bytes_xfer += 2*(end_line - start_line) *
|
||||
(right_pix - left_pix);
|
||||
|
||||
|
||||
x_push_kimage(kimage_ptr, BASE_MARGIN_LEFT + left_pix,
|
||||
BASE_MARGIN_TOP + srcy, left_pix, srcy,
|
||||
x_push_kimage(kimage_ptr, g_video_act_margin_left + left_pix,
|
||||
g_video_act_margin_top + srcy, left_pix, srcy,
|
||||
(right_pix - left_pix), 2*(end_line - start_line));
|
||||
}
|
||||
|
||||
@ -3087,9 +3113,31 @@ video_push_border_sides_lines(int src_x, int dest_x, int width, int start_line,
|
||||
g_refresh_bytes_xfer += 2 * (end_line - start_line) * width;
|
||||
|
||||
srcy = 2 * start_line;
|
||||
x_push_kimage(kimage_ptr, dest_x, BASE_MARGIN_TOP + srcy,
|
||||
|
||||
// Adjust dext_x to accound for changed margins
|
||||
dest_x = dest_x + g_video_act_margin_left - BASE_MARGIN_LEFT;
|
||||
if(dest_x < BASE_MARGIN_LEFT) {
|
||||
src_x = src_x + g_video_act_margin_left - BASE_MARGIN_LEFT;
|
||||
// Don't adjust src_x if doing right border
|
||||
}
|
||||
if(dest_x < 0) {
|
||||
width = width + dest_x;
|
||||
src_x = src_x - dest_x;
|
||||
dest_x = 0;
|
||||
}
|
||||
if(src_x < 0) {
|
||||
width = width + src_x;
|
||||
dest_x = dest_x - src_x;
|
||||
src_x = 0;
|
||||
}
|
||||
if(dest_x + width > g_video_act_width) {
|
||||
width = g_video_act_width - dest_x;
|
||||
}
|
||||
if(width > 0) {
|
||||
x_push_kimage(kimage_ptr, dest_x, g_video_act_margin_top + srcy,
|
||||
src_x, srcy, width, 2*(end_line - start_line));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
video_push_border_sides()
|
||||
@ -3134,18 +3182,39 @@ video_push_border_special()
|
||||
{
|
||||
Kimage *kimage_ptr;
|
||||
int width, height;
|
||||
|
||||
width = X_A2_WINDOW_WIDTH;
|
||||
height = BASE_MARGIN_TOP;
|
||||
int src_x, src_y;
|
||||
int dest_x, dest_y;
|
||||
|
||||
kimage_ptr = &g_kimage_border_special;
|
||||
width = g_video_act_width;
|
||||
g_refresh_bytes_xfer += width * (BASE_MARGIN_TOP + BASE_MARGIN_BOTTOM);
|
||||
|
||||
x_push_kimage(kimage_ptr, 0, BASE_MARGIN_TOP + A2_WINDOW_HEIGHT,
|
||||
0, 0, width, BASE_MARGIN_BOTTOM);
|
||||
x_push_kimage(kimage_ptr, 0, 0,
|
||||
0, BASE_MARGIN_BOTTOM, width, BASE_MARGIN_TOP);
|
||||
// First do bottom border: dest_x from 0 to 640+MARGIN_LEFT+MARGIN_RIGHT
|
||||
// and dest_y of BASE_MARGIN_BOTTOM starting at TOP+A2_HEIGHT
|
||||
// src_x is dest_x, and src_y is 0.
|
||||
dest_y = g_video_act_margin_top + A2_WINDOW_HEIGHT;
|
||||
height = g_video_act_margin_bottom;
|
||||
src_y = BASE_MARGIN_BOTTOM - height;
|
||||
|
||||
dest_x = 0;
|
||||
src_x = BASE_MARGIN_LEFT - g_video_act_margin_left;
|
||||
|
||||
if(width > 0 && height > 0) {
|
||||
x_push_kimage(kimage_ptr, dest_x, dest_y, src_x, src_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
// Then fix top border: dest_x from 0 to 640+LEFT+RIGHT and
|
||||
// dest_y from 0 to TOP. src_x is dest_x, but src_y is
|
||||
// BOTTOM to BOTTOM+TOP
|
||||
// Just use src_x and dest_x from earlier.
|
||||
height = g_video_act_margin_top;
|
||||
dest_y = 0;
|
||||
src_y = BASE_MARGIN_BOTTOM;
|
||||
if(width > 0 && height > 0) {
|
||||
x_push_kimage(kimage_ptr, dest_x, dest_y, src_x, src_y,
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -3352,3 +3421,70 @@ video_show_debug_info()
|
||||
printf("lines since vbl: %06x\n", tmp1);
|
||||
printf("Last line updated: %d\n", g_vid_update_last_line);
|
||||
}
|
||||
|
||||
word32
|
||||
float_bus(double dcycs)
|
||||
{
|
||||
word32 val;
|
||||
int lines_since_vbl;
|
||||
int line, eff_line, line24;
|
||||
int all_stat;
|
||||
int byte_offset;
|
||||
int hires, page2;
|
||||
int addr;
|
||||
|
||||
lines_since_vbl = get_lines_since_vbl(dcycs);
|
||||
|
||||
/* For floating bus, model hires style: Visible lines 0-191 are simply the */
|
||||
/* data being displayed at that time. Lines 192-255 are lines 0 - 63 again */
|
||||
/* and lines 256-261 are lines 58-63 again */
|
||||
/* For each line, figure out starting byte at -25 mod 128 bytes from this */
|
||||
/* line's start */
|
||||
/* This emulates an Apple II style floating bus. A reall IIgs does not */
|
||||
/* drive anything meaningful during the 25 horizontal blanking lines, */
|
||||
/* nor during veritical blanking. The data seems to be 0 or related to */
|
||||
/* the instruction fetches on a real IIgs during blankings */
|
||||
|
||||
line = lines_since_vbl >> 8;
|
||||
byte_offset = lines_since_vbl & 0xff;
|
||||
/* byte offset is from 0 to 65, where the visible screen is drawn */
|
||||
/* from 25 to 65 */
|
||||
|
||||
eff_line = line;
|
||||
if(line >= 192) {
|
||||
eff_line = line - 192;
|
||||
if(line >= 256) {
|
||||
eff_line = line - 262 + 64;
|
||||
}
|
||||
}
|
||||
all_stat = g_cur_a2_stat;
|
||||
hires = all_stat & ALL_STAT_HIRES;
|
||||
if((all_stat & ALL_STAT_MIX_T_GR) && (line >= 160)) {
|
||||
hires = 0;
|
||||
}
|
||||
page2 = EXTRU(all_stat, 31 - BIT_ALL_STAT_PAGE2, 1);
|
||||
if(all_stat & ALL_STAT_ST80) {
|
||||
page2 = 0;
|
||||
}
|
||||
|
||||
line24 = (eff_line >> 3) & 0x1f;
|
||||
addr = g_screen_index[line24] & 0x3ff;
|
||||
addr = (addr & 0x380) + (((addr & 0x7f) - 25 + byte_offset) & 0x7f);
|
||||
if(hires) {
|
||||
addr = 0x2000 + addr + ((eff_line & 7) << 10) + (page2 << 13);
|
||||
} else {
|
||||
addr = 0x400 + addr + (page2 << 10);
|
||||
}
|
||||
|
||||
val = g_slow_memory_ptr[addr];
|
||||
if(byte_offset < 10) {
|
||||
/* Bob Bishop's sample program seems to get confused by */
|
||||
/* these bytes--so mask some off to prevent seeing some */
|
||||
val = 0;
|
||||
}
|
||||
#if 0
|
||||
printf("For %04x (%d) addr=%04x, val=%02x, dcycs:%9.2f\n",
|
||||
lines_since_vbl, eff_line, addr, val, dcycs - g_last_vbl_dcycs);
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
@ -8,7 +8,10 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_windriver_c[] = "@(#)$KmKId: windriver.c,v 1.8 2004-03-23 17:25:37-05 kentd Exp $";
|
||||
const char rcsid_windriver_c[] = "@(#)$KmKId: windriver.c,v 1.11 2004-11-24 16:43:46-05 kentd Exp $";
|
||||
|
||||
/* Based on code from Chea Chee Keong from KEGS32, which is available at */
|
||||
/* http://www.geocities.com/akilgard/kegs32 */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN /* Tell windows we want less header gunk */
|
||||
#define STRICT /* Tell Windows we want compile type checks */
|
||||
@ -187,6 +190,34 @@ int g_a2_key_to_wsym[][3] = {
|
||||
{ -1, -1, -1 }
|
||||
};
|
||||
|
||||
int
|
||||
win_nonblock_read_stdin(int fd, char *bufptr, int len)
|
||||
{
|
||||
HANDLE oshandle;
|
||||
DWORD dwret;
|
||||
int ret;
|
||||
|
||||
errno = EAGAIN;
|
||||
oshandle = (HANDLE)_get_osfhandle(fd); // get stdin handle
|
||||
dwret = WaitForSingleObject(oshandle, 1); // wait 1msec for data
|
||||
ret = -1;
|
||||
if(dwret == WAIT_OBJECT_0) {
|
||||
ret = read(fd, bufptr, len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
x_dialog_create_kegs_conf(const char *str)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
x_show_alert(int is_fatal, const char *str)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
win_update_mouse(int x, int y, int button_states, int buttons_valid)
|
||||
{
|
||||
@ -635,3 +666,9 @@ x_hide_pointer(int do_hide)
|
||||
ShowCursor(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
x_full_screen(int do_full)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
/* You may contact the author at: kadickey@alumni.princeton.edu */
|
||||
/************************************************************************/
|
||||
|
||||
const char rcsid_xdriver_c[] = "@(#)$KmKId: xdriver.c,v 1.181 2004-03-23 17:25:25-05 kentd Exp $";
|
||||
const char rcsid_xdriver_c[] = "@(#)$KmKId: xdriver.c,v 1.187 2004-11-15 16:24:19-05 kentd Exp $";
|
||||
|
||||
# if !defined(__CYGWIN__) && !defined(__POWERPC__)
|
||||
/* No shared memory on Cygwin */
|
||||
@ -136,7 +136,7 @@ int g_num_a2_keycodes = 0;
|
||||
int a2_key_to_xsym[][3] = {
|
||||
{ 0x35, XK_Escape, 0 },
|
||||
{ 0x7a, XK_F1, 0 },
|
||||
{ 0x7b, XK_F2, 0 },
|
||||
{ 0x78, XK_F2, 0 },
|
||||
{ 0x63, XK_F3, 0 },
|
||||
{ 0x76, XK_F4, 0 },
|
||||
{ 0x60, XK_F5, 0 },
|
||||
@ -165,7 +165,7 @@ int a2_key_to_xsym[][3] = {
|
||||
{ 0x1b, '-', '_' },
|
||||
{ 0x18, '=', '+' },
|
||||
{ 0x33, XK_BackSpace, 0 },
|
||||
{ 0x72, XK_Insert, 0 }, /* Help? */
|
||||
{ 0x72, XK_Insert, XK_Help }, /* Help? */
|
||||
/* { 0x73, XK_Home, 0 }, alias XK_Home to be XK_KP_Equal! */
|
||||
{ 0x74, XK_Page_Up, 0 },
|
||||
{ 0x47, XK_Num_Lock, XK_Clear }, /* Clear */
|
||||
@ -248,6 +248,23 @@ main(int argc, char **argv)
|
||||
return kegsmain(argc, argv);
|
||||
}
|
||||
|
||||
void
|
||||
x_dialog_create_kegs_conf(const char *str)
|
||||
{
|
||||
/* do nothing -- not implemented yet */
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
x_show_alert(int is_fatal, const char *str)
|
||||
{
|
||||
/* Not implemented yet */
|
||||
adb_all_keys_up();
|
||||
|
||||
clear_fatal_logs();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define MAKE_2(val) ( (val << 8) + val)
|
||||
|
||||
@ -1160,15 +1177,23 @@ handle_keysym(XEvent *xev_in)
|
||||
switch(keysym) {
|
||||
case XK_Alt_R:
|
||||
case XK_Meta_R:
|
||||
case XK_Super_R:
|
||||
case XK_Mode_switch:
|
||||
case XK_Cancel:
|
||||
keysym = XK_Print; /* option */
|
||||
break;
|
||||
case XK_Alt_L:
|
||||
case XK_Meta_L:
|
||||
case XK_Super_L:
|
||||
case XK_Menu:
|
||||
keysym = XK_Scroll_Lock; /* cmd */
|
||||
break;
|
||||
case 0x1000003:
|
||||
if(keycode == 0x3c) {
|
||||
/* enter key on Mac OS X laptop--make it option */
|
||||
keysym = XK_Print;
|
||||
}
|
||||
break;
|
||||
case NoSymbol:
|
||||
switch(keycode) {
|
||||
/* 94-95 are for my PC101 kbd + windows keys on HPUX */
|
||||
@ -1196,6 +1221,7 @@ handle_keysym(XEvent *xev_in)
|
||||
keysym = XK_Scroll_Lock;
|
||||
break;
|
||||
case 0x0048:
|
||||
case 0x0076: /* Windows menu key on Mac OS X */
|
||||
/* menu windows == option */
|
||||
keysym = XK_Print;
|
||||
break;
|
||||
@ -1304,3 +1330,9 @@ x_auto_repeat_off(int must)
|
||||
adb_kbd_repeat_off();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
x_full_screen(int do_full)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user